class ImportDataDlg(QDialog): __isJy = False # 数据校验成功的标志 __mlist = [] # 定义一个列表用于保存从excel表中取出的数据 def __init__(self, iface, parent=None, impType=ImpDateType.SITEANDCELL): super(ImportDataDlg, self).__init__() self.iface = iface self.parent = parent self.impType = impType self.initView() def initView(self): if self.impType == ImpDateType.SERVINGCELL: self.setWindowTitle(u'相邻小区数据导入') else: self.setWindowTitle(u'基站和小区数据导入') self.setWindowIcon(QIcon('images/logo.png')) self.resize(620, 480) # 数据表格 self.tableWidget = QTableWidget(self) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.setRowCount(7) # 设置当前Table不能编辑 self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) # 初始化表格上下文菜单 self.initTableContextMenu() # 初始化表头 self.initTableHeader() # 导入出错列表 self.listWidget = QListWidget(self) # 按钮组 impBtn = QPushButton(u"导入EXCEL表", self) yzBtn = QPushButton(u"数据检验", self) impdateBtn = QPushButton(u"导入数据", self) btnVBox = QVBoxLayout() btnVBox.addWidget(impBtn) btnVBox.addWidget(yzBtn) btnVBox.addWidget(impdateBtn) # 错误列表与按钮组 hBox = QHBoxLayout() hBox.setMargin(20) hBox.addWidget(self.listWidget) hBox.addLayout(btnVBox) self.mbar = QStatusBar(self) self.mbar.showMessage(u'准备就绪...') self.maction = QToolBar(self) self.editAction = QAction(u'编辑', self.maction) self.editAction.setCheckable(True) self.combox = QComboBox(self) self.combox.addItems(HeadsConfig.ImpExcelName) self.maction.addWidget(self.combox) self.maction.addAction(self.editAction) vBox = QVBoxLayout() vBox.addWidget(self.maction) vBox.addWidget(self.tableWidget) vBox.addLayout(hBox) vBox.addWidget(self.mbar) vBox.setStretchFactor(self.tableWidget, 9) vBox.setStretchFactor(hBox, 5) vBox.setStretchFactor(self.mbar, 1) self.setLayout(vBox) QObject.connect(impBtn, SIGNAL('clicked()'), self.impClick) QObject.connect(yzBtn, SIGNAL('clicked()'), self.yzClick) QObject.connect(impdateBtn, SIGNAL('clicked()'), self.impdateClick) QObject.connect(self.editAction, SIGNAL('triggered()'), self.editClick) QObject.connect(self.combox, SIGNAL('currentIndexChanged(int)'), self.comboxChange) self.listWidget.doubleClicked.connect(self.mlistClicked) # self.connect(self.listWidget, SIGNAL("itemDoubleClicked (QListWidgetItem)"), self.mlistClicked) def initTableContextMenu(self): self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.popMenu = QMenu(self.tableWidget) delAction = QAction(u'删除', self) # 删除 self.popMenu.addAction(delAction) # 设置表格可以双击修改数据 def setEditTriggers(self, isTrigger): if isTrigger: self.tableWidget.setEditTriggers(QAbstractItemView.DoubleClicked) else: self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) # 提供给外部修改状态栏消息 def setStatusBarMsg(self, msg): self.mbar.showMessage(msg) # 选框改变时,清空当前表格的全部内容,包括表格头 def updateType(self, mtype): self.impType = mtype self.tableWidget.clear() # 清空表格所有内容 self.initTableHeader() # 初始化表格的每个Item def initTable(self, mlist): self.tableWidget.setRowCount(len(mlist)) for (i, v) in enumerate(mlist): for (j, item) in enumerate(v): if type(item) != str: item = unicode(item) if item == None: item = u"" tabItem = QTableWidgetItem(item) tabItem.setTextAlignment(Qt.AlignCenter) self.tableWidget.setItem(i, j, tabItem) # 初始化错误信息列表 def initListView(self, mlist): for iv in mlist: lisItm = QListWidgetItem(self.listWidget) lisItm.setTextColor(Qt.red) lisItm.setData(Qt.UserRole, iv) if isinstance(iv, basestring): # 如果错误信息是一行字符串 lisItm.setText(iv) else: lisItm.setText(u'第' + unicode(str(iv['row'] + 1)) + u'行,第' + unicode(str(iv['col'] + 1)) + u'列:' + iv['msg']) # 初始化Table的头 def initTableHeader(self): self.heads = [] if self.impType == ImpDateType.SITEANDCELL: # 获取当前项目图层的字段名 cell_layer = getLayerByName(u"小区", self.iface) for head in HeadsConfig.SiteANDCellHead: self.heads.append(head) if len(cell_layer.pendingFields()) > 55: for (index, field) in enumerate(cell_layer.pendingFields()): if index > 54: field_name = field.name().strip() self.heads.append(field_name) else: self.heads = HeadsConfig.ServingCellHead self.tableWidget.setColumnCount(len(self.heads)) # 设置表格的列数 for (i, h) in enumerate(self.heads): tabItem = QTableWidgetItem(h) self.tableWidget.setHorizontalHeaderItem(i, tabItem) # 自定义为Table添加Item def addTableItem(self, row, col, content): tabItem = QTableWidgetItem(content) self.tableWidget.setItem(row, col, tabItem) # 修改Item的内容 def editTableItem(self, row, col, content): tabItem = self.tableWidget.item(row, col) tabItem.setText(content) self.tableWidget.setItem(row, col, tabItem) # 从Excel表读取数据(导入Excel表) def impClick(self): fileName = QFileDialog.getOpenFileName(self, u'基站小区数据导入', '/', 'Excel Files (*.xls *.xlsx)') if fileName.strip() != "": self.setStatusBarMsg(u'选择完毕:' + fileName) importData = GetDataFromExcel(fileName, self.impType, self.heads) self.__mlist = [] self.__mlist.extend(importData.getData()) self.tableWidget.clearContents() self.listWidget.clear() self.initTable(self.__mlist) self.setStatusBarMsg(u'数据导入完成...') self.__isJy = False # 导入完数据后,说明需要重新验证数据的正确性 else: QMessageBox.information(self.parent, u"错误", u"请选中文件") # 数据验证按钮点击事件处理 def yzClick(self): if len(self.__mlist) > 0: self.erlist = [] # 定义一个列表用于保存数据验证错误的数据 # 清楚全部的Item if self.listWidget.count() > 0: self.listWidget.clear() # 根据tableWidget更新self.__mlist for (r, items) in enumerate(self.__mlist): for (v, item) in enumerate(self.__mlist[r]): if self.tableWidget.item(r, v).text() == u"": continue else: # 跟据self.__mlist[r][v]数据类型进行比对 if type(self.__mlist[r][v]) == int: if unicode(self.__mlist[r][v]) != ( self.tableWidget.item(r, v).text()): self.__mlist[r][v] = int( self.tableWidget.item(r, v).text()) elif type(self.__mlist[r][v]) == float: if unicode(self.__mlist[r][v]) != ( self.tableWidget.item(r, v).text()): self.__mlist[r][v] = float( self.tableWidget.item(r, v).text()) elif type(self.__mlist[r][v]) == str: if unicode(self.__mlist[r][v] ) != self.tableWidget.item(r, v).text(): self.__mlist[r][v] = str( self.tableWidget.item(r, v).text()) elif type(self.__mlist[r][v]) == unicode: if (self.__mlist[r][v]) != self.tableWidget.item( r, v).text(): self.__mlist[r][v] = self.tableWidget.item( r, v).text() else: print type(self.__mlist[r][v]) # 执行数据校验函数 self.erlist = checkDataByDataType(self.__mlist, self.impType) if len(self.erlist) > 0: self.initListView(self.erlist) QMessageBox.information(self.parent, u'数据校验', u'数据校验失败,请检查数据正确性后,再导入到地图中') self.__isJy = False else: QMessageBox.information(self.parent, u'数据校验', u'数据校验成功,没有错误数据') self.__isJy = True else: QMessageBox.warning(self.parent, u'数据校验', u'请先导入Excel数据后再操作!') # 导入数据到地图中 def impdateClick(self): if self.__isJy: # 如果数据校验成功 if self.impType == ImpDateType.SITEANDCELL: # 导入基站小区 importDataToLayer = ImportDataToLayer(self.iface, self.__mlist, self.parent) if importDataToLayer.importSiteAndCellData(): QMessageBox.information(self.parent, u"导入数据", u"导入数据成功!") else: QMessageBox.critical(self.parent, u"导入数据", u"导入数据失败!") else: # 导入相邻小区 importDataToLayer = ImportDataToLayer(self.iface, self.__mlist, self.parent) if importDataToLayer.importSCellData(): QMessageBox.information(self.parent, u"导入数据", u"导入数据成功!") else: QMessageBox.critical(self.parent, u"导入数据", u"导入数据失败!") else: QMessageBox.warning(self.parent, u'数据导入', u'请确保校验数据成功后,再导入到地图中') # 编辑Action点击事件 def editClick(self): self.setEditTriggers(self.editAction.isChecked()) # 错误列表双击事件处理 def mlistClicked(self, listItem): itemData = listItem.data(Qt.UserRole) self.tableWidget.setFocus() self.tableWidget.setCurrentCell(itemData['row'], itemData['col']) # 选框改变事件 def comboxChange(self, index): self.updateType(index) # 字段验证是否为空 def __validNull(self, name, col, row, itm, rowitm): if itm is None or itm == '': tmpMap = {} tmpMap['col'] = col tmpMap['row'] = row tmpMap['msg'] = unicode(name) + u'不能为空' tmpMap['item'] = rowitm return tmpMap else: return None # 导入数据线程开始信号 绑定函数 def impStart(self): self.setStatusBarMsg(u'准备导入...') # 导入数据线程发生异常信号 绑定函数 def impError(self, e, exception_string): self.setStatusBarMsg(u'发生错误:' + unicode(e)) QMessageBox.warning(self.parent, u'Excel数据导入', u'发生错误:' + unicode(e)) # 导入数据线程完成信号 绑定函数 def impFinish(self, mylist): self.__mlist = [] self.__mlist.extend(mylist) self.mthread.quit() self.mthread.wait() self.mthread.deleteLater() self.impDateThread.deleteLater() self.tableWidget.clearContents() self.listWidget.clear() self.initTable(self.__mlist) self.setStatusBarMsg(u'数据导入完成...') self.__isJy = False # 导入完数据后,说明需要重新验证数据的正确性 # 导入数据到地图线程发生异常信号 绑定函数 def impError1(self, e, exception_string): self.setStatusBarMsg(u"导入数据发生错误") QMessageBox.critical(self, u'数据导入', u"发生错误:" + unicode(e)) # 导入数据到地图线程完成信号 绑定函数 def impFinish1(self, mylist): self.threadImp.quit() self.threadImp.wait() self.threadImp.deleteLater() self.impFeatureThread.deleteLater() remsg = u'数据导入完成!' layer = None if self.impType == LayerType.SITE: # remsg = u'基站' + remsg layer = getLayerByName(u'基站', self.iface) elif self.impType == LayerType.CELL: # remsg = u'小区' + remsg layer = getLayerByName(u'小区', self.iface) else: remsg = u'相邻小区' + remsg layer = getLayerByName(u'相邻小区', self.iface) self.setStatusBarMsg(remsg) layer.updateExtents() # 更新地图数据 self.iface.actionDraw().trigger() QMessageBox.information(self, u'数据导入', remsg) merlist = [] for eritm in self.erlist: merlist.append(eritm['item']) self.tableWidget.clearContents() # 先清楚表格的内容,再将错误的行显示到表格中 self.initTable(merlist)
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " super(Main, self).initialize(*args, **kwargs) self.scriptPath, self.scriptArgs = "", [] self.profilerPath, self.tempPath = profilerPath, tempPath self.output = " ERROR: FAIL: No output ! " self.process = QProcess() self.process.finished.connect(self.on_process_finished) self.process.error.connect(self.on_process_error) self.tabWidget, self.stat = QTabWidget(), QWidget() self.tabWidget.tabCloseRequested.connect( lambda: self.tabWidget.setTabPosition(1) if self.tabWidget. tabPosition() == 0 else self.tabWidget.setTabPosition(0)) self.tabWidget.setStyleSheet('QTabBar{font-weight:bold;}') self.tabWidget.setMovable(True) self.tabWidget.setTabsClosable(True) self.vboxlayout1 = QVBoxLayout(self.stat) self.hboxlayout1 = QHBoxLayout() self.filterTableLabel = QLabel("<b>Type to Search : </b>", self.stat) self.hboxlayout1.addWidget(self.filterTableLabel) self.filterTableLineEdit = QLineEdit(self.stat) self.filterTableLineEdit.setPlaceholderText(' Type to Search . . . ') self.hboxlayout1.addWidget(self.filterTableLineEdit) self.filterHintTableLabel = QLabel(" ? ", self.stat) self.hboxlayout1.addWidget(self.filterHintTableLabel) self.vboxlayout1.addLayout(self.hboxlayout1) self.tableWidget = QTableWidget(self.stat) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.setColumnCount(8) self.tableWidget.setRowCount(2) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(0, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(1, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(2, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(3, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(4, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(5, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(6, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(7, item) self.tableWidget.itemDoubleClicked.connect( self.on_tableWidget_itemDoubleClicked) self.vboxlayout1.addWidget(self.tableWidget) self.tabWidget.addTab(self.stat, " ? ") self.source = QWidget() self.gridlayout = QGridLayout(self.source) self.scintillaWarningLabel = QLabel( "QScintilla is not installed!. Falling back to basic text edit!.", self.source) self.gridlayout.addWidget(self.scintillaWarningLabel, 1, 0, 1, 2) self.sourceTreeWidget = QTreeWidget(self.source) self.sourceTreeWidget.setAlternatingRowColors(True) self.sourceTreeWidget.itemActivated.connect( self.on_sourceTreeWidget_itemActivated) self.sourceTreeWidget.itemClicked.connect( self.on_sourceTreeWidget_itemClicked) self.sourceTreeWidget.itemDoubleClicked.connect( self.on_sourceTreeWidget_itemClicked) self.gridlayout.addWidget(self.sourceTreeWidget, 0, 0, 1, 1) self.sourceTextEdit = QTextEdit(self.source) self.sourceTextEdit.setReadOnly(True) self.gridlayout.addWidget(self.sourceTextEdit, 0, 1, 1, 1) self.tabWidget.addTab(self.source, " ? ") self.result = QWidget() self.vlayout = QVBoxLayout(self.result) self.globalStatGroupBox = QGroupBox(self.result) self.hboxlayout = QHBoxLayout(self.globalStatGroupBox) self.totalTimeLcdNumber = QLCDNumber(self.globalStatGroupBox) self.totalTimeLcdNumber.setSegmentStyle(QLCDNumber.Filled) self.totalTimeLcdNumber.setNumDigits(7) self.totalTimeLcdNumber.display(1000000) self.totalTimeLcdNumber.setFrameShape(QFrame.StyledPanel) self.totalTimeLcdNumber.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.hboxlayout.addWidget(self.totalTimeLcdNumber) self.tTimeLabel = QLabel("<b>Total Time (Sec)</b>", self.globalStatGroupBox) self.tTimeLabel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.hboxlayout.addWidget(self.tTimeLabel) self.numCallLcdNumber = QLCDNumber(self.globalStatGroupBox) self.numCallLcdNumber.setNumDigits(7) self.numCallLcdNumber.display(1000000) self.numCallLcdNumber.setSegmentStyle(QLCDNumber.Filled) self.numCallLcdNumber.setFrameShape(QFrame.StyledPanel) self.numCallLcdNumber.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.hboxlayout.addWidget(self.numCallLcdNumber) self.numCallLabel = QLabel("<b>Number of calls</b>", self.globalStatGroupBox) self.numCallLabel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.hboxlayout.addWidget(self.numCallLabel) self.primCallLcdNumber = QLCDNumber(self.globalStatGroupBox) self.primCallLcdNumber.setSegmentStyle(QLCDNumber.Filled) self.primCallLcdNumber.setFrameShape(QFrame.StyledPanel) self.primCallLcdNumber.setNumDigits(7) self.primCallLcdNumber.display(1000000) self.primCallLcdNumber.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.hboxlayout.addWidget(self.primCallLcdNumber) self.primCallLabel = QLabel("<b>Primitive calls (%)</b>", self.globalStatGroupBox) self.primCallLabel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.hboxlayout.addWidget(self.primCallLabel) self.vlayout.addWidget(self.globalStatGroupBox) try: from PyKDE4.kdeui import KRatingWidget self.rating = KRatingWidget(self.globalStatGroupBox) self.rating.setToolTip('Profiling Performance Rating') except ImportError: pass self.tabWidget.addTab(self.result, " Get Results ! ") self.resgraph = QWidget() self.vlayout2 = QVBoxLayout(self.result) self.graphz = QGroupBox(self.resgraph) self.hboxlayout2 = QHBoxLayout(self.graphz) try: from PyKDE4.kdeui import KLed KLed(self.graphz) except ImportError: pass self.hboxlayout2.addWidget( QLabel(''' Work in Progress :) Not Ready Yet''')) self.vlayout2.addWidget(self.graphz) self.tabWidget.addTab(self.resgraph, " Graphs and Charts ") self.pathz = QWidget() self.vlayout3 = QVBoxLayout(self.pathz) self.patz = QGroupBox(self.pathz) self.hboxlayout3 = QVBoxLayout(self.patz) self.profilepath = QLineEdit(profilerPath) self.getprofile = QPushButton(QIcon.fromTheme("document-open"), 'Open') self.getprofile.setToolTip( 'Dont touch if you dont know what are doing') self.getprofile.clicked.connect(lambda: self.profilepath.setText( str( QFileDialog.getOpenFileName( self.patz, ' Open the profile.py file ', path.expanduser("~"), ';;(profile.py)')))) self.hboxlayout3.addWidget( QLabel( '<center><b>Profile.py Python Library Full Path:</b></center>') ) self.hboxlayout3.addWidget(self.profilepath) self.hboxlayout3.addWidget(self.getprofile) self.argGroupBox = QGroupBox(self.pathz) self.hbxlayout = QHBoxLayout(self.argGroupBox) self.argLineEdit = QLineEdit(self.argGroupBox) self.argLineEdit.setToolTip( 'Not touch if you dont know what are doing') self.argLineEdit.setPlaceholderText( 'Dont touch if you dont know what are doing') self.hbxlayout.addWidget( QLabel('<b>Additional Profile Arguments:</b>')) self.hbxlayout.addWidget(self.argLineEdit) self.hboxlayout3.addWidget(self.argGroupBox) self.vlayout3.addWidget(self.patz) self.tabWidget.addTab(self.pathz, " Paths and Configs ") self.outp = QWidget() self.vlayout4 = QVBoxLayout(self.outp) self.outgro = QGroupBox(self.outp) self.outgro.setTitle(" MultiProcessing Output Logs ") self.hboxlayout4 = QVBoxLayout(self.outgro) self.outputlog = QTextEdit() self.outputlog.setText(''' I do not fear computers, I fear the lack of them. -Isaac Asimov ''') self.hboxlayout4.addWidget(self.outputlog) self.vlayout4.addWidget(self.outgro) self.tabWidget.addTab(self.outp, " Logs ") self.actionNew_profiling = QAction(QIcon.fromTheme("document-new"), 'New Profiling', self) self.actionLoad_profile = QAction(QIcon.fromTheme("document-open"), 'Open Profiling', self) self.actionClean = QAction(QIcon.fromTheme("edit-clear"), 'Clean', self) self.actionClean.triggered.connect(lambda: self.clearContent) self.actionAbout = QAction(QIcon.fromTheme("help-about"), 'About', self) self.actionAbout.triggered.connect(lambda: QMessageBox.about( self.dock, __doc__, ', '.join( (__doc__, __license__, __author__, __email__)))) self.actionSave_profile = QAction(QIcon.fromTheme("document-save"), 'Save Profiling', self) self.actionManual = QAction(QIcon.fromTheme("help-contents"), 'Help', self) self.actionManual.triggered.connect(lambda: open_new_tab( 'http://docs.python.org/library/profile.html')) self.tabWidget.setCurrentIndex(2) self.globalStatGroupBox.setTitle("Global Statistics") item = self.tableWidget.horizontalHeaderItem(0) item.setText("Number of Calls") item = self.tableWidget.horizontalHeaderItem(1) item.setText("Total Time") item = self.tableWidget.horizontalHeaderItem(2) item.setText("Per Call") item = self.tableWidget.horizontalHeaderItem(3) item.setText("Cumulative Time") item = self.tableWidget.horizontalHeaderItem(4) item.setText("Per Call") item = self.tableWidget.horizontalHeaderItem(5) item.setText("Filename") item = self.tableWidget.horizontalHeaderItem(6) item.setText("Line") item = self.tableWidget.horizontalHeaderItem(7) item.setText("Function") self.tabWidget.setTabText(self.tabWidget.indexOf(self.stat), "Statistics per Function") self.sourceTreeWidget.headerItem().setText(0, "Source files") self.tabWidget.setTabText(self.tabWidget.indexOf(self.source), "Sources Navigator") ####################################################################### self.scrollable, self.dock = QScrollArea(), QDockWidget() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(self.tabWidget) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setWidget(self.scrollable) QToolBar(self.dock).addActions( (self.actionNew_profiling, self.actionClean, self.actionSave_profile, self.actionLoad_profile, self.actionManual, self.actionAbout)) self.actionNew_profiling.triggered.connect( self.on_actionNew_profiling_triggered) self.actionLoad_profile.triggered.connect( self.on_actionLoad_profile_triggered) self.actionSave_profile.triggered.connect( self.on_actionSave_profile_triggered) self.locator.get_service('misc').add_widget( self.dock, QIcon.fromTheme("document-open-recent"), __doc__) if QSCI: # Scintilla source editor management self.scintillaWarningLabel.setText(' QScintilla is Ready ! ') layout = self.source.layout() layout.removeWidget(self.sourceTextEdit) self.sourceTextEdit = Qsci.QsciScintilla(self.source) layout.addWidget(self.sourceTextEdit, 0, 1) doc = self.sourceTextEdit doc.setLexer(Qsci.QsciLexerPython(self.sourceTextEdit)) doc.setReadOnly(True) doc.setEdgeMode(Qsci.QsciScintilla.EdgeLine) doc.setEdgeColumn(80) doc.setEdgeColor(QColor("#FF0000")) doc.setFolding(Qsci.QsciScintilla.BoxedTreeFoldStyle) doc.setBraceMatching(Qsci.QsciScintilla.SloppyBraceMatch) doc.setCaretLineVisible(True) doc.setMarginLineNumbers(1, True) doc.setMarginWidth(1, 25) doc.setTabWidth(4) doc.setEolMode(Qsci.QsciScintilla.EolUnix) self.marker = {} for color in COLORS: mnr = doc.markerDefine(Qsci.QsciScintilla.Background) doc.setMarkerBackgroundColor(color, mnr) self.marker[color] = mnr self.currentSourcePath = None # Connect table and tree filter edit signal to unique slot self.filterTableLineEdit.textEdited.connect( self.on_filterLineEdit_textEdited) # Timer to display filter hint message self.filterHintTimer = QTimer(self) self.filterHintTimer.setSingleShot(True) self.filterHintTimer.timeout.connect(self.on_filterHintTimer_timeout) # Timer to start search self.filterSearchTimer = QTimer(self) self.filterSearchTimer.setSingleShot(True) self.filterSearchTimer.timeout.connect( self.on_filterSearchTimer_timeout) self.tabLoaded = {} for i in range(10): self.tabLoaded[i] = False self.backgroundTreeMatchedItems = {} self.resizeWidgetToContent(self.tableWidget) def on_actionNew_profiling_triggered(self): self.clearContent() self.scriptPath = str( QFileDialog.getOpenFileName(self.dock, "Choose your script to profile", path.expanduser("~"), "Python (*.py *.pyw)")) commandLine = [ self.profilerPath, "-o", self.tempPath, self.scriptPath ] + self.scriptArgs commandLine = " ".join(commandLine) ##if self.termCheckBox.checkState() == Qt.Checked: #termList = ["xterm", "aterm"] #for term in termList: #termPath = which(term) #if termPath: #break #commandLine = """%s -e "%s ; echo 'Press ENTER Exit' ; read" """ \ #% (termPath, commandLine) self.process.start(commandLine) if not self.process.waitForStarted(): print((" ERROR: {} failed!".format(commandLine))) return def on_process_finished(self, exitStatus): ' whan the process end ' print((" INFO: OK: QProcess is %s" % self.process.exitCode())) self.output = self.process.readAll().data() if not self.output: self.output = " ERROR: FAIL: No output ! " self.outputlog.setText(self.output + str(self.process.exitCode())) if path.exists(self.tempPath): self.setStat(self.tempPath) remove(self.tempPath) else: self.outputlog.setText(" ERROR: QProcess FAIL: Profiling failed.") self.tabWidget.setCurrentIndex(2) def on_process_error(self, error): ' when the process fail, I hope you never see this ' print(" ERROR: QProcess FAIL: Profiler Dead, wheres your God now ? ") if error == QProcess.FailedToStart: self.outputlog.setText(" ERROR: FAIL: Profiler execution failed ") elif error == QProcess.Crashed: self.outputlog.setText(" ERROR: FAIL: Profiler execution crashed ") else: self.outputlog.setText(" ERROR: FAIL: Profiler unknown error ") def on_actionLoad_profile_triggered(self): """Load a previous profile sessions""" statPath = str( QFileDialog.getOpenFileName(self.dock, "Open profile dump", path.expanduser("~"), "Profile file (*)")) if statPath: self.clearContent() print(' INFO: OK: Loading profiling from ' + statPath) self.setStat(statPath) def on_actionSave_profile_triggered(self): """Save a profile sessions""" statPath = str( QFileDialog.getSaveFileName(self.dock, "Save profile dump", path.expanduser("~"), "Profile file (*)")) if statPath: #TODO: handle error case and give feelback to user print(' INFO: OK: Saving profiling to ' + statPath) self.stat.save(statPath) #=======================================================================# # Common parts # #=======================================================================# def on_tabWidget_currentChanged(self, index): """slot for tab change""" # Kill search and hint timer if running to avoid cross effect for timer in (self.filterHintTimer, self.filterSearchTimer): if timer.isActive(): timer.stop() if not self.stat: #No stat loaded, nothing to do return self.populateTable() self.populateSource() def on_filterLineEdit_textEdited(self, text): """slot for filter change (table or tree""" if self.filterSearchTimer.isActive(): # Already runnning, stop it self.filterSearchTimer.stop() # Start timer self.filterSearchTimer.start(300) def on_filterHintTimer_timeout(self): """Timeout to warn user about text length""" print("timeout") tab = self.tabWidget.currentIndex() if tab == TAB_FUNCTIONSTAT: label = self.filterHintTableLabel label.setText("Type > 2 characters to search") def on_filterSearchTimer_timeout(self): """timeout to start search""" tab = self.tabWidget.currentIndex() if tab == TAB_FUNCTIONSTAT: text = self.filterTableLineEdit.text() label = self.filterHintTableLabel edit = self.filterTableLineEdit widget = self.tableWidget else: print("Unknow tab for filterSearch timeout !") print(("do search for %s" % text)) if not len(text): # Empty keyword, just clean all if self.filterHintTimer.isActive(): self.filterHintTimer.stop() label.setText(" ? ") self.warnUSer(True, edit) self.clearSearch() return if len(text) < 2: # Don't filter if text is too short and tell it to user self.filterHintTimer.start(600) return else: if self.filterHintTimer.isActive(): self.filterHintTimer.stop() label.setText(" ? ") # Search self.clearSearch() matchedItems = [] if tab == TAB_FUNCTIONSTAT: # Find items matchedItems = widget.findItems(text, Qt.MatchContains) widget.setSortingEnabled(False) matchedRows = [item.row() for item in matchedItems] # Hide matched items header = widget.verticalHeader() for row in range(widget.rowCount()): if row not in matchedRows: header.hideSection(row) widget.setSortingEnabled(True) else: print(" Unknow tab for filterSearch timeout ! ") print(("got %s members" % len(matchedItems))) self.warnUSer(matchedItems, edit) self.resizeWidgetToContent(widget) def resizeWidgetToContent(self, widget): """Resize all columns according to content""" for i in range(widget.columnCount()): widget.resizeColumnToContents(i) def clearSearch(self): """Clean search result For table, show all items For tree, remove colored items""" tab = self.tabWidget.currentIndex() if tab == TAB_FUNCTIONSTAT: header = self.tableWidget.verticalHeader() if header.hiddenSectionCount(): for i in range(header.count()): if header.isSectionHidden(i): header.showSection(i) def clearContent(self): # Clear tabs self.tableWidget.clearContents() self.sourceTreeWidget.clear() # Reset LCD numbers for lcdNumber in (self.totalTimeLcdNumber, self.numCallLcdNumber, self.primCallLcdNumber): lcdNumber.display(1000000) # Reset stat self.pstat = None # Disable save as menu self.actionSave_profile.setEnabled(False) # Mark all tabs as unloaded for i in range(10): self.tabLoaded[i] = False def warnUSer(self, result, inputWidget): palette = inputWidget.palette() if result: palette.setColor(QPalette.Normal, QPalette.Base, QColor(255, 255, 255)) else: palette.setColor(QPalette.Normal, QPalette.Base, QColor(255, 136, 138)) inputWidget.setPalette(palette) inputWidget.update() def setStat(self, statPath): self.stat = Stat(path=statPath) # Global stat update self.totalTimeLcdNumber.display(self.stat.getTotalTime()) self.numCallLcdNumber.display(self.stat.getCallNumber()) self.primCallLcdNumber.display(self.stat.getPrimitiveCallRatio()) # Refresh current tab self.on_tabWidget_currentChanged(self.tabWidget.currentIndex()) # Activate save as menu self.actionSave_profile.setEnabled(True) try: self.rating.setMaxRating(10) self.rating.setRating( int(self.stat.getPrimitiveCallRatio()) / 10 - 1) except: pass #========================================================================# # Statistics table # #=======================================================================# def populateTable(self): row = 0 rowCount = self.stat.getStatNumber() progress = QProgressDialog("Populating statistics table...", "Abort", 0, 2 * rowCount) self.tableWidget.setSortingEnabled(False) self.tableWidget.setRowCount(rowCount) progress.setWindowModality(Qt.WindowModal) for (key, value) in self.stat.getStatItems(): #ncalls item = StatTableWidgetItem(str(value[0])) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_NCALLS, item) colorTableItem(item, self.stat.getCallNumber(), value[0]) #total time item = StatTableWidgetItem(str(value[2])) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_TTIME, item) colorTableItem(item, self.stat.getTotalTime(), value[2]) #per call (total time) if value[0] != 0: tPerCall = str(value[2] / value[0]) cPerCall = str(value[3] / value[0]) else: tPerCall = "" cPerCall = "" item = StatTableWidgetItem(tPerCall) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_TPERCALL, item) colorTableItem( item, 100.0 * self.stat.getTotalTime() / self.stat.getCallNumber(), tPerCall) #per call (cumulative time) item = StatTableWidgetItem(cPerCall) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_CPERCALL, item) colorTableItem( item, 100.0 * self.stat.getTotalTime() / self.stat.getCallNumber(), cPerCall) #cumulative time item = StatTableWidgetItem(str(value[3])) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_CTIME, item) colorTableItem(item, self.stat.getTotalTime(), value[3]) #Filename self.tableWidget.setItem(row, STAT_FILENAME, StatTableWidgetItem(str(key[0]))) #Line item = StatTableWidgetItem(str(key[1])) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_LINE, item) #Function name self.tableWidget.setItem(row, STAT_FUNCTION, StatTableWidgetItem(str(key[2]))) row += 1 # Store it in stat hash array self.stat.setStatLink(item, key, TAB_FUNCTIONSTAT) progress.setValue(row) if progress.wasCanceled(): return for i in range(self.tableWidget.rowCount()): progress.setValue(row + i) for j in range(self.tableWidget.columnCount()): item = self.tableWidget.item(i, j) if item: item.setFlags(Qt.ItemIsEnabled) self.tableWidget.setSortingEnabled(True) self.resizeWidgetToContent(self.tableWidget) progress.setValue(2 * rowCount) def on_tableWidget_itemDoubleClicked(self, item): matchedItems = [] filename = str(self.tableWidget.item(item.row(), STAT_FILENAME).text()) if not filename or filename.startswith("<"): # No source code associated, return immediatly return function = self.tableWidget.item(item.row(), STAT_FUNCTION).text() line = self.tableWidget.item(item.row(), STAT_LINE).text() self.on_tabWidget_currentChanged(TAB_SOURCE) # load source tab function = "%s (%s)" % (function, line) fathers = self.sourceTreeWidget.findItems(filename, Qt.MatchContains, SOURCE_FILENAME) print(("find %s father" % len(fathers))) for father in fathers: findItems(father, function, SOURCE_FILENAME, matchedItems) print(("find %s items" % len(matchedItems))) if matchedItems: self.tabWidget.setCurrentIndex(TAB_SOURCE) self.sourceTreeWidget.scrollToItem(matchedItems[0]) self.on_sourceTreeWidget_itemClicked(matchedItems[0], SOURCE_FILENAME) matchedItems[0].setSelected(True) else: print("oups, item found but cannot scroll to it !") #=======================================================================# # Source explorer # #=====================================================================# def populateSource(self): items = {} for stat in self.stat.getStatKeys(): source = stat[0] function = "%s (%s)" % (stat[2], stat[1]) if source in ("", "profile") or source.startswith("<"): continue # Create the function child child = QTreeWidgetItem([function]) # Store it in stat hash array self.stat.setStatLink(child, stat, TAB_SOURCE) if source in items: father = items[source] else: # Create the father father = QTreeWidgetItem([source]) items[source] = father father.addChild(child) self.sourceTreeWidget.setSortingEnabled(False) for value in list(items.values()): self.sourceTreeWidget.addTopLevelItem(value) self.sourceTreeWidget.setSortingEnabled(True) def on_sourceTreeWidget_itemActivated(self, item, column): self.on_sourceTreeWidget_itemClicked(item, column) def on_sourceTreeWidget_itemClicked(self, item, column): line = 0 parent = item.parent() if QSCI: doc = self.sourceTextEdit if parent: pathz = parent.text(column) result = match("(.*) \(([0-9]+)\)", item.text(column)) if result: try: function = str(result.group(1)) line = int(result.group(2)) except ValueError: # We got garbage... falling back to line 0 pass else: pathz = item.text(column) pathz = path.abspath(str(pathz)) if self.currentSourcePath != pathz: # Need to load source self.currentSourcePath == pathz try: if QSCI: doc.clear() doc.insert(file(pathz).read()) else: self.sourceTextEdit.setPlainText(file(pathz).read()) except IOError: QMessageBox.warning(self, "Error", "Source file could not be found", QMessageBox.Ok) return if QSCI: for function, line in [(i[2], i[1]) for i in self.stat.getStatKeys() if i[0] == pathz]: # expr, regexp, case sensitive, whole word, wrap, forward doc.findFirst("def", False, True, True, False, True, line, 0, True) end, foo = doc.getCursorPosition() time = self.stat.getStatTotalTime((pathz, line, function)) colorSource(doc, self.stat.getTotalTime(), time, line, end, self.marker) if QSCI: doc.ensureLineVisible(line)
class MainWidget(QMainWindow): def __init__(self, parent=None): super(MainWidget, self).__init__(parent, windowTitle='GithubRemote', windowIcon=QIcon(image_path('git.png')), geometry=QRect(300, 300, 600, 372)) self.repo_pixmap = QPixmap(image_path('book_16.png')) self.big_repo_pixmap = QPixmap(image_path('book_32.png')) self.repo_fork_pixmap = QPixmap(image_path('book_fork_16.png')) self.star_pixmap = QPixmap(image_path('star_16.png')) self.big_star_pixmap = QPixmap(image_path('star_32.png')) self.fork_pixmap = QPixmap(image_path('fork_16.png')) self.eye_pixmap = QPixmap(image_path('eye_16.png')) self.github = None # Actions self.repoAddAction = QAction(QIcon(image_path('plus_48.png')), '&Add Repo', self, statusTip='Add a new repo') self.repoAddAction.triggered.connect(self.repoAdd) self.repoRemoveAction = QAction(QIcon(image_path('minus.png')), '&Remove Repo', self, statusTip='Remove repo') self.repoRemoveAction.triggered.connect(self.repoRemove) self.repoRefreshAction = QAction(QIcon(image_path('refresh.png')), 'Refresh', self, statusTip='Refresh list of repos') self.repoRefreshAction.triggered.connect(self.reposRefresh) self.repoRefreshAction.triggered.connect(self.starsRefresh) self.addAccountAction = QAction('Add Account', self, statusTip='Add Account') self.addAccountAction.triggered.connect(self.addAccount) # userPushButton - Displays the current active username and # image on the top right of the toolbar. self.userButtonMenu = UserButtonMenu(32, 32) # ToolBar self.toolBar = self.addToolBar('Main') self.toolBar.setMovable(False) self.toolBar.setFloatable(False) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.toolBar.addAction(self.repoAddAction) self.toolBar.addAction(self.repoRemoveAction) self.toolBar.addAction(self.repoRefreshAction) self.toolBar.addWidget(spacer) self.toolBar.addWidget(self.userButtonMenu) # Menu menuBar = self.menuBar() fileMenu = menuBar.addMenu('&File') actionMenu = menuBar.addMenu('&Action') fileMenu.addAction(self.addAccountAction) actionMenu.addAction(self.repoAddAction) actionMenu.addAction(self.repoRemoveAction) actionMenu.addAction(self.repoRefreshAction) # StatusBar statusBar = self.statusBar() self.setStatusBar(statusBar) # reposTableWidget - Displays a list of the users repositories self.reposTableWidget = QTableWidget( 0, 5, selectionBehavior=QAbstractItemView.SelectRows, selectionMode=QAbstractItemView.SingleSelection, editTriggers=QAbstractItemView.NoEditTriggers, itemSelectionChanged=self.actionsUpdate) self.reposTableWidget.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.reposTableWidget.horizontalHeader().setResizeMode( 1, QHeaderView.Stretch) self.reposTableWidget.horizontalHeader().setVisible(False) self.reposTableWidget.verticalHeader().setVisible(False) self.reposTableWidget.setShowGrid(False) self.reposTableWidget.verticalHeader().setMinimumSectionSize(25) # repoTab - Layout reposTab = QWidget() reposTabLayout = QVBoxLayout(reposTab) reposTabLayout.addWidget(self.reposTableWidget) reposTab.setLayout(reposTabLayout) # starsTableWidget - Displays a list of the users repositories self.starsTableWidget = QTableWidget( 0, 5, selectionBehavior=QAbstractItemView.SelectRows, selectionMode=QAbstractItemView.SingleSelection, editTriggers=QAbstractItemView.NoEditTriggers, itemSelectionChanged=self.actionsUpdate) self.starsTableWidget.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.starsTableWidget.horizontalHeader().setResizeMode( 1, QHeaderView.Stretch) self.starsTableWidget.horizontalHeader().setVisible(False) self.starsTableWidget.verticalHeader().setVisible(False) self.starsTableWidget.setShowGrid(False) self.starsTableWidget.verticalHeader().setMinimumSectionSize(25) # repoTab - Layout starsTab = QWidget() starsTabLayout = QVBoxLayout(starsTab) starsTabLayout.addWidget(self.starsTableWidget) starsTab.setLayout(starsTabLayout) # Tab Widget self.tabs = QTabWidget() self.tabs.setTabBar(FlippedTabBar(self)) self.tabs.addTab(reposTab, QIcon(self.big_repo_pixmap), "repos") self.tabs.addTab(starsTab, QIcon(self.big_star_pixmap), "stars") self.tabs.setTabPosition(QTabWidget.West) # Layout self.setCentralWidget(self.tabs) self.actionsUpdate() self.show() # Update self.loadUserMenu() if self.activeUserAction: self.activeUserAction.setVisible(False) self.authenticate() self.actionsUpdate() self.reposRefresh() self.starsRefresh() self.updateImage() @waiting_effects def updateImage(self): try: url = self.github.get_user().avatar_url except (GithubException, AttributeError): return data = urllib.urlopen(url).read() pixmap = QPixmap() pixmap.loadFromData(data) self.activeUserAction.setIcon(QIcon(pixmap)) self.userButtonMenu.setPixmap(pixmap) self.userButtonMenu.setText(self.github.get_user().login) @waiting_effects def loadUserMenu(self): action = None for _, username, token in generate_tokens(CONFIG_PATH, 'github'): try: url = Github(token).get_user().avatar_url except (GithubException, AttributeError): action = QAction(username, self, triggered=self.changeActive) self.userButtonMenu.addAction(action) continue data = urllib.urlopen(url).read() pixmap = QPixmap() pixmap.loadFromData(data) action = QAction(QIcon(pixmap), username, self, triggered=self.changeActive) action.setIconVisibleInMenu(True) self.userButtonMenu.addAction(action) self.activeUserAction = action def changeActive(self): sender = self.sender() self.activeUserAction.setVisible(True) self.activeUserAction = sender self.activeUserAction.setVisible(False) self.authenticate() self.actionsUpdate() self.reposRefresh() self.starsRefresh() self.updateImage() @waiting_effects def reposRefresh(self): self.reposTableWidget.clearContents() try: repos = self.github.get_user().get_repos() self.reposTableWidget.setRowCount( self.github.get_user().public_repos) except (GithubException, AttributeError): return for row, repo in enumerate(repos): imageLabel = QLabel() if repo.fork: imageLabel.setPixmap(self.repo_fork_pixmap) else: imageLabel.setPixmap(self.repo_pixmap) imageLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) imageLabel.setMargin(5) self.reposTableWidget.setCellWidget(row, 0, imageLabel) label = QLabel('<b>{}</b><br />{}'.format(str(repo.name), str(repo.description))) label.setAlignment(Qt.AlignVCenter) label.setMargin(5) label.setWordWrap(True) self.reposTableWidget.setCellWidget(row, 1, label) self.reposTableWidget.setItem( row, 2, QTableWidgetItem(QIcon(self.star_pixmap), str(repo.stargazers_count))) self.reposTableWidget.setItem( row, 3, QTableWidgetItem(QIcon(self.eye_pixmap), str(repo.watchers_count))) self.reposTableWidget.setItem( row, 4, QTableWidgetItem(QIcon(self.fork_pixmap), str(repo.forks_count))) self.reposTableWidget.resizeRowsToContents() @waiting_effects def starsRefresh(self): self.starsTableWidget.clearContents() try: starred = self.github.get_user().get_starred() self.starsTableWidget.setRowCount( self.github.get_user().public_repos) except (GithubException, AttributeError): return for row, repo in enumerate(starred): imageLabel = QLabel() if repo.fork: imageLabel.setPixmap(self.repo_fork_pixmap) else: imageLabel.setPixmap(self.repo_pixmap) imageLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) imageLabel.setMargin(5) self.starsTableWidget.setCellWidget(row, 0, imageLabel) label = QLabel(u'<b>{}/{}</b><br />{}'.format( unicode(repo.owner.login), unicode(repo.name), unicode(repo.description))) label.setAlignment(Qt.AlignVCenter) label.setMargin(5) label.setWordWrap(True) self.starsTableWidget.setCellWidget(row, 1, label) self.starsTableWidget.setItem( row, 2, QTableWidgetItem(QIcon(self.star_pixmap), '0')) self.starsTableWidget.setItem( row, 3, QTableWidgetItem(QIcon(self.eye_pixmap), str(repo.watchers_count))) self.starsTableWidget.setItem( row, 4, QTableWidgetItem(QIcon(self.fork_pixmap), str(repo.forks_count))) self.starsTableWidget.resizeRowsToContents() @waiting_effects def authenticate(self): if self.activeUserAction: username = str(self.activeUserAction.text()) token = load_token(CONFIG_PATH, 'github', username) self.github = Github(token) else: self.github = None def actionsUpdate(self): # TODO disable if no user is logged in if self.github is None: self.repoAddAction.setEnabled(False) self.repoRemoveAction.setEnabled(False) self.repoRefreshAction.setEnabled(False) else: self.repoAddAction.setEnabled(True) self.repoRefreshAction.setEnabled(True) if self._isARepoSelected(): self.repoRemoveAction.setEnabled(True) else: self.repoRemoveAction.setEnabled(False) def addAccount(self): wizard = AddAccountWizard(self) if wizard.exec_(): username = str(wizard.field('username').toString()) token = str(wizard.field('token').toString()) store_token(CONFIG_PATH, 'github', username, token) self.authenticate() self.reposRefresh() self.updateImage() self.actionsUpdate() def repoAdd(self): wizard = AddRepoWizard(self.github, self) if wizard.exec_(): self.github.get_user().create_repo( str(wizard.field('name').toString()), description=str(wizard.field('description').toString()), private=bool(wizard.field('private').toBool()), auto_init=bool(wizard.field('auto_init').toBool()), gitignore_template=str(wizard.field('gitignore').toString()), homepage=str(wizard.field('homepage').toString()), has_wiki=bool(wizard.field('has_wiki').toBool()), has_downloads=bool(wizard.field('has_downloads').toBool()), has_issues=bool(wizard.field('has_issues').toBool())) self.reposRefresh() def repoRemove(self): row = self._selectedRepoRow() name = self.reposTableWidget.item(row, 0).text() dialog = RepoRemoveDialog(self.github, name) if dialog.exec_(): self.github.get_user().get_repo(str(name)).delete() self.reposRefresh() def _isARepoSelected(self): """ Return True if a repo is selected else False """ if len(self.reposTableWidget.selectedItems()) > 0: return True else: return False def _selectedRepoRow(self): """ Return the currently select repo """ # TODO - figure out what happens if no repo is selected selectedModelIndexes = \ self.reposTableWidget.selectionModel().selectedRows() for index in selectedModelIndexes: return index.row()
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): logging.info(u'创建主窗口...') QtGui.QMainWindow.__init__(self, parent) tabs = QtGui.QTabWidget(self) tab2 = QtGui.QWidget() tab3 = QtGui.QWidget() self.console = MyConsole(parent=self) # tab2 - self.console self.console.setMinimumSize(1500, 800) scroll = QtGui.QScrollArea() scroll.setWidget(self.console) scroll.setAutoFillBackground(True) scroll.setWidgetResizable(True) vbox = QtGui.QVBoxLayout() vbox.addWidget(scroll) tab2.setLayout(vbox) # tab3 - self.viewEntry = QTableWidget(0, 12) self.viewEntry.setHorizontalHeaderLabels( [u'期数', u'时间', u'冠军', u'亚军', u'第三名', u'第四名', u'第五名', u'第六名', u'第七名', u'第八名', u'第九名', u'第十名']) self.viewEntry.horizontalHeader().setStretchLastSection(True) self.viewEntry.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) vbox3 = QtGui.QVBoxLayout() vbox3.addWidget(self.viewEntry) tab3.setLayout(vbox3) tabs.addTab(tab2, u"控制台") tabs.addTab(tab3, u"开奖结果") tabs.resize(1500, 800) self.resize(1500, 800) self.tabs = tabs self.tab2 = tab2 self.tab3 = tab3 self.scroll = scroll # 禁止最大化 self.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint) from myutil.tool.Overlay import Overlay self.setCentralWidget(self.tabs) self.overlay = Overlay(self.centralWidget()) self.overlay.hide() self.show() @pyqtSlot(str) def mySetWindowTitle(self, title): self.setWindowTitle(title) @pyqtSlot(str, list) def completeHistoryResultData(self, timesnow, open_balls): logging.info(u"【主窗口-历史数据展板-填充之】") for i in range(len(open_balls)): newItem = QTableWidgetItem(str(open_balls[i])) self.viewEntry.setItem(0, 2 + i, newItem) logging.info(u"【主窗口-历史数据展板-填充完毕】") @pyqtSlot(str, list) def appendHistoryResultData(self, timesnow, open_balls): logging.info(u"【主窗口-历史数据展板-追加】") time_str = MyTool.getCurrentTimeStr() self.viewEntry.insertRow(0) # 期数 newItem = QTableWidgetItem(str(int(timesnow) - 1)) self.viewEntry.setItem(0, 0, newItem) # 时间 newItem = QTableWidgetItem(time_str) self.viewEntry.setItem(0, 1, newItem) for i in range(len(open_balls)): newItem = QTableWidgetItem(str(open_balls[i])) self.viewEntry.setItem(0, 2 + i, newItem) logging.info(u"【主窗口-历史数据展板-追加完毕】") @pyqtSlot(list) def updateHistoryResultData(self, data_list): logging.info(u"【主窗口-历史数据展板-大更新】################START HistoryResultData################") # 先清空... self.viewEntry.clearContents() self.viewEntry.setRowCount(0) for period in data_list: # 添加一行 row = self.viewEntry.rowCount() self.viewEntry.insertRow(row) # 期数 newItem = QTableWidgetItem(period[0]) self.viewEntry.setItem(row, 0, newItem) # 时间 newItem = QTableWidgetItem(str(period[1])) self.viewEntry.setItem(row, 1, newItem) if self.console.play_mode in [common.PLAYMODE_PK10, common.PLAYMODE_XYFT]: for i in range(10): newItem = QTableWidgetItem(str(period[2 + i])) self.viewEntry.setItem(row, 2 + i, newItem) else: for i in range(5): newItem = QTableWidgetItem(str(period[2 + i])) self.viewEntry.setItem(row, 2 + i, newItem) logging.info(u"【主窗口-历史数据展板-大更新】################END HistoryResultData################") def closeEvent(self, event): reply = QtGui.QMessageBox.question(self, u'退出', u"您确定离开吗?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: # 关闭http连接... from common.common import req_session req_session.close() event.accept() else: event.ignore() def resizeEvent(self, event): self.overlay.resize(event.size()) event.accept()
class ScanRecordTable(QGroupBox): """ GUI component. Displays a list of previous scan results. Selecting a scan causes details of the scan to appear in other GUI components (list of barcodes in the barcode table and image of the puck in the image frame). """ COLUMNS = ['Date', 'Time', 'Plate Type', 'Valid', 'Invalid', 'Empty'] def __init__(self, barcode_table, image_frame, options): super(ScanRecordTable, self).__init__() # Read the store from file self._store = Store(options.store_directory.value(), options) self._options = options self._barcodeTable = barcode_table self._imageFrame = image_frame self.setTitle("Scan Records") self._init_ui() self._load_store_records() def _init_ui(self): # Create record table - lists all the records in the store self._table = QTableWidget() self._table.setFixedWidth(440) self._table.setFixedHeight(600) self._table.setColumnCount(len(self.COLUMNS)) self._table.setHorizontalHeaderLabels(self.COLUMNS) self._table.setColumnWidth(0, 70) self._table.setColumnWidth(1, 55) self._table.setColumnWidth(2, 85) self._table.setColumnWidth(3, 60) self._table.setColumnWidth(4, 60) self._table.setColumnWidth(5, 60) self._table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self._table.cellPressed.connect(self._record_selected) # Delete button - deletes selected records btn_delete = QtGui.QPushButton('Delete') btn_delete.setToolTip('Delete selected scan/s') btn_delete.resize(btn_delete.sizeHint()) btn_delete.clicked.connect(self._delete_selected_records) hbox = QHBoxLayout() hbox.setSpacing(10) hbox.addWidget(btn_delete) hbox.addStretch(1) vbox = QVBoxLayout() vbox.addWidget(self._table) vbox.addLayout(hbox) self.setLayout(vbox) def add_record(self, plate, image): """ Add a new scan record to the store and display it. """ self._store.add_record(plate, image) self._load_store_records() def add_record_frame(self, plate, image): """ Add a new scan frame - creates a new record if its a new puck, else merges with previous record""" self._store.merge_record(plate, image) self._load_store_records() if self._options.scan_clipboard.value(): self._barcodeTable.copy_selected_to_clipboard() def _load_store_records(self): """ Populate the record table with all of the records in the store. """ self._table.clearContents() self._table.setRowCount(self._store.size()) for n, record in enumerate(self._store.records): items = [record.date, record.time, record.plate_type, record.num_valid_barcodes, record.num_unread_slots, record.num_empty_slots] if (record.num_valid_barcodes + record.num_empty_slots) == record.num_slots: color = self._options.col_ok() else: color = self._options.col_bad() color.a = 192 for m, item in enumerate(items): new_item = QtGui.QTableWidgetItem(str(item)) new_item.setBackgroundColor(color.to_qt()) new_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self._table.setItem(n, m, new_item) # Display the first (most recent) record self._table.setCurrentCell(0, 0) self._record_selected() def _record_selected(self): """ Called when a row is selected, causes details of the selected record to be displayed (list of barcodes in the barcode table and image of the scan in the image frame). """ try: row = self._table.selectionModel().selectedRows()[0].row() record = self._store.get_record(row) self._barcodeTable.populate(record.barcodes) marked_image = record.marked_image(self._options) self._imageFrame.display_puck_image(marked_image) except IndexError: pass self._barcodeTable.populate([]) self._imageFrame.clear_frame() def _delete_selected_records(self): """ Called when the 'Delete' button is pressed. Deletes all of the selected records (and the associated images) from the store and from disk. Asks for user confirmation. """ # Display a confirmation dialog to check that user wants to proceed with deletion quit_msg = "This operation cannot be undone.\nAre you sure you want to delete these record/s?" reply = QtGui.QMessageBox.warning(self, 'Confirm Delete', quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) # If yes, find the appropriate records and delete them if reply == QtGui.QMessageBox.Yes: rows = self._table.selectionModel().selectedRows() records_to_delete = [] for row in rows: index = row.row() record = self._store.get_record(index) records_to_delete.append(record) self._store.delete_records(records_to_delete) self._load_store_records()
class ProcExpWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) # setup menu bar exitItem = QAction('Exit', self) exitItem.setShortcut('Ctrl+Q') exitItem.setStatusTip('Exit application') exitItem.triggered.connect(self.close) menuBar = self.menuBar() fileMenu = menuBar.addMenu('&File') fileMenu.addAction(exitItem) # setup widgets self.model = ProcTableModel(self) self.procTable = ProcTableWidget(self.model) self.procTable.clicked.connect(self.showDescriptors) self.handlesTable = QTableWidget() self.handlesTable.setColumnCount(2) self.handlesTable.setHorizontalHeaderLabels(('Type', 'Object Name')) self.handlesTable.verticalHeader().setVisible(False) self.handlesTable.setShowGrid(False) self.handlesTable.setSelectionBehavior(QTableWidget.SelectRows) self.handlesTable.horizontalHeader().setStretchLastSection(True) # TODO: find a way to get the row height from the QTreeView self.handlesTable.verticalHeader().setDefaultSectionSize(24) mainSplitter = QSplitter(Qt.Vertical) mainSplitter.addWidget(self.procTable) mainSplitter.addWidget(self.handlesTable) self.setCentralWidget(mainSplitter) desktopGeometry = QApplication.desktop().screenGeometry() self.setGeometry(0, 0, 1280, 700) self.move((desktopGeometry.width() - self.width()) / 2, (desktopGeometry.height() - self.height()) / 2) self.setWindowTitle('Linux Process Explorer') # find handle dialog self.findDialog = None @pyqtSlot(int) def removeFindDialog(self): self.findDialog = None def keyPressEvent(self, event): modifiers = event.modifiers() if event.key() == Qt.Key_F and modifiers & Qt.ControlModifier: if self.findDialog is None: self.findDialog = FindHandleDialog(self.model, self) self.findDialog.finished.connect(self.removeFindDialog) self.findDialog.show() else: self.findDialog.activateWindow() else: super().keyPressEvent(event) @pyqtSlot(QModelIndex) def showDescriptors(self, processMIdx): try: self.handlesTable.setRowCount(0) self.handlesTable.clearContents() descriptors = self.model.getProcDescriptors(processMIdx) libs = self.model.getProcLibraries(processMIdx) self.handlesTable.setRowCount(len(descriptors) + len(libs)) except PermissionError: self.handlesTable.setRowCount(1) self.handlesTable.setSpan(0, 0, 1, 2) permDeniedMsg = QTableWidgetItem('<Permission Denied>') permDeniedMsg.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) permDeniedMsg.setTextAlignment(Qt.AlignCenter) permDeniedMsg.setTextColor(QColor(255, 0, 0)) self.handlesTable.setItem(0, 0, permDeniedMsg) else: for row, descriptor in enumerate(descriptors): typeItem = QTableWidgetItem(descriptor.type) typeItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) nameItem = QTableWidgetItem(descriptor.name) nameItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.handlesTable.setItem(row, 0, typeItem) self.handlesTable.setItem(row, 1, nameItem) for row, libName in enumerate(libs, start=len(descriptors)): typeItem = QTableWidgetItem('Shared Library') typeItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) nameItem = QTableWidgetItem(libName) nameItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.handlesTable.setItem(row, 0, typeItem) self.handlesTable.setItem(row, 1, nameItem)
class OptimizateNewSiteUI(QDialog): def __init__(self, iface, parent=None): super(OptimizateNewSiteUI, self).__init__() self.iface = iface self.parent = parent self.initUI() # 初始化界面 def initUI(self): self.setWindowTitle(u'自动规划基站优化') self.setWindowIcon(QIcon('images/logo.png')) self.resize(600, 300) self.setWindowFlags(Qt.WindowMinMaxButtonsHint) self.initView() def initView(self): # 数据表格 self.tableWidget = QTableWidget(self) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.setRowCount(7) # 设置当前Table不能编辑 self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers) # 初始化表格上下文菜单 self.initTableContextMenu() self.initTableHeader() # 定义按钮 impBtn = QPushButton(u"导入EXCEL表", self) self.connect(impBtn, SIGNAL('clicked()'), self.impData) startBtn = QPushButton(u"开始合并", self) self.connect(startBtn, SIGNAL('clicked()'), self.mergeJSite) #布局 hbox = QHBoxLayout() hbox.addWidget(impBtn) hbox.addWidget(startBtn) vbox = QVBoxLayout() vbox.addWidget(self.tableWidget) vbox.addLayout(hbox) self.setLayout(vbox) # 判断是否已有规划基站结果 layer = getLayerByName(u'规划基站结果', self.iface) if layer: data_list = [] for feature in layer.getFeatures(): temp_list = [] for value in feature.attributes(): temp_list.append(value) data_list.append(temp_list) del temp_list self.initTable(data_list) self.__mlist = data_list def initTableContextMenu(self): self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.popMenu = QMenu(self.tableWidget) delAction = QAction(u'删除', self) # 删除 self.popMenu.addAction(delAction) # 初始化Table的头 def initTableHeader(self): self.heads = [] self.heads = MergeSiteHead self.tableWidget.setColumnCount(len(self.heads)) # 设置表格的列数 for (i, h) in enumerate(self.heads): tabItem = QTableWidgetItem(h) self.tableWidget.setHorizontalHeaderItem(i, tabItem) # 导入Excel表数据 def impData(self): fileName = QFileDialog.getOpenFileName(self, u'数据导入', '/', 'Excel Files (*.xls *.xlsx)') if fileName != None and fileName != '': self.impType = ExcelType.MERGESITE getDataFromExcel = GetDataFromExcel(fileName, self.impType) datas_list = getDataFromExcel.getData() self.impFinish(datas_list) # 导入数据完成绑定函数 def impFinish(self, mylist): self.__mlist = [] self.__mlist.extend(mylist) self.tableWidget.clearContents() self.initTable(self.__mlist) # 初始化表格的每个Item def initTable(self, mlist): self.tableWidget.setRowCount(len(mlist)) for (i, v) in enumerate(mlist): for (j, item) in enumerate(v): if type(item) != str: item = unicode(item) if item == None: item = '' tabItem = QTableWidgetItem(item) tabItem.setTextAlignment(Qt.AlignCenter) self.tableWidget.setItem(i, j, tabItem) # 开始运行 def mergeJSite(self): self.accept() merge = OptimizateNewSite(self.__mlist, self) merge.calculationResult.connect(self.calculationFinish) merge.run() def calculationFinish(self, merge_result): self.setResultLayer(merge_result) fileName = QFileDialog.getSaveFileName(self, u'合并结果导出到 ...', '/', 'Excel File(*.xls *.xlsx)') if fileName: self.sphead = [u'规划基站名称', u'经度', u'纬度', u'区域类型', u"平均距离"] for i in range(6): # 根据输入的参数增加表头 self.sphead.append(u'基站名称') self.sphead.append(u'距离') self.sphead.append(u'经度') self.sphead.append(u'纬度') layer = getLayerByName(u"基站合并结果", self.iface) if not layer: QMessageBox.critical(self, u"错误", u"找不到基站合并结果图层") exportData = ExportData(self.iface, self) if exportData.exportDataToExcel(layer, fileName): QMessageBox.information(self, u"成功", u"数据导出成功!") else: QMessageBox.critical(self, u"错误", u"数据导出失败!") else: self.close() # 生成规划基站结果图层 def setResultLayer(self, result_list): layerName = u'规划基站优化结果' layerType = QGis.WKBPoint project_dir = getProjectDir(self.iface) # 先判断是否已存在规划基站结果图层 result_layer = getLayerByName(layerName, self.iface) if result_layer: # 清空数据 delAllFeatures(result_layer) else: # 删除原有图层文件 deleteShapefile(project_dir, layerName) shapPath = os.path.join(project_dir, layerName + u".shp") # 生成图层 fileds = self.createFields() # 创建出Shap文件 # 数据源编码模式为GBK2312(否则中文字段会乱码) wr = QgsVectorFileWriter(shapPath, "GBK2312", fileds, layerType, None, "ESRI Shapefile") # 如果保存的时候没有错误 if wr.hasError() == QgsVectorFileWriter.NoError: pass else: print wr.hasError() raise Exception, wr.errorMessage() # 发生错误,抛出异常交给外面的方法处理异常 del wr # 使添加的字段生效 result_layer = QgsVectorLayer(shapPath, layerName, 'ogr') QgsMapLayerRegistry.instance().addMapLayer(result_layer) # 添加数据 features_list = [] for result in result_list: feature = createABasicPointFeature( QgsPoint(float(result[1]), float(result[2])), result) features_list.append(feature) importFeaturesToLayer(result_layer, features_list) def createFields(self): names = PLANNINGHead types = PLANNINGType2 lengs = PLANNINGLength precs = PLANNINGPrec fields = QgsFields() for (i, itm) in enumerate(names): cuType = types[i] mtype = 'String' if cuType == QVariant.Int: mtype = 'Integer' elif cuType == QVariant.Double: mtype = 'Real' field = QgsField(itm, cuType, mtype, lengs[i], precs[i]) fields.append(field) return fields def exportFinish(self, result): QMessageBox.information(self, u'新建基站结果', u'数据导出到Excel表完成,请查看') def exportError(self, e, erStr): QMessageBox.information(self, u'新建结果', u'生成基站时,发生错误,请重试+' + erStr)
class ScanRecordTable(QGroupBox): """ GUI component. Displays a list of previous scan results. Selecting a scan causes details of the scan to appear in other GUI components (list of barcodes in the barcode table and image of the puck in the image frame). """ COLUMNS = [ 'Date', 'Time', 'Plate Barcode', 'Plate Type', 'Valid', 'Invalid', 'Empty' ] def __init__(self, barcode_table, image_frame, options, to_run_on_table_clicked): super(ScanRecordTable, self).__init__() # Read the store from file self._store = Store(options.store_directory.value(), options.store_capacity, FileManager()) self._options = options self._barcodeTable = barcode_table self._imageFrame = image_frame self.setTitle("Scan Records") self._init_ui(to_run_on_table_clicked) self._load_store_records() def _init_ui(self, to_run_on_table_clicked): # Create record table - lists all the records in the store self._table = QTableWidget() self._table.setFixedWidth(440) self._table.setFixedHeight(600) self._table.setColumnCount(len(self.COLUMNS)) self._table.setHorizontalHeaderLabels(self.COLUMNS) self._table.setColumnWidth(0, 70) self._table.setColumnWidth(1, 55) self._table.setColumnWidth(2, 85) self._table.setColumnWidth(3, 70) self._table.setColumnWidth(4, 45) self._table.setColumnWidth(5, 50) self._table.setColumnWidth(6, 45) self._table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) self._table.cellPressed.connect(to_run_on_table_clicked) self._table.cellPressed.connect(self._record_selected) # Delete button - deletes selected records btn_delete = QtGui.QPushButton('Delete') btn_delete.setToolTip('Delete selected scan/s') btn_delete.resize(btn_delete.sizeHint()) btn_delete.clicked.connect(self._delete_selected_records) hbox = QHBoxLayout() hbox.setSpacing(10) hbox.addWidget(btn_delete) hbox.addStretch(1) vbox = QVBoxLayout() vbox.addWidget(self._table) vbox.addLayout(hbox) self.setLayout(vbox) def add_record_frame(self, holder_barcode, plate, holder_img, pins_img): """ Add a new scan frame - creates a new record if its a new puck, else merges with previous record""" self._store.merge_record(holder_barcode, plate, holder_img, pins_img) self._load_store_records() if self._options.scan_clipboard.value(): self._barcodeTable.copy_to_clipboard() def _load_store_records(self): """ Populate the record table with all of the records in the store. """ self._table.clearContents() self._table.setRowCount(self._store.size()) for n, record in enumerate(self._store.records): items = [ record.date, record.time, record.holder_barcode, record.plate_type, record.num_valid_barcodes, record.num_unread_slots, record.num_empty_slots ] if (record.num_valid_barcodes + record.num_empty_slots) == record.num_slots: color = self._options.col_ok() else: color = self._options.col_bad() color.a = 192 for m, item in enumerate(items): new_item = QtGui.QTableWidgetItem(str(item)) new_item.setBackgroundColor(color.to_qt()) new_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self._table.setItem(n, m, new_item) # Display the first (most recent) record self._table.setCurrentCell(0, 0) self._record_selected() def _record_selected(self): """ Called when a row is selected, causes details of the selected record to be displayed (list of barcodes in the barcode table and image of the scan in the image frame). """ try: row = self._table.selectionModel().selectedRows()[0].row() record = self._store.get_record(row) self._barcodeTable.populate(record.holder_barcode, record.barcodes) marked_image = record.marked_image(self._options) self._imageFrame.display_puck_image(marked_image) except IndexError: self._barcodeTable.clear() self._imageFrame.clear_frame( "Record table empty\nNothing to display") def _delete_selected_records(self): """ Called when the 'Delete' button is pressed. Deletes all of the selected records (and the associated images) from the store and from disk. Asks for user confirmation. """ # Display a confirmation dialog to check that user wants to proceed with deletion quit_msg = "This operation cannot be undone.\nAre you sure you want to delete these record/s?" reply = QtGui.QMessageBox.warning(self, 'Confirm Delete', quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) # If yes, find the appropriate records and delete them if reply == QtGui.QMessageBox.Yes: rows = self._table.selectionModel().selectedRows() records_to_delete = [] for row in rows: index = row.row() record = self._store.get_record(index) records_to_delete.append(record) self._store.delete_records(records_to_delete) self._load_store_records() def is_latest_holder_barcode(self, holder_barcode): return self._store.is_latest_holder_barcode(holder_barcode)
class RLibraryBrowser(QDialog): def __init__(self, parent=None, paths=None): QDialog.__init__(self, parent) QShortcut(QKeySequence("Escape"), self, self.reject) self.setWindowTitle("manageR - Library Browser") self.resize(500, 500) port = robjects.r('tools:::httpdPort')[0] if not port > 0: robjects.r('tools::startDynamicHelp()') port = robjects.r('tools:::httpdPort')[0] robjects.r("""make.packages.html()""") host = "localhost" home = "/doc/html/packages.html" #splitter = QSplitter(self) #splitter.setOrientation(Qt.Vertical) #splitter.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) labels = QStringList(["Loaded", "Package", "Title", "Path"]) self.parent = parent self.home = home self.packageTable = QTableWidget(0, 4, self) self.htmlViewer = HtmlBrowser(self, host, port, home, paths) #splitter.addWidget(self.packageTable) #splitter.addWidget(self.htmlViewer) vbox = QVBoxLayout(self) #hbox.addWidget(splitter) vbox.addWidget(self.packageTable) vbox.addWidget(self.htmlViewer) self.packageTable.setHorizontalHeaderLabels(labels) self.packageTable.setShowGrid(True) self.packageTable.setSelectionBehavior(QAbstractItemView.SelectRows) self.packageTable.setSelectionMode(QAbstractItemView.SingleSelection) self.packageTable.setAlternatingRowColors(True) self.updatePackages() self.connect(self.packageTable, SIGNAL("itemChanged(QTableWidgetItem*)"), self.loadPackage) self.connect(self.packageTable, SIGNAL("itemDoubleClicked(QTableWidgetItem*)"), self.showPackage) def setSource(self, source): self.htmlViewer.setSource(source) def showPackage(self, item): row = item.row() tmp = self.packageTable.item(row, 1) package = tmp.text() home = QUrl(self.home) curr = QUrl("../../library/%s/html/00Index.html" % package) self.htmlViewer.setSource(home.resolved(curr)) def loadPackage(self, item): row = item.row() tmp = self.packageTable.item(row, 1) package = tmp.text() if item.checkState() == Qt.Checked: command = "library(%s)" % package else: command = "detach('package:%s')" % package robjects.r(command) #self.emit(SIGNAL(...(command) def updatePackages(self): library_ = robjects.r.get('library', mode='function') packages_ = robjects.r.get('.packages', mode='function') loaded = list(packages_()) packages = list(library_()[1]) length = len(packages) self.packageTable.clearContents() #self.table.setRowCount(length/3) packageList = [] for i in range(length/3): package = unicode(packages[i]) if not package in packageList: packageList.append(package) self.packageTable.setRowCount(len(packageList)) item = QTableWidgetItem("Loaded") item.setFlags( Qt.ItemIsUserCheckable|Qt.ItemIsEnabled|Qt.ItemIsSelectable) if package in loaded: item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) self.packageTable.setItem(i, 0, item) item = QTableWidgetItem(unicode(packages[i])) item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable) self.packageTable.setItem(i, 1, item) item = QTableWidgetItem(unicode(packages[i+(2*(length/3))])) item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable) self.packageTable.setItem(i, 2, item) item = QTableWidgetItem(unicode(packages[i+(length/3)])) item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsSelectable) self.packageTable.setItem(i, 3, item) self.packageTable.resizeColumnsToContents()
class BarcodeTable(QGroupBox): """ GUI component. Displays a list of barcodes for the currently selected puck. """ def __init__(self, options): super(BarcodeTable, self).__init__() self._barcodes = [] self._options = options self.setTitle("Barcodes") self._init_ui() def _init_ui(self): # Create record table - lists all the records in the store self._table = QTableWidget() # Create barcode table - lists all the barcodes in a record self._table = QtGui.QTableWidget() self._table.setFixedWidth(110) self._table.setFixedHeight(600) self._table.setColumnCount(1) self._table.setRowCount(10) self._table.setHorizontalHeaderLabels(['Barcode']) self._table.setColumnWidth(0, 100) # Clipboard button - copy the selected barcodes to the clipboard self._btn_clipboard = QtGui.QPushButton('Copy To Clipboard') self._btn_clipboard.setToolTip( 'Copy barcodes for the selected record to the clipboard') self._btn_clipboard.resize(self._btn_clipboard.sizeHint()) self._btn_clipboard.clicked.connect(self.copy_selected_to_clipboard) self._btn_clipboard.setEnabled(False) hbox = QHBoxLayout() hbox.setSpacing(10) hbox.addWidget(self._btn_clipboard) hbox.addStretch(1) vbox = QVBoxLayout() vbox.addWidget(self._table) vbox.addLayout(hbox) self.setLayout(vbox) def populate(self, barcodes): """ Called when a new row is selected on the record table. Displays all of the barcodes from the selected record in the barcode table. By default, valid barcodes are highlighted green, invalid barcodes are highlighted red, and empty slots are grey. """ num_slots = len(barcodes) self._table.clearContents() self._table.setRowCount(num_slots) for index, barcode in enumerate(barcodes): # Select appropriate background color if barcode == NOT_FOUND_SLOT_SYMBOL: color = self._options.col_bad() elif barcode == EMPTY_SLOT_SYMBOL: color = self._options.col_empty() else: color = self._options.col_ok() color.a = 192 # Set table item barcode = QtGui.QTableWidgetItem(barcode) barcode.setBackgroundColor(color.to_qt()) barcode.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self._table.setItem(index, 0, barcode) self._barcodes = barcodes[:] for i, barcode in enumerate(self._barcodes): if barcode in [NOT_FOUND_SLOT_SYMBOL, EMPTY_SLOT_SYMBOL]: self._barcodes[i] = "" self._update_button_state() def _update_button_state(self): if self._barcodes is None or len(self._barcodes) == 0: self._btn_clipboard.setEnabled(False) else: self._btn_clipboard.setEnabled(True) def copy_selected_to_clipboard(self): """ Called when the copy to clipboard button is pressed. Copies the list/s of barcodes for the currently selected records to the clipboard so that the user can paste it elsewhere. """ sep = os.linesep if self._barcodes: pyperclip.copy(sep.join(self._barcodes))
class BarcodeTable(QGroupBox): """ GUI component. Displays a list of barcodes for the currently selected puck. """ def __init__(self, options): super(BarcodeTable, self).__init__() self._barcodes = [] self._options = options self.setTitle("Barcodes") self._init_ui() def _init_ui(self): # Create record table - lists all the records in the store self._table = QTableWidget() # Create barcode table - lists all the barcodes in a record self._table = QtGui.QTableWidget() self._table.setFixedWidth(110) self._table.setFixedHeight(600) self._table.setColumnCount(1) self._table.setRowCount(10) self._table.setHorizontalHeaderLabels(['Barcode']) self._table.setColumnWidth(0, 100) # Clipboard button - copy the selected barcodes to the clipboard self._btn_clipboard = QtGui.QPushButton('Copy To Clipboard') self._btn_clipboard.setToolTip('Copy barcodes for the selected record to the clipboard') self._btn_clipboard.resize(self._btn_clipboard.sizeHint()) self._btn_clipboard.clicked.connect(self.copy_selected_to_clipboard) self._btn_clipboard.setEnabled(False) hbox = QHBoxLayout() hbox.setSpacing(10) hbox.addWidget(self._btn_clipboard) hbox.addStretch(1) vbox = QVBoxLayout() vbox.addWidget(self._table) vbox.addLayout(hbox) self.setLayout(vbox) def populate(self, barcodes): """ Called when a new row is selected on the record table. Displays all of the barcodes from the selected record in the barcode table. By default, valid barcodes are highlighted green, invalid barcodes are highlighted red, and empty slots are grey. """ num_slots = len(barcodes) self._table.clearContents() self._table.setRowCount(num_slots) for index, barcode in enumerate(barcodes): # Select appropriate background color if barcode == NOT_FOUND_SLOT_SYMBOL: color = self._options.col_bad() elif barcode == EMPTY_SLOT_SYMBOL: color = self._options.col_empty() else: color = self._options.col_ok() color.a = 192 # Set table item barcode = QtGui.QTableWidgetItem(barcode) barcode.setBackgroundColor(color.to_qt()) barcode.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self._table.setItem(index, 0, barcode) self._barcodes = barcodes[:] for i, barcode in enumerate(self._barcodes): if barcode in [NOT_FOUND_SLOT_SYMBOL, EMPTY_SLOT_SYMBOL]: self._barcodes[i] = "" self._update_button_state() def _update_button_state(self): if self._barcodes is None or len(self._barcodes) == 0: self._btn_clipboard.setEnabled(False) else: self._btn_clipboard.setEnabled(True) def copy_selected_to_clipboard(self): """ Called when the copy to clipboard button is pressed. Copies the list/s of barcodes for the currently selected records to the clipboard so that the user can paste it elsewhere. """ sep = os.linesep if self._barcodes: pyperclip.copy(sep.join(self._barcodes))
class Main(plugin.Plugin): " Main Class " def initialize(self, *args, **kwargs): " Init Main Class " super(Main, self).initialize(*args, **kwargs) self.scriptPath, self.scriptArgs = "", [] self.profilerPath, self.tempPath = profilerPath, tempPath self.output = " ERROR: FAIL: No output ! " self.process = QProcess() self.process.finished.connect(self.on_process_finished) self.process.error.connect(self.on_process_error) self.tabWidget, self.stat = QTabWidget(), QWidget() self.tabWidget.tabCloseRequested.connect(lambda: self.tabWidget.setTabPosition(1) if self.tabWidget.tabPosition() == 0 else self.tabWidget.setTabPosition(0)) self.tabWidget.setStyleSheet('QTabBar{font-weight:bold;}') self.tabWidget.setMovable(True) self.tabWidget.setTabsClosable(True) self.vboxlayout1 = QVBoxLayout(self.stat) self.hboxlayout1 = QHBoxLayout() self.filterTableLabel = QLabel("<b>Type to Search : </b>", self.stat) self.hboxlayout1.addWidget(self.filterTableLabel) self.filterTableLineEdit = QLineEdit(self.stat) self.filterTableLineEdit.setPlaceholderText(' Type to Search . . . ') self.hboxlayout1.addWidget(self.filterTableLineEdit) self.filterHintTableLabel = QLabel(" ? ", self.stat) self.hboxlayout1.addWidget(self.filterHintTableLabel) self.vboxlayout1.addLayout(self.hboxlayout1) self.tableWidget = QTableWidget(self.stat) self.tableWidget.setAlternatingRowColors(True) self.tableWidget.setColumnCount(8) self.tableWidget.setRowCount(2) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(0, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(1, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(2, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(3, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(4, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(5, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(6, item) item = QTableWidgetItem() self.tableWidget.setHorizontalHeaderItem(7, item) self.tableWidget.itemDoubleClicked.connect( self.on_tableWidget_itemDoubleClicked) self.vboxlayout1.addWidget(self.tableWidget) self.tabWidget.addTab(self.stat, " ? ") self.source = QWidget() self.gridlayout = QGridLayout(self.source) self.scintillaWarningLabel = QLabel( "QScintilla is not installed!. Falling back to basic text edit!.", self.source) self.gridlayout.addWidget(self.scintillaWarningLabel, 1, 0, 1, 2) self.sourceTreeWidget = QTreeWidget(self.source) self.sourceTreeWidget.setAlternatingRowColors(True) self.sourceTreeWidget.itemActivated.connect( self.on_sourceTreeWidget_itemActivated) self.sourceTreeWidget.itemClicked.connect( self.on_sourceTreeWidget_itemClicked) self.sourceTreeWidget.itemDoubleClicked.connect( self.on_sourceTreeWidget_itemClicked) self.gridlayout.addWidget(self.sourceTreeWidget, 0, 0, 1, 1) self.sourceTextEdit = QTextEdit(self.source) self.sourceTextEdit.setReadOnly(True) self.gridlayout.addWidget(self.sourceTextEdit, 0, 1, 1, 1) self.tabWidget.addTab(self.source, " ? ") self.result = QWidget() self.vlayout = QVBoxLayout(self.result) self.globalStatGroupBox = QGroupBox(self.result) self.hboxlayout = QHBoxLayout(self.globalStatGroupBox) self.totalTimeLcdNumber = QLCDNumber(self.globalStatGroupBox) self.totalTimeLcdNumber.setSegmentStyle(QLCDNumber.Filled) self.totalTimeLcdNumber.setNumDigits(7) self.totalTimeLcdNumber.display(1000000) self.totalTimeLcdNumber.setFrameShape(QFrame.StyledPanel) self.totalTimeLcdNumber.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.hboxlayout.addWidget(self.totalTimeLcdNumber) self.tTimeLabel = QLabel("<b>Total Time (Sec)</b>", self.globalStatGroupBox) self.tTimeLabel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.hboxlayout.addWidget(self.tTimeLabel) self.numCallLcdNumber = QLCDNumber(self.globalStatGroupBox) self.numCallLcdNumber.setNumDigits(7) self.numCallLcdNumber.display(1000000) self.numCallLcdNumber.setSegmentStyle(QLCDNumber.Filled) self.numCallLcdNumber.setFrameShape(QFrame.StyledPanel) self.numCallLcdNumber.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.hboxlayout.addWidget(self.numCallLcdNumber) self.numCallLabel = QLabel("<b>Number of calls</b>", self.globalStatGroupBox) self.numCallLabel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.hboxlayout.addWidget(self.numCallLabel) self.primCallLcdNumber = QLCDNumber(self.globalStatGroupBox) self.primCallLcdNumber.setSegmentStyle(QLCDNumber.Filled) self.primCallLcdNumber.setFrameShape(QFrame.StyledPanel) self.primCallLcdNumber.setNumDigits(7) self.primCallLcdNumber.display(1000000) self.primCallLcdNumber.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.hboxlayout.addWidget(self.primCallLcdNumber) self.primCallLabel = QLabel("<b>Primitive calls (%)</b>", self.globalStatGroupBox) self.primCallLabel.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.hboxlayout.addWidget(self.primCallLabel) self.vlayout.addWidget(self.globalStatGroupBox) try: from PyKDE4.kdeui import KRatingWidget self.rating = KRatingWidget(self.globalStatGroupBox) self.rating.setToolTip('Profiling Performance Rating') except ImportError: pass self.tabWidget.addTab(self.result, " Get Results ! ") self.resgraph = QWidget() self.vlayout2 = QVBoxLayout(self.result) self.graphz = QGroupBox(self.resgraph) self.hboxlayout2 = QHBoxLayout(self.graphz) try: from PyKDE4.kdeui import KLed KLed(self.graphz) except ImportError: pass self.hboxlayout2.addWidget(QLabel(''' Work in Progress :) Not Ready Yet''')) self.vlayout2.addWidget(self.graphz) self.tabWidget.addTab(self.resgraph, " Graphs and Charts ") self.pathz = QWidget() self.vlayout3 = QVBoxLayout(self.pathz) self.patz = QGroupBox(self.pathz) self.hboxlayout3 = QVBoxLayout(self.patz) self.profilepath = QLineEdit(profilerPath) self.getprofile = QPushButton(QIcon.fromTheme("document-open"), 'Open') self.getprofile.setToolTip('Dont touch if you dont know what are doing') self.getprofile.clicked.connect(lambda: self.profilepath.setText(str( QFileDialog.getOpenFileName(self.patz, ' Open the profile.py file ', path.expanduser("~"), ';;(profile.py)')))) self.hboxlayout3.addWidget(QLabel( '<center><b>Profile.py Python Library Full Path:</b></center>')) self.hboxlayout3.addWidget(self.profilepath) self.hboxlayout3.addWidget(self.getprofile) self.argGroupBox = QGroupBox(self.pathz) self.hbxlayout = QHBoxLayout(self.argGroupBox) self.argLineEdit = QLineEdit(self.argGroupBox) self.argLineEdit.setToolTip('Not touch if you dont know what are doing') self.argLineEdit.setPlaceholderText( 'Dont touch if you dont know what are doing') self.hbxlayout.addWidget(QLabel('<b>Additional Profile Arguments:</b>')) self.hbxlayout.addWidget(self.argLineEdit) self.hboxlayout3.addWidget(self.argGroupBox) self.vlayout3.addWidget(self.patz) self.tabWidget.addTab(self.pathz, " Paths and Configs ") self.outp = QWidget() self.vlayout4 = QVBoxLayout(self.outp) self.outgro = QGroupBox(self.outp) self.outgro.setTitle(" MultiProcessing Output Logs ") self.hboxlayout4 = QVBoxLayout(self.outgro) self.outputlog = QTextEdit() self.outputlog.setText(''' I do not fear computers, I fear the lack of them. -Isaac Asimov ''') self.hboxlayout4.addWidget(self.outputlog) self.vlayout4.addWidget(self.outgro) self.tabWidget.addTab(self.outp, " Logs ") self.actionNew_profiling = QAction(QIcon.fromTheme("document-new"), 'New Profiling', self) self.actionLoad_profile = QAction(QIcon.fromTheme("document-open"), 'Open Profiling', self) self.actionClean = QAction(QIcon.fromTheme("edit-clear"), 'Clean', self) self.actionClean.triggered.connect(lambda: self.clearContent) self.actionAbout = QAction(QIcon.fromTheme("help-about"), 'About', self) self.actionAbout.triggered.connect(lambda: QMessageBox.about(self.dock, __doc__, ', '.join((__doc__, __license__, __author__, __email__)))) self.actionSave_profile = QAction(QIcon.fromTheme("document-save"), 'Save Profiling', self) self.actionManual = QAction(QIcon.fromTheme("help-contents"), 'Help', self) self.actionManual.triggered.connect(lambda: open_new_tab('http://docs.python.org/library/profile.html')) self.tabWidget.setCurrentIndex(2) self.globalStatGroupBox.setTitle("Global Statistics") item = self.tableWidget.horizontalHeaderItem(0) item.setText("Number of Calls") item = self.tableWidget.horizontalHeaderItem(1) item.setText("Total Time") item = self.tableWidget.horizontalHeaderItem(2) item.setText("Per Call") item = self.tableWidget.horizontalHeaderItem(3) item.setText("Cumulative Time") item = self.tableWidget.horizontalHeaderItem(4) item.setText("Per Call") item = self.tableWidget.horizontalHeaderItem(5) item.setText("Filename") item = self.tableWidget.horizontalHeaderItem(6) item.setText("Line") item = self.tableWidget.horizontalHeaderItem(7) item.setText("Function") self.tabWidget.setTabText(self.tabWidget.indexOf(self.stat), "Statistics per Function") self.sourceTreeWidget.headerItem().setText(0, "Source files") self.tabWidget.setTabText(self.tabWidget.indexOf(self.source), "Sources Navigator") ####################################################################### self.scrollable, self.dock = QScrollArea(), QDockWidget() self.scrollable.setWidgetResizable(True) self.scrollable.setWidget(self.tabWidget) self.dock.setWindowTitle(__doc__) self.dock.setStyleSheet('QDockWidget::title{text-align: center;}') self.dock.setWidget(self.scrollable) QToolBar(self.dock).addActions((self.actionNew_profiling, self.actionClean, self.actionSave_profile, self.actionLoad_profile, self.actionManual, self.actionAbout)) self.actionNew_profiling.triggered.connect( self.on_actionNew_profiling_triggered) self.actionLoad_profile.triggered.connect( self.on_actionLoad_profile_triggered) self.actionSave_profile.triggered.connect( self.on_actionSave_profile_triggered) self.locator.get_service('misc').add_widget(self.dock, QIcon.fromTheme("document-open-recent"), __doc__) if QSCI: # Scintilla source editor management self.scintillaWarningLabel.setText(' QScintilla is Ready ! ') layout = self.source.layout() layout.removeWidget(self.sourceTextEdit) self.sourceTextEdit = Qsci.QsciScintilla(self.source) layout.addWidget(self.sourceTextEdit, 0, 1) doc = self.sourceTextEdit doc.setLexer(Qsci.QsciLexerPython(self.sourceTextEdit)) doc.setReadOnly(True) doc.setEdgeMode(Qsci.QsciScintilla.EdgeLine) doc.setEdgeColumn(80) doc.setEdgeColor(QColor("#FF0000")) doc.setFolding(Qsci.QsciScintilla.BoxedTreeFoldStyle) doc.setBraceMatching(Qsci.QsciScintilla.SloppyBraceMatch) doc.setCaretLineVisible(True) doc.setMarginLineNumbers(1, True) doc.setMarginWidth(1, 25) doc.setTabWidth(4) doc.setEolMode(Qsci.QsciScintilla.EolUnix) self.marker = {} for color in COLORS: mnr = doc.markerDefine(Qsci.QsciScintilla.Background) doc.setMarkerBackgroundColor(color, mnr) self.marker[color] = mnr self.currentSourcePath = None # Connect table and tree filter edit signal to unique slot self.filterTableLineEdit.textEdited.connect( self.on_filterLineEdit_textEdited) # Timer to display filter hint message self.filterHintTimer = QTimer(self) self.filterHintTimer.setSingleShot(True) self.filterHintTimer.timeout.connect(self.on_filterHintTimer_timeout) # Timer to start search self.filterSearchTimer = QTimer(self) self.filterSearchTimer.setSingleShot(True) self.filterSearchTimer.timeout.connect( self.on_filterSearchTimer_timeout) self.tabLoaded = {} for i in range(10): self.tabLoaded[i] = False self.backgroundTreeMatchedItems = {} self.resizeWidgetToContent(self.tableWidget) def on_actionNew_profiling_triggered(self): self.clearContent() self.scriptPath = str(QFileDialog.getOpenFileName(self.dock, "Choose your script to profile", path.expanduser("~"), "Python (*.py *.pyw)")) commandLine = [self.profilerPath, "-o", self.tempPath, self.scriptPath] + self.scriptArgs commandLine = " ".join(commandLine) ##if self.termCheckBox.checkState() == Qt.Checked: #termList = ["xterm", "aterm"] #for term in termList: #termPath = which(term) #if termPath: #break #commandLine = """%s -e "%s ; echo 'Press ENTER Exit' ; read" """ \ #% (termPath, commandLine) self.process.start(commandLine) if not self.process.waitForStarted(): print((" ERROR: {} failed!".format(commandLine))) return def on_process_finished(self, exitStatus): ' whan the process end ' print((" INFO: OK: QProcess is %s" % self.process.exitCode())) self.output = self.process.readAll().data() if not self.output: self.output = " ERROR: FAIL: No output ! " self.outputlog.setText(self.output + str(self.process.exitCode())) if path.exists(self.tempPath): self.setStat(self.tempPath) remove(self.tempPath) else: self.outputlog.setText(" ERROR: QProcess FAIL: Profiling failed.") self.tabWidget.setCurrentIndex(2) def on_process_error(self, error): ' when the process fail, I hope you never see this ' print(" ERROR: QProcess FAIL: Profiler Dead, wheres your God now ? ") if error == QProcess.FailedToStart: self.outputlog.setText(" ERROR: FAIL: Profiler execution failed ") elif error == QProcess.Crashed: self.outputlog.setText(" ERROR: FAIL: Profiler execution crashed ") else: self.outputlog.setText(" ERROR: FAIL: Profiler unknown error ") def on_actionLoad_profile_triggered(self): """Load a previous profile sessions""" statPath = str(QFileDialog.getOpenFileName(self.dock, "Open profile dump", path.expanduser("~"), "Profile file (*)")) if statPath: self.clearContent() print(' INFO: OK: Loading profiling from ' + statPath) self.setStat(statPath) def on_actionSave_profile_triggered(self): """Save a profile sessions""" statPath = str(QFileDialog.getSaveFileName(self.dock, "Save profile dump", path.expanduser("~"), "Profile file (*)")) if statPath: #TODO: handle error case and give feelback to user print(' INFO: OK: Saving profiling to ' + statPath) self.stat.save(statPath) #=======================================================================# # Common parts # #=======================================================================# def on_tabWidget_currentChanged(self, index): """slot for tab change""" # Kill search and hint timer if running to avoid cross effect for timer in (self.filterHintTimer, self.filterSearchTimer): if timer.isActive(): timer.stop() if not self.stat: #No stat loaded, nothing to do return self.populateTable() self.populateSource() def on_filterLineEdit_textEdited(self, text): """slot for filter change (table or tree""" if self.filterSearchTimer.isActive(): # Already runnning, stop it self.filterSearchTimer.stop() # Start timer self.filterSearchTimer.start(300) def on_filterHintTimer_timeout(self): """Timeout to warn user about text length""" print("timeout") tab = self.tabWidget.currentIndex() if tab == TAB_FUNCTIONSTAT: label = self.filterHintTableLabel label.setText("Type > 2 characters to search") def on_filterSearchTimer_timeout(self): """timeout to start search""" tab = self.tabWidget.currentIndex() if tab == TAB_FUNCTIONSTAT: text = self.filterTableLineEdit.text() label = self.filterHintTableLabel edit = self.filterTableLineEdit widget = self.tableWidget else: print("Unknow tab for filterSearch timeout !") print(("do search for %s" % text)) if not len(text): # Empty keyword, just clean all if self.filterHintTimer.isActive(): self.filterHintTimer.stop() label.setText(" ? ") self.warnUSer(True, edit) self.clearSearch() return if len(text) < 2: # Don't filter if text is too short and tell it to user self.filterHintTimer.start(600) return else: if self.filterHintTimer.isActive(): self.filterHintTimer.stop() label.setText(" ? ") # Search self.clearSearch() matchedItems = [] if tab == TAB_FUNCTIONSTAT: # Find items matchedItems = widget.findItems(text, Qt.MatchContains) widget.setSortingEnabled(False) matchedRows = [item.row() for item in matchedItems] # Hide matched items header = widget.verticalHeader() for row in range(widget.rowCount()): if row not in matchedRows: header.hideSection(row) widget.setSortingEnabled(True) else: print(" Unknow tab for filterSearch timeout ! ") print(("got %s members" % len(matchedItems))) self.warnUSer(matchedItems, edit) self.resizeWidgetToContent(widget) def resizeWidgetToContent(self, widget): """Resize all columns according to content""" for i in range(widget.columnCount()): widget.resizeColumnToContents(i) def clearSearch(self): """Clean search result For table, show all items For tree, remove colored items""" tab = self.tabWidget.currentIndex() if tab == TAB_FUNCTIONSTAT: header = self.tableWidget.verticalHeader() if header.hiddenSectionCount(): for i in range(header.count()): if header.isSectionHidden(i): header.showSection(i) def clearContent(self): # Clear tabs self.tableWidget.clearContents() self.sourceTreeWidget.clear() # Reset LCD numbers for lcdNumber in (self.totalTimeLcdNumber, self.numCallLcdNumber, self.primCallLcdNumber): lcdNumber.display(1000000) # Reset stat self.pstat = None # Disable save as menu self.actionSave_profile.setEnabled(False) # Mark all tabs as unloaded for i in range(10): self.tabLoaded[i] = False def warnUSer(self, result, inputWidget): palette = inputWidget.palette() if result: palette.setColor(QPalette.Normal, QPalette.Base, QColor(255, 255, 255)) else: palette.setColor(QPalette.Normal, QPalette.Base, QColor(255, 136, 138)) inputWidget.setPalette(palette) inputWidget.update() def setStat(self, statPath): self.stat = Stat(path=statPath) # Global stat update self.totalTimeLcdNumber.display(self.stat.getTotalTime()) self.numCallLcdNumber.display(self.stat.getCallNumber()) self.primCallLcdNumber.display(self.stat.getPrimitiveCallRatio()) # Refresh current tab self.on_tabWidget_currentChanged(self.tabWidget.currentIndex()) # Activate save as menu self.actionSave_profile.setEnabled(True) try: self.rating.setMaxRating(10) self.rating.setRating( int(self.stat.getPrimitiveCallRatio()) / 10 - 1) except: pass #========================================================================# # Statistics table # #=======================================================================# def populateTable(self): row = 0 rowCount = self.stat.getStatNumber() progress = QProgressDialog("Populating statistics table...", "Abort", 0, 2 * rowCount) self.tableWidget.setSortingEnabled(False) self.tableWidget.setRowCount(rowCount) progress.setWindowModality(Qt.WindowModal) for (key, value) in self.stat.getStatItems(): #ncalls item = StatTableWidgetItem(str(value[0])) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_NCALLS, item) colorTableItem(item, self.stat.getCallNumber(), value[0]) #total time item = StatTableWidgetItem(str(value[2])) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_TTIME, item) colorTableItem(item, self.stat.getTotalTime(), value[2]) #per call (total time) if value[0] != 0: tPerCall = str(value[2] / value[0]) cPerCall = str(value[3] / value[0]) else: tPerCall = "" cPerCall = "" item = StatTableWidgetItem(tPerCall) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_TPERCALL, item) colorTableItem(item, 100.0 * self.stat.getTotalTime() / self.stat.getCallNumber(), tPerCall) #per call (cumulative time) item = StatTableWidgetItem(cPerCall) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_CPERCALL, item) colorTableItem(item, 100.0 * self.stat.getTotalTime() / self.stat.getCallNumber(), cPerCall) #cumulative time item = StatTableWidgetItem(str(value[3])) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_CTIME, item) colorTableItem(item, self.stat.getTotalTime(), value[3]) #Filename self.tableWidget.setItem(row, STAT_FILENAME, StatTableWidgetItem(str(key[0]))) #Line item = StatTableWidgetItem(str(key[1])) item.setTextAlignment(Qt.AlignRight) self.tableWidget.setItem(row, STAT_LINE, item) #Function name self.tableWidget.setItem(row, STAT_FUNCTION, StatTableWidgetItem(str(key[2]))) row += 1 # Store it in stat hash array self.stat.setStatLink(item, key, TAB_FUNCTIONSTAT) progress.setValue(row) if progress.wasCanceled(): return for i in range(self.tableWidget.rowCount()): progress.setValue(row + i) for j in range(self.tableWidget.columnCount()): item = self.tableWidget.item(i, j) if item: item.setFlags(Qt.ItemIsEnabled) self.tableWidget.setSortingEnabled(True) self.resizeWidgetToContent(self.tableWidget) progress.setValue(2 * rowCount) def on_tableWidget_itemDoubleClicked(self, item): matchedItems = [] filename = str(self.tableWidget.item(item.row(), STAT_FILENAME).text()) if not filename or filename.startswith("<"): # No source code associated, return immediatly return function = self.tableWidget.item(item.row(), STAT_FUNCTION).text() line = self.tableWidget.item(item.row(), STAT_LINE).text() self.on_tabWidget_currentChanged(TAB_SOURCE) # load source tab function = "%s (%s)" % (function, line) fathers = self.sourceTreeWidget.findItems(filename, Qt.MatchContains, SOURCE_FILENAME) print(("find %s father" % len(fathers))) for father in fathers: findItems(father, function, SOURCE_FILENAME, matchedItems) print(("find %s items" % len(matchedItems))) if matchedItems: self.tabWidget.setCurrentIndex(TAB_SOURCE) self.sourceTreeWidget.scrollToItem(matchedItems[0]) self.on_sourceTreeWidget_itemClicked(matchedItems[0], SOURCE_FILENAME) matchedItems[0].setSelected(True) else: print("oups, item found but cannot scroll to it !") #=======================================================================# # Source explorer # #=====================================================================# def populateSource(self): items = {} for stat in self.stat.getStatKeys(): source = stat[0] function = "%s (%s)" % (stat[2], stat[1]) if source in ("", "profile") or source.startswith("<"): continue # Create the function child child = QTreeWidgetItem([function]) # Store it in stat hash array self.stat.setStatLink(child, stat, TAB_SOURCE) if source in items: father = items[source] else: # Create the father father = QTreeWidgetItem([source]) items[source] = father father.addChild(child) self.sourceTreeWidget.setSortingEnabled(False) for value in list(items.values()): self.sourceTreeWidget.addTopLevelItem(value) self.sourceTreeWidget.setSortingEnabled(True) def on_sourceTreeWidget_itemActivated(self, item, column): self.on_sourceTreeWidget_itemClicked(item, column) def on_sourceTreeWidget_itemClicked(self, item, column): line = 0 parent = item.parent() if QSCI: doc = self.sourceTextEdit if parent: pathz = parent.text(column) result = match("(.*) \(([0-9]+)\)", item.text(column)) if result: try: function = str(result.group(1)) line = int(result.group(2)) except ValueError: # We got garbage... falling back to line 0 pass else: pathz = item.text(column) pathz = path.abspath(str(pathz)) if self.currentSourcePath != pathz: # Need to load source self.currentSourcePath == pathz try: if QSCI: doc.clear() doc.insert(file(pathz).read()) else: self.sourceTextEdit.setPlainText(file(pathz).read()) except IOError: QMessageBox.warning(self, "Error", "Source file could not be found", QMessageBox.Ok) return if QSCI: for function, line in [(i[2], i[1] ) for i in self.stat.getStatKeys() if i[0] == pathz]: # expr, regexp, case sensitive, whole word, wrap, forward doc.findFirst("def", False, True, True, False, True, line, 0, True) end, foo = doc.getCursorPosition() time = self.stat.getStatTotalTime((pathz, line, function)) colorSource(doc, self.stat.getTotalTime(), time, line, end, self.marker) if QSCI: doc.ensureLineVisible(line)
class SentenceFillDlg(QDialog, ui_sentencefilldlg.Ui_SentenceFillDlg): def __init__(self, tableName, rangeValues, parent=None): super(SentenceFillDlg, self).__init__(parent) self.tableName = tableName self.rangeValues = rangeValues self.setupUi(self) self.initUI() def initUI(self): fontLabel = QFont('SansSerif', 14) self.setMinimumSize(1200, 600) self.resize(1200, 600) self.sentenceToFillTable = QTableWidget(5, 1, self) self.sentenceToFillTable.setGeometry(QRect(70, 60, 800, 400)) self.sentenceToFillTable.setColumnCount(1) item = QTableWidgetItem() item.setText('Sentences To Match') font = QFont() font.setBold(True) font.setWeight(75) item.setFont(font) self.sentenceToFillTable.setHorizontalHeaderItem(0, item) self.sentenceToFillTable.resizeColumnsToContents() self.sentenceToFillTable.horizontalHeader().setStretchLastSection(True) self.sentenceToFillTable.verticalHeader().setStretchLastSection(True) self.sentenceList = [] self.getSentencesFromDatabase() # split the sentences into chunks of 5 # Map to hold the anwers self.rightWordList = {} self.iteration = 0 self.sentenceMasterList = [] self.sentenceSlaveList = [] if len(self.sentenceList) > 0: for sentence in self.sentenceList: if len(self.sentenceSlaveList) < 5: self.sentenceSlaveList.append(sentence) else: self.sentenceMasterList.append(self.sentenceSlaveList) self.sentenceSlaveList = [] self.sentenceSlaveList.append(sentence) if len(self.sentenceSlaveList) <= 5: self.sentenceMasterList.append(self.sentenceSlaveList) self.maxIteration = len(self.sentenceMasterList) ## set the row height self.tableHeightSize = 0 ## Only if there is atleast one sentence fetched from the database if len(self.sentenceList) > 0: for index in range(0, 5): if len(self.sentenceList[index]) < 150: self.sentenceToFillTable.verticalHeader().resizeSection(index, 80) self.tableHeightSize = self.tableHeightSize + 90 elif len(self.sentenceList[index]) < 200: self.sentenceToFillTable.verticalHeader().resizeSection(index, 100) self.tableHeightSize = self.tableHeightSize + 100 else: self.sentenceToFillTable.verticalHeader().resizeSection(index, 120) self.tableHeightSize = self.tableHeightSize + 120 # split words from databse into chunks of 5 self.refIteration = 0 self.refWordMasterList = [] self.refWordSlaveList = [] for wordList in self.wordMap.values(): if len(self.refWordSlaveList) < 5: self.refWordSlaveList.append(wordList) else: self.refWordMasterList.append(self.refWordSlaveList) self.refWordSlaveList = [] self.refWordSlaveList.append(wordList) if len(self.refWordSlaveList) <= 5: self.refWordMasterList.append(self.refWordSlaveList) self.refMaxIteration = len(self.refWordMasterList) self.insertSentencesInTable() self.connect(self.sentenceToFillTable, SIGNAL("cellClicked(int, int)"), self.itemSelect) # create next, submit and close buttons self.nextButton = QPushButton('Next', self) self.nextButton.move(170, 520) self.nextButton.setEnabled(False) self.submitButton = QPushButton('Submit', self) self.submitButton.move(380, 520) self.closeButton = QPushButton('Close', self) self.closeButton.move(600, 520) self.connect(self.closeButton, SIGNAL('clicked()'), self.closeClicked) self.connect(self.submitButton, SIGNAL('clicked()'), self.onSubmitClicked) self.connect(self.nextButton, SIGNAL('clicked()'), self.onNextClicked) self.setWindowTitle('Sentence Fill') #self.setGeometry(10, 80, 1100, 750) def getSentencesFromDatabase(self): self.twoTypeList = data.Data().getSentencesFromDatabase(self.tableName, self.rangeValues) if len(self.twoTypeList) == 2: self.sentenceList = self.twoTypeList[0] self.wordMap = self.twoTypeList[1] def closeClicked(self): reply = QMessageBox.question(self, "Fill the Sentences", "You want to close the application", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: self.reject() def onNextClicked(self): if not self.iteration < self.maxIteration: QMessageBox.information(self, "Fill the Sentences", "All Sentences are matched", QMessageBox.Ok) else: self.sentenceToFillTable.clearContents() ## Fetch the next records self.refIteration = self.refIteration + 1 self.rightWordList = {} ## clear the contents of the combo box self.wordListComboBox.clear() self.insertSentencesInTable() # validate whether the user has matched the blanks with a value during next and submit button clicks def onNextSubmitValidation(self): self.textNotFilled = False for row in range(0, len(self.currentSentenceListInTable)): if self.sentenceToFillTable.item(row, 0).text() == self.currentSentenceListInTable[row]: self.textNotFilled = True if self.textNotFilled: QMessageBox.information(self, "Fill the sentences", "Match all the sentences in the table", QMessageBox.Ok) self.nextButton.setEnabled(False) def onSubmitClicked(self): self.wordsMatched = True self.allWordsMatched = True brushRed = QBrush(QColor(255,0,0)) brushRed.setStyle(Qt.SolidPattern) brushGreen = QBrush(QColor(0,255,0)) brushGreen.setStyle(Qt.SolidPattern) # validate whether the user all matched the blanks with a value #self.onNextSubmitValidation() textNotFilled = False for row in range(0, len(self.currentSentenceListInTable)): if self.sentenceToFillTable.item(row, 0).text() == self.currentSentenceListInTable[row]: textNotFilled = True if textNotFilled: QMessageBox.information(self, "Fill the sentences", "Match all the sentences in the table", QMessageBox.Ok) else: splittedSentence = [] foundWordInSentence = "" self.rightWordListCopy = self.rightWordList for row in range(0, len(self.currentSentenceListInTable)): sentenceFilled = str(self.sentenceToFillTable.item(row, 0).text()) newSplittedSentence = [word.strip() for word in sentenceFilled.split()] splittedSentence = [] for word in newSplittedSentence: match = re.search(r'\w+', word) if match: splittedSentence.append(str(match.group())) wordList = self.rightWordListCopy[row] if len(wordList) > 1: firstWord = wordList[0].strip() secondWord = wordList[1].strip() if ' ' in firstWord: for word in firstWord.split(): if word not in splittedSentence: self.wordsMatched = False else: if firstWord not in splittedSentence: self.wordsMatched = False if self.wordsMatched: ## check is valid only if the first word is matched if ' ' in secondWord: for word in secondWord.split(): if word not in splittedSentence: self.wordsMatched = False else: if secondWord not in splittedSentence: self.wordsMatched = False elif len(wordList) == 1: word = wordList[0].strip() if word not in splittedSentence: self.wordsMatched = False if self.wordsMatched: self.sentenceToFillTable.item(row, 0).setBackground(brushGreen) else: self.sentenceToFillTable.item(row, 0).setBackground(brushRed) self.allWordsMatched = False self.wordsMatched = True if self.allWordsMatched: self.nextButton.setEnabled(True) QMessageBox.information(self, "Fill the sentences", "All sentences are matched", QMessageBox.Ok) def insertSentencesInTable(self): if self.iteration < self.maxIteration: cellList = [] self.col = 0 self.currentSentenceListInTable = self.sentenceMasterList[self.iteration] for sentence in self.currentSentenceListInTable: item = QTableWidgetItem(QString(sentence)) item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)) cellList.append(item) cellList.reverse() for index in range(0, len(self.currentSentenceListInTable)): self.sentenceToFillTable.setItem(index, self.col, cellList.pop()) self.sentenceToFillTable.setRowCount(len(self.sentenceMasterList[self.iteration])) self.sentenceToFillTable.setFixedHeight(self.tableHeightSize) # increment the count for the next button click self.iteration = self.iteration + 1 def createComboBox(self, rowIndex): self.xAxis = 1000 self.yAxis = 80 if self.refIteration < self.refMaxIteration: wordListWithFiveArrays = self.refWordMasterList[self.refIteration] requiredWordList = wordListWithFiveArrays[rowIndex] ## Create a combo box self.wordListComboBox = QComboBox(self) self.wordListComboBox.setGeometry(900, 80, 100, 20) self.connect(self.wordListComboBox, SIGNAL("currentIndexChanged(int)"), self.wordSelected) self.wordListComboBox.show() ## save the right word if len(requiredWordList) > 0: if rowIndex not in self.rightWordList.keys(): if len(requiredWordList) > 0: wordList = requiredWordList[0].split('&') self.rightWordList[rowIndex] = wordList ## insert words in the combo box random.shuffle(requiredWordList) random.shuffle(requiredWordList) self.wordListComboBox.addItem(' ') self.wordListComboBox.addItems(requiredWordList) def wordSelected(self): ## Avoid the blank option if len(str(self.wordListComboBox.currentText()).strip()) > 0: sentence = self.currentSentenceListInTable[self.selectedSentenceIndex] splittedText = sentence.split('-') if len(splittedText) == 2: item = QTableWidgetItem(QString(splittedText[0] + str(self.wordListComboBox.currentText()) + ' ' + splittedText[1].strip())) item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)) self.sentenceToFillTable.setItem(self.selectedSentenceIndex, 0, item) elif len(splittedText) > 2: wordsFromCombobox = str(self.wordListComboBox.currentText()).split('&') item = QTableWidgetItem(QString(splittedText[0] + wordsFromCombobox[0] + splittedText[1] + wordsFromCombobox[1] + ' ' + splittedText[2].strip())) item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)) self.sentenceToFillTable.setItem(self.selectedSentenceIndex, 0, item) def createIndexForWords(self): self.indexForWords = {} self.nextIndex = 0 for word in self.refWordListForIndex: if self.nextIndex == 5: break self.indexForWords[word] = self.nextIndex self.nextIndex = self.nextIndex + 1 def itemSelect(self,rowIndex): self.createComboBox(rowIndex) self.selectedSentenceIndex = rowIndex
class LabelAssistDialog(QDialog): """ A simple UI for showing bookmarks and navigating to them. FIXME: For now, this window is tied to a particular lane. If your project has more than one lane, then each one will have it's own bookmark window, which is kinda dumb. """ def __init__(self, parent, topLevelOperatorView): super(LabelAssistDialog, self).__init__(parent) # Create thread router to populate table on main thread self.threadRouter = ThreadRouter(self) # Set object classification operator view self.topLevelOperatorView = topLevelOperatorView self.setWindowTitle("Label Assist") self.setMinimumWidth(500) self.setMinimumHeight(700) layout = QGridLayout() layout.setContentsMargins(10, 10, 10, 10) # Show variable importance table rows = 0 columns = 4 self.table = QTableWidget(rows, columns) self.table.setHorizontalHeaderLabels( ['Frame', 'Max Area', 'Min Area', 'Labels']) self.table.verticalHeader().setVisible(False) # Select full row on-click and call capture double click self.table.setSelectionBehavior(QTableView.SelectRows) self.table.doubleClicked.connect(self._captureDoubleClick) layout.addWidget(self.table, 1, 0, 3, 2) # Create progress bar self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(0) self.progressBar.hide() layout.addWidget(self.progressBar, 4, 0, 1, 2) # Create button to populate table self.computeButton = QPushButton('Compute object info') self.computeButton.clicked.connect(self._triggerTableUpdate) layout.addWidget(self.computeButton, 5, 0) # Create close button closeButton = QPushButton('Close') closeButton.clicked.connect(self.close) layout.addWidget(closeButton, 5, 1) # Set dialog layout self.setLayout(layout) def _triggerTableUpdate(self): # Check that object area is included in selected features featureNames = self.topLevelOperatorView.SelectedFeatures.value if 'Standard Object Features' not in featureNames or 'Count' not in featureNames[ 'Standard Object Features']: box = QMessageBox( QMessageBox.Warning, 'Warning', 'Object area is not a selected feature. Please select this feature on: \"Standard Object Features > Shape > Size in pixels\"', QMessageBox.NoButton, self) box.show() return # Clear table self.table.clearContents() self.table.setRowCount(0) self.table.setSortingEnabled(False) self.progressBar.show() self.computeButton.setEnabled(False) # Compute object features and number of labels per frame def compute_features(): features = self.topLevelOperatorView.ObjectFeatures([]).wait() labels = self.topLevelOperatorView.LabelInputs([]).wait() return features, labels req = Request(compute_features) req.notify_finished(self._populateTable) req.submit() @threadRouted def _populateTable(self, features_and_labels): features, labels = features_and_labels self.progressBar.hide() self.computeButton.setEnabled(True) for frame, objectFeatures in features.iteritems(): # Insert row rowNum = self.table.rowCount() self.table.insertRow(self.table.rowCount()) # Get max and min object areas areas = objectFeatures['Standard Object Features']['Count'] maxObjArea = numpy.max(areas[numpy.nonzero(areas)]) minObjArea = numpy.min(areas[numpy.nonzero(areas)]) # Get number of labeled objects labelNum = numpy.count_nonzero(labels[frame]) # Load fram number item = QTableWidgetItem(str(frame)) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.table.setItem(rowNum, 0, item) # Load max object areas item = QTableWidgetItemWithFloatSorting( str("{: .02f}".format(maxObjArea))) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.table.setItem(rowNum, 1, item) # Load min object areas item = QTableWidgetItemWithFloatSorting( str("{: .02f}".format(minObjArea))) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.table.setItem(rowNum, 2, item) # Load label numbers item = QTableWidgetItemWithFloatSorting( str("{: .01f}".format(labelNum))) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.table.setItem(rowNum, 3, item) # Resize column size to fit dialog size self.table.horizontalHeader().setResizeMode(QHeaderView.Stretch) # Sort by max object area self.table.setSortingEnabled(True) self.table.sortByColumn(1) def _captureDoubleClick(self): # Navigate to selected frame index = self.table.selectedIndexes()[0] frameStr = self.table.model().data(index).toString() if frameStr: frameNum = int(frameStr) self.parent().editor.posModel.time = frameNum
class RemoveSentencesDlg(QDialog): def __init__(self): super(RemoveSentencesDlg, self).__init__() self.removeList = {} self.initUI() def initUI(self): ## create a font type for the label fontLabel = QFont('SansSerif', 14) ## create a label self.label = QLabel(self) self.label.setAutoFillBackground(True) self.label.setAlignment(Qt.AlignCenter) self.label.setGeometry(QRect(200, 10, 400, 40)) self.label.setFont(fontLabel) ## set the text for the Label self.label.setText('Remove the Sentences') ## Create a Table to hold all the sentences self.sentenceTable = QTableWidget(self) ## set the size and the position of the table self.sentenceTable.setGeometry(QRect(10, 60, 800, 400)) ## set the column count for the table self.sentenceTable.setColumnCount(1) sentenceHeaderList = ['Sentences From Table'] self.sentenceTable.setHorizontalHeaderLabels(sentenceHeaderList) self.sentenceTable.resizeColumnsToContents() self.sentenceTable.horizontalHeader().setStretchLastSection(True) self.sentenceTable.verticalHeader().setStretchLastSection(True) # Create a Remove button self.removeButton = QPushButton('Remove', self) self.removeButton.move(350, 600) # Create a close button self.closeButton = QPushButton('Close', self) self.closeButton.move(450, 600) ## Create signal for the remove button self.connect(self.removeButton, SIGNAL("clicked()"), self.onRemoveClicked) ## Create signal for the close button self.connect(self.closeButton, SIGNAL("clicked()"), self.closeClicked) ## Create signal for the sentence table self.connect(self.sentenceTable, SIGNAL('cellClicked(int, int)'), self.sentenceStateChanged) ## Get sentences from the database table self.getSentencesFromDatabase() self.setGeometry(800, 800, 900, 650) def getSentencesFromDatabase(self): ## returns the sentence and the corresponding word associated with it self.twoTypeList = data.Data().getSentencesFromDatabase() if len(self.twoTypeList) == 2: self.sentenceList = self.twoTypeList[0] ## load the sentences in the Table Widget self.loadSentencesInTable() def loadSentencesInTable(self): self.col = 0 if len(self.sentenceList) > 0: self.sentenceTable.setRowCount(len(self.sentenceList)) cellList = [] ## Create QTableWidgetItems from the sentence list for sentence in self.sentenceList: item = QTableWidgetItem(QString(sentence)) item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)) item.setCheckState(Qt.Unchecked) cellList.append(item) cellList.reverse() # set the widget items in the table for item in range(0, len(self.sentenceList)): self.sentenceTable.setItem(item, self.col, cellList.pop()) for index in range(0, len(self.sentenceList)): self.sentenceTable.verticalHeader().resizeSection(index, 100) if len(self.sentenceList) == 5: self.sentenceTable.setFixedHeight(500) if len(self.sentenceList) == 4: self.sentenceTable.setFixedHeight(400) elif len(self.sentenceList) == 3: self.sentenceTable.setFixedHeight(300) elif len(self.sentenceList) == 2: self.sentenceTable.setFixedHeight(200) elif len(self.sentenceList) == 1: self.sentenceTable.setFixedHeight(100) else: self.sentenceTable.clearContents() def sentenceStateChanged(self, row, col): if (self.sentenceTable.item(row, col).checkState() == 2): self.removeList[row] = self.sentenceTable.item(row, col).text() self.sentenceTable.item(row, col).setFlags(Qt.ItemFlags(Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)) else: self.sentenceTable.item(row,col).setFlags(Qt.ItemFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)) del self.removeList[row] def onRemoveClicked(self): if len(self.removeList) == 0: QMessageBox.information(self, 'Remove Sentences', 'Select the Sentences to Delete') else: reply = QMessageBox.question(self, 'Remove Sentences', 'You want to delete the selected sentences', QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: for sentence in self.removeList: if sentence in self.sentenceList: self.sentenceList.remove(sentence) ## clear the contents of the Table self.sentenceTable.clearContents() cellList = [] ## Add the new entries into the table for sentence in self.sentenceList: item = QTableWidgetItem(QString(sentence)) item.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)) item.setCheckState(Qt.Unchecked) cellList.append(item) cellList.reverse() for index in range(0, len(self.sentenceList)): self.sentenceTable.setItem(index, self.col, cellList.pop()) self.sentenceTable.setRowCount(len(self.sentenceList)) deleteSentences = [] for sentence in self.removeList.values(): deleteSentences.append(sentence) rowsDeletec = data.Data().deleteSentencesFromDatabase(deleteSentences) self.getSentencesFromDatabase() self.removeList = {} def closeClicked(self): reply = QMessageBox.question(self, "Remove Sentences", "Do you want to close the application", QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: self.reject()
class MainWidget(QMainWindow): def __init__(self, parent=None): super(MainWidget, self).__init__( parent, windowTitle='GithubRemote', windowIcon=QIcon(image_path('git.png')), geometry=QRect(300, 300, 600, 372)) self.repo_pixmap = QPixmap(image_path('book_16.png')) self.big_repo_pixmap = QPixmap(image_path('book_32.png')) self.repo_fork_pixmap = QPixmap(image_path('book_fork_16.png')) self.star_pixmap = QPixmap(image_path('star_16.png')) self.big_star_pixmap = QPixmap(image_path('star_32.png')) self.fork_pixmap = QPixmap(image_path('fork_16.png')) self.eye_pixmap = QPixmap(image_path('eye_16.png')) self.github = None # Actions self.repoAddAction = QAction( QIcon(image_path('plus_48.png')), '&Add Repo', self, statusTip='Add a new repo') self.repoAddAction.triggered.connect(self.repoAdd) self.repoRemoveAction = QAction( QIcon(image_path('minus.png')), '&Remove Repo', self, statusTip='Remove repo') self.repoRemoveAction.triggered.connect(self.repoRemove) self.repoRefreshAction = QAction( QIcon(image_path('refresh.png')), 'Refresh', self, statusTip='Refresh list of repos') self.repoRefreshAction.triggered.connect(self.reposRefresh) self.repoRefreshAction.triggered.connect(self.starsRefresh) self.addAccountAction = QAction( 'Add Account', self, statusTip='Add Account') self.addAccountAction.triggered.connect(self.addAccount) # userPushButton - Displays the current active username and # image on the top right of the toolbar. self.userButtonMenu = UserButtonMenu(32,32) # ToolBar self.toolBar = self.addToolBar('Main') self.toolBar.setMovable(False) self.toolBar.setFloatable(False) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.toolBar.addAction(self.repoAddAction) self.toolBar.addAction(self.repoRemoveAction) self.toolBar.addAction(self.repoRefreshAction) self.toolBar.addWidget(spacer) self.toolBar.addWidget(self.userButtonMenu) # Menu menuBar = self.menuBar() fileMenu = menuBar.addMenu('&File') actionMenu = menuBar.addMenu('&Action') fileMenu.addAction(self.addAccountAction) actionMenu.addAction(self.repoAddAction) actionMenu.addAction(self.repoRemoveAction) actionMenu.addAction(self.repoRefreshAction) # StatusBar statusBar = self.statusBar() self.setStatusBar(statusBar) # reposTableWidget - Displays a list of the users repositories self.reposTableWidget = QTableWidget(0, 5, selectionBehavior = QAbstractItemView.SelectRows, selectionMode = QAbstractItemView.SingleSelection, editTriggers = QAbstractItemView.NoEditTriggers, itemSelectionChanged = self.actionsUpdate) self.reposTableWidget.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.reposTableWidget.horizontalHeader().setResizeMode(1, QHeaderView.Stretch) self.reposTableWidget.horizontalHeader().setVisible(False) self.reposTableWidget.verticalHeader().setVisible(False) self.reposTableWidget.setShowGrid(False) self.reposTableWidget.verticalHeader().setMinimumSectionSize(25) # repoTab - Layout reposTab = QWidget() reposTabLayout = QVBoxLayout(reposTab) reposTabLayout.addWidget(self.reposTableWidget) reposTab.setLayout(reposTabLayout) # starsTableWidget - Displays a list of the users repositories self.starsTableWidget = QTableWidget(0, 5, selectionBehavior = QAbstractItemView.SelectRows, selectionMode = QAbstractItemView.SingleSelection, editTriggers = QAbstractItemView.NoEditTriggers, itemSelectionChanged = self.actionsUpdate) self.starsTableWidget.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.starsTableWidget.horizontalHeader().setResizeMode(1, QHeaderView.Stretch) self.starsTableWidget.horizontalHeader().setVisible(False) self.starsTableWidget.verticalHeader().setVisible(False) self.starsTableWidget.setShowGrid(False) self.starsTableWidget.verticalHeader().setMinimumSectionSize(25) # repoTab - Layout starsTab = QWidget() starsTabLayout = QVBoxLayout(starsTab) starsTabLayout.addWidget(self.starsTableWidget) starsTab.setLayout(starsTabLayout) # Tab Widget self.tabs = QTabWidget() self.tabs.setTabBar(FlippedTabBar(self)) self.tabs.addTab(reposTab, QIcon(self.big_repo_pixmap), "repos") self.tabs.addTab(starsTab, QIcon(self.big_star_pixmap), "stars") self.tabs.setTabPosition(QTabWidget.West) # Layout self.setCentralWidget(self.tabs) self.actionsUpdate() self.show() # Update self.loadUserMenu() if self.activeUserAction: self.activeUserAction.setVisible(False) self.authenticate() self.actionsUpdate() self.reposRefresh() self.starsRefresh() self.updateImage() @waiting_effects def updateImage(self): try: url = self.github.get_user().avatar_url except (GithubException, AttributeError): return data = urllib.urlopen(url).read() pixmap = QPixmap() pixmap.loadFromData(data) self.activeUserAction.setIcon(QIcon(pixmap)) self.userButtonMenu.setPixmap(pixmap) self.userButtonMenu.setText(self.github.get_user().login) @waiting_effects def loadUserMenu(self): action = None for _, username, token in generate_tokens(CONFIG_PATH, 'github'): try: url = Github(token).get_user().avatar_url except (GithubException, AttributeError): action = QAction(username, self, triggered=self.changeActive) self.userButtonMenu.addAction(action) continue data = urllib.urlopen(url).read() pixmap = QPixmap() pixmap.loadFromData(data) action = QAction(QIcon(pixmap), username, self, triggered=self.changeActive) action.setIconVisibleInMenu(True) self.userButtonMenu.addAction(action) self.activeUserAction = action def changeActive(self): sender = self.sender() self.activeUserAction.setVisible(True) self.activeUserAction = sender self.activeUserAction.setVisible(False) self.authenticate() self.actionsUpdate() self.reposRefresh() self.starsRefresh() self.updateImage() @waiting_effects def reposRefresh(self): self.reposTableWidget.clearContents() try: repos = self.github.get_user().get_repos() self.reposTableWidget.setRowCount(self.github.get_user().public_repos) except (GithubException, AttributeError): return for row, repo in enumerate(repos): imageLabel = QLabel() if repo.fork: imageLabel.setPixmap(self.repo_fork_pixmap) else: imageLabel.setPixmap(self.repo_pixmap) imageLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) imageLabel.setMargin(5) self.reposTableWidget.setCellWidget(row, 0, imageLabel) label = QLabel('<b>{}</b><br />{}'.format( str(repo.name), str(repo.description))) label.setAlignment(Qt.AlignVCenter) label.setMargin(5) label.setWordWrap(True) self.reposTableWidget.setCellWidget(row, 1, label) self.reposTableWidget.setItem(row, 2, QTableWidgetItem(QIcon(self.star_pixmap), str(repo.stargazers_count))) self.reposTableWidget.setItem(row, 3, QTableWidgetItem(QIcon(self.eye_pixmap), str(repo.watchers_count))) self.reposTableWidget.setItem(row, 4, QTableWidgetItem(QIcon(self.fork_pixmap), str(repo.forks_count))) self.reposTableWidget.resizeRowsToContents() @waiting_effects def starsRefresh(self): self.starsTableWidget.clearContents() try: starred = self.github.get_user().get_starred() self.starsTableWidget.setRowCount(self.github.get_user().public_repos) except (GithubException, AttributeError): return for row, repo in enumerate(starred): imageLabel = QLabel() if repo.fork: imageLabel.setPixmap(self.repo_fork_pixmap) else: imageLabel.setPixmap(self.repo_pixmap) imageLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) imageLabel.setMargin(5) self.starsTableWidget.setCellWidget(row, 0, imageLabel) label = QLabel(u'<b>{}/{}</b><br />{}'.format( unicode(repo.owner.login), unicode(repo.name), unicode(repo.description))) label.setAlignment(Qt.AlignVCenter) label.setMargin(5) label.setWordWrap(True) self.starsTableWidget.setCellWidget(row, 1, label) self.starsTableWidget.setItem(row, 2, QTableWidgetItem(QIcon(self.star_pixmap), '0')) self.starsTableWidget.setItem(row, 3, QTableWidgetItem(QIcon(self.eye_pixmap), str(repo.watchers_count))) self.starsTableWidget.setItem(row, 4, QTableWidgetItem(QIcon(self.fork_pixmap), str(repo.forks_count))) self.starsTableWidget.resizeRowsToContents() @waiting_effects def authenticate(self): if self.activeUserAction: username = str(self.activeUserAction.text()) token = load_token(CONFIG_PATH, 'github', username) self.github = Github(token) else: self.github = None def actionsUpdate(self): # TODO disable if no user is logged in if self.github is None: self.repoAddAction.setEnabled(False) self.repoRemoveAction.setEnabled(False) self.repoRefreshAction.setEnabled(False) else: self.repoAddAction.setEnabled(True) self.repoRefreshAction.setEnabled(True) if self._isARepoSelected(): self.repoRemoveAction.setEnabled(True) else: self.repoRemoveAction.setEnabled(False) def addAccount(self): wizard = AddAccountWizard(self) if wizard.exec_(): username = str(wizard.field('username').toString()) token = str(wizard.field('token').toString()) store_token(CONFIG_PATH, 'github', username, token) self.authenticate() self.reposRefresh() self.updateImage() self.actionsUpdate() def repoAdd(self): wizard = AddRepoWizard(self.github, self) if wizard.exec_(): self.github.get_user().create_repo( str(wizard.field('name').toString()), description=str(wizard.field('description').toString()), private=bool(wizard.field('private').toBool()), auto_init=bool(wizard.field('auto_init').toBool()), gitignore_template=str(wizard.field('gitignore').toString()), homepage=str(wizard.field('homepage').toString()), has_wiki=bool(wizard.field('has_wiki').toBool()), has_downloads=bool(wizard.field('has_downloads').toBool()), has_issues=bool(wizard.field('has_issues').toBool())) self.reposRefresh() def repoRemove(self): row = self._selectedRepoRow() name = self.reposTableWidget.item(row, 0).text() dialog = RepoRemoveDialog(self.github, name) if dialog.exec_(): self.github.get_user().get_repo(str(name)).delete() self.reposRefresh() def _isARepoSelected(self): """ Return True if a repo is selected else False """ if len(self.reposTableWidget.selectedItems()) > 0: return True else: return False def _selectedRepoRow(self): """ Return the currently select repo """ # TODO - figure out what happens if no repo is selected selectedModelIndexes = \ self.reposTableWidget.selectionModel().selectedRows() for index in selectedModelIndexes: return index.row()
class DataItemWidget(QWidget): __EXTRA_COLUMN_WIDTH = 20 def __init__(self, me_cls, data): QWidget.__init__(self) self.__me_cls = me_cls self.__setup_ui() self.__data = data self.__init_data() self.__connect_slot() def __setup_ui(self): v_layout = QVBoxLayout() self.__tool_widget = ToolWidget() self.__tool_widget.setMaximumHeight(40) self.__data_table_widget = QTableWidget() self.__data_table_widget.horizontalHeader().setStretchLastSection(True) self.__data_table_widget.horizontalHeader().setResizeMode( 0, QHeaderView.Fixed) v_layout.setSpacing(0) v_layout.setContentsMargins(0, 0, 0, 0) v_layout.addWidget(self.__tool_widget, 0) v_layout.addWidget(self.__data_table_widget, 1) self.setLayout(v_layout) def __connect_slot(self): pass #self.connect(self.__tool_widget,SIGNAL('refresh_btn_clicked()'), self ,SLOT('__on_refresh_signal()')) def __init_data(self): self.__data_table_widget.clearContents() # init header #self.__colume_names = yt_connection.get_table_colume_names(self.__table_name) self.__colume_names = [x.field.name for x in self.__me_cls.attributes] #self.__colume_names.insert(0,'entity_id') #print self.__colume_names self.__data_table_widget.setColumnCount(len(self.__colume_names)) head_list = QStringList() for colume in self.__colume_names: head_list << colume self.__data_table_widget.setHorizontalHeaderLabels(head_list) # default the header column both sides are coverd, these codes add __EXTRA_COLUMN_WIDTH to the header column width # and reise column width in function self.__adjust_table_colume() self.__data_table_widget.horizontalHeader().setResizeMode( QHeaderView.ResizeToContents) self.__record_colume_header_width() self.__data_table_widget.horizontalHeader().setResizeMode( QHeaderView.Interactive) self.__record_colume_header_width() show_data = [] for entity_id, value in self.__data.items(): item = value.obj_data.copy() item['managed_entity_id'] = entity_id show_data.append(item) self.__update_table(show_data) # init data # data = yt_connection.get_table_data(self.__table_name) # # self.__update_table(data) self.__adjust_table_colume() def __record_colume_header_width(self): count = self.__data_table_widget.columnCount() self.__column_widths = [] for i in range(count): self.__column_widths.append( self.__data_table_widget.columnWidth(i) + self.__EXTRA_COLUMN_WIDTH) ''' data like this [ {u'direction': 'to-lport', u'name': '[]', u'priority': '100', u'log': 'true', u'action': 'drop', u'external_ids': '{"neutron:lport"="5fb77332-2035-4f72-8e57-7415b02489c9"}', u'match': '"outport==\\"inside-vm2\\""', u'severity': '[]', 'uuid': '2890a832-1c83-4b8e-8b40-2928817012cc'} ] ''' def __update_table(self, data): self.__data_table_widget.clearContents() row_num = 0 for row in data: self.__data_table_widget.insertRow(row_num) colume_num = 0 for colume in self.__colume_names: if row.has_key(colume): item_str = str(row[colume]) else: item_str = 'None' table_wid_item = QTableWidgetItem(item_str) table_wid_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) self.__data_table_widget.setItem(row_num, colume_num, table_wid_item) colume_num += 1 row_num += 1 def __clear_table_data(self): row_count = self.__data_table_widget.rowCount() rev = [i for i in range(row_count)] rev.reverse() for i in rev: self.__data_table_widget.removeRow(i) def __adjust_table_colume(self): self.__data_table_widget.resizeColumnsToContents() count = self.__data_table_widget.columnCount() for i in range(count): col_wid = self.__data_table_widget.columnWidth(i) if col_wid < self.__column_widths[i]: self.__data_table_widget.setColumnWidth( i, self.__column_widths[i])
class LabelAssistDialog(QDialog): """ A simple UI for showing bookmarks and navigating to them. FIXME: For now, this window is tied to a particular lane. If your project has more than one lane, then each one will have it's own bookmark window, which is kinda dumb. """ def __init__(self, parent, topLevelOperatorView): super(LabelAssistDialog, self).__init__(parent) # Create thread router to populate table on main thread self.threadRouter = ThreadRouter(self) # Set object classification operator view self.topLevelOperatorView = topLevelOperatorView self.setWindowTitle("Label Assist") self.setMinimumWidth(500) self.setMinimumHeight(700) layout = QGridLayout() layout.setContentsMargins(10, 10, 10, 10) # Show variable importance table rows = 0 columns = 4 self.table = QTableWidget(rows, columns) self.table.setHorizontalHeaderLabels(['Frame', 'Max Area', 'Min Area', 'Labels']) self.table.verticalHeader().setVisible(False) # Select full row on-click and call capture double click self.table.setSelectionBehavior(QTableView.SelectRows); self.table.doubleClicked.connect(self._captureDoubleClick) layout.addWidget(self.table, 1, 0, 3, 2) # Create progress bar self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(0) self.progressBar.hide() layout.addWidget(self.progressBar, 4, 0, 1, 2) # Create button to populate table self.computeButton = QPushButton('Compute object info') self.computeButton.clicked.connect(self._triggerTableUpdate) layout.addWidget(self.computeButton, 5, 0) # Create close button closeButton = QPushButton('Close') closeButton.clicked.connect(self.close) layout.addWidget(closeButton, 5, 1) # Set dialog layout self.setLayout(layout) def _triggerTableUpdate(self): # Check that object area is included in selected features featureNames = self.topLevelOperatorView.SelectedFeatures.value if 'Standard Object Features' not in featureNames or 'Count' not in featureNames['Standard Object Features']: box = QMessageBox(QMessageBox.Warning, 'Warning', 'Object area is not a selected feature. Please select this feature on: \"Standard Object Features > Shape > Size in pixels\"', QMessageBox.NoButton, self) box.show() return # Clear table self.table.clearContents() self.table.setRowCount(0) self.table.setSortingEnabled(False) self.progressBar.show() self.computeButton.setEnabled(False) def compute_features_for_frame(tIndex, t, features): # Compute features and labels (called in parallel from request pool) roi = [slice(None) for i in range(len(self.topLevelOperatorView.LabelImages.meta.shape))] roi[tIndex] = slice(t, t+1) roi = tuple(roi) frame = self.topLevelOperatorView.SegmentationImages(roi).wait() frame = frame.squeeze().astype(numpy.uint32, copy=False) # Dirty trick: We don't care what we're passing here for the 'image' parameter, # but vigra insists that we pass *something*, so we'll cast the label image as float32. features[t] = vigra.analysis.extractRegionFeatures(frame.view(numpy.float32), frame, ['Count'], ignoreLabel=0) tIndex = self.topLevelOperatorView.SegmentationImages.meta.axistags.index('t') tMax = self.topLevelOperatorView.SegmentationImages.meta.shape[tIndex] features = {} labels = {} def compute_all_features(): # Compute features in parallel pool = RequestPool() for t in range(tMax): pool.add( Request( partial(compute_features_for_frame, tIndex, t, features) ) ) pool.wait() # Compute labels labels = self.topLevelOperatorView.LabelInputs([]).wait() req = Request(compute_all_features) req.notify_finished( partial(self._populateTable, features, labels) ) req.submit() @threadRouted def _populateTable(self, features, labels, *args): self.progressBar.hide() self.computeButton.setEnabled(True) for time, feature in features.iteritems(): # Insert row rowNum = self.table.rowCount() self.table.insertRow(self.table.rowCount()) # Get max and min object areas areas = feature['Count']#objectFeatures['Standard Object Features']['Count'] maxObjArea = numpy.max(areas[numpy.nonzero(areas)]) minObjArea = numpy.min(areas[numpy.nonzero(areas)]) # Get number of labeled objects labelNum = numpy.count_nonzero(labels[time]) # Load fram number item = QTableWidgetItem(str(time)) item.setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) self.table.setItem(rowNum, 0, item) # Load max object areas item = QTableWidgetItemWithFloatSorting(str("{: .02f}".format(maxObjArea))) item.setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) self.table.setItem(rowNum, 1, item) # Load min object areas item = QTableWidgetItemWithFloatSorting(str("{: .02f}".format(minObjArea))) item.setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) self.table.setItem(rowNum, 2, item) # Load label numbers item = QTableWidgetItemWithFloatSorting(str("{: .01f}".format(labelNum))) item.setFlags( Qt.ItemIsSelectable | Qt.ItemIsEnabled ) self.table.setItem(rowNum, 3, item) # Resize column size to fit dialog size self.table.horizontalHeader().setResizeMode(QHeaderView.Stretch) # Sort by max object area self.table.setSortingEnabled(True) self.table.sortByColumn(1) def _captureDoubleClick(self): # Navigate to selected frame index = self.table.selectedIndexes()[0] frameStr = self.table.model().data(index).toString() if frameStr: frameNum = int(frameStr) self.parent().editor.posModel.time = frameNum
class FormTable(QWidget): # ------------------------------------------------------------------------------------- # Form signal(s) closingFormTable = pyqtSignal() deletingFormTable = pyqtSignal() # ------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------- # Method init def __init__(self, parent=None): # ------------------------------------------------------------------------------------- # Constructor super(FormTable, self).__init__(parent) self.setWindowTitle('Section Table') oLayout = QVBoxLayout() self.TableWidget = QTableWidget() self.BtnSave = QPushButton('Save', self) self.BtnCancel = QPushButton('Cancel', self) # Define layout oLayout.addWidget(self.TableWidget) oLayout.addWidget(self.BtnSave) oLayout.addWidget(self.BtnCancel) # Set layout self.setLayout(oLayout) self.oLayout = oLayout # Define action(s) self.BtnSave.pressed.connect(self.saveTable) self.BtnCancel.pressed.connect(self.cancelTable) # Show widget self.show() # ------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------- # Method to set data def setData(self, oData): # Check data table if oData: iDataRows = len(oData) iDataCols = len(oData[0]) self.TableWidget.setRowCount(iDataRows) self.TableWidget.setColumnCount(iDataCols) self.TableWidget.setHorizontalHeaderLabels(oFormSectionHeader) oTableHeader = self.TableWidget.horizontalHeader() oTableHeader.setStretchLastSection(True) iNL = None for iID, a1oLine in enumerate(oData): if iNL is None: iNL = len(a1oLine) a2oTable = [[] for iL in range(iNL)] else: pass for iElemID, oElemVal in enumerate(a1oLine): a2oTable[iElemID].append(oElemVal) oItem = QTableWidgetItem(oElemVal) oItem.setFlags(Qt.ItemIsSelectable) self.TableWidget.setItem(iID, iElemID, oItem) self.TableWidget.resizeColumnsToContents() self.TableWidget.update() #self.TableWidget.repaint() self.TableWidget.setEditTriggers(QAbstractItemView.CurrentChanged) else: # Nullity table object #self.TableWidget.setRowCount(0) #self.TableWidget.setColumnCount(0) self.TableWidget.clearContents() self.TableWidget.setItem(0, 0, QTableWidgetItem("No data here ... ")) #self.TableWidget.setHorizontalHeaderLabels(oFormSectionHeader) # ------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------- # Method to cancel table def cancelTable(self): self.deletingFormTable.emit() # ------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------- # Method to save table object to ascii file def saveTable(self): # Select output filename sFilePath = str(QFileDialog.getSaveFileName(self, 'Save File', '', 'ASCII (*.txt)')) # Check file definition by user if sFilePath is not None: # Save data to file writeTableObj(sFilePath, self.TableWidget) else: pass # ------------------------------------------------------------------------------------- # ------------------------------------------------------------------------------------- # Method to close event (destroy QWidget); closing plugin will destroy table form too def closeEvent(self, oEvent): oEvent.accept() self.closingFormTable.emit()