def __init__(self, *args, **kwargs): super(Widget_objectList, self).__init__(*args, **kwargs) self.installEventFilter(self) mainLayout = QVBoxLayout(self) treeWidget = QTreeWidget() treeWidget.setColumnCount(2) headerItem = treeWidget.headerItem() headerItem.setText(0, "Target Node") headerItem.setText(1, "Attribute Name") treeWidget.setRootIsDecorated(False) treeWidget.setStyleSheet( "QTreeWidget::item { border-left: 1px solid gray;border-bottom: 1px solid gray; padding: 3px}\ QTreeWidget{ font-size:13px;}") treeWidget.header().setStyleSheet("font-size:12px;") w_buttons = QWidget() lay_buttons = QHBoxLayout(w_buttons) lay_buttons.setContentsMargins(0, 0, 0, 0) lay_buttons.setSpacing(0) button_load = QPushButton("Load List") button_load.setStyleSheet("font:14px;") lay_buttons.addWidget(button_load) mainLayout.addWidget(treeWidget) mainLayout.addWidget(w_buttons) self.treeWidget = treeWidget QtCore.QObject.connect( treeWidget, QtCore.SIGNAL("itemChanged(QTreeWidgetItem * , int )"), self.writeData) QtCore.QObject.connect(button_load, QtCore.SIGNAL("clicked()"), self.cmd_loadList)
def testWidgetIterator(self): treeWidget = QTreeWidget() treeWidget.setColumnCount(1) items = [] for i in range(10): items.append(QTreeWidgetItem(None, ['item: %d' % i])) treeWidget.insertTopLevelItems(0, items) index = 0 for it in QTreeWidgetItemIterator(treeWidget): self.assertEqual(it.value().text(0), 'item: %d' % index) index += 1
def testWidgetIterator(self): treeWidget = QTreeWidget() treeWidget.setColumnCount(1) items = [] for i in range(10): items.append(QTreeWidgetItem(None, ["item: %d" % i])) treeWidget.insertTopLevelItems(0, items) index = 0 for it in QTreeWidgetItemIterator(treeWidget): self.assertEqual(it.value().text(0), "item: %d" % index) index += 1
def testCase(self): treeWidget = QTreeWidget() treeWidget.setColumnCount(1) items = [] for i in range(10): items.append(QTreeWidgetItem(None, ["item: %i" % i])) treeWidget.insertTopLevelItems(0, items); _iter = QTreeWidgetItemIterator(treeWidget) index = 0 while(_iter.value()): item = _iter.value() self.assert_(item is items[index]) index += 1 _iter += 1
def __init__(self, *args, **kwargs): super(Widget_connectionList, self).__init__(*args, **kwargs) self.installEventFilter(self) mainLayout = QVBoxLayout(self) mainLayout.setContentsMargins(5, 5, 5, 5) mainLayout.setSpacing(0) treeWidget = QTreeWidget() treeWidget.setColumnCount(3) headerItem = treeWidget.headerItem() headerItem.setText(0, "Attribute") headerItem.setText(1, "Target Node") headerItem.setText(2, "Target Attr") treeWidget.setRootIsDecorated(False) self.treeWidget = treeWidget treeWidget.setStyleSheet( "QTreeWidget::item { border-bottom: 1px solid gray; padding:1px}\ QTreeWidget{ font-size:13px;}") treeWidget.header().setStyleSheet("font-size:12px;") w_buttons = QWidget() lay_buttons = QHBoxLayout(w_buttons) lay_buttons.setContentsMargins(0, 0, 0, 0) lay_buttons.setSpacing(5) button_add = QPushButton("Add Line") button_remove = QPushButton("Remove Line") lay_buttons.addWidget(button_add) lay_buttons.addWidget(button_remove) mainLayout.addWidget(treeWidget) mainLayout.addWidget(w_buttons) button_add.clicked.connect(self.cmd_addLine) button_remove.clicked.connect(self.cmd_removeLine) treeWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) QtCore.QObject.connect( treeWidget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.loadContextMenu) self.treeWidget = treeWidget self.readData()
def __init__(self, *args, **kwargs ): self.index = 0 if kwargs.has_key( 'index' ): self.index = kwargs.pop( 'index' ) QWidget.__init__( self, *args, **kwargs ) mainLayout = QVBoxLayout( self ); mainLayout.setContentsMargins(0,0,0,0) mainLayout.setSpacing(0) treeWidget = QTreeWidget() treeWidget.setColumnCount(1) headerItem = treeWidget.headerItem() headerItem.setText( 0, 'Controller list'.decode('utf-8') ) button = QPushButton( 'Load Controllers'.decode('utf-8') ) mainLayout.addWidget( treeWidget ) mainLayout.addWidget( button ) self.treeWidget = treeWidget QtCore.QObject.connect( button, QtCore.SIGNAL("clicked()"), self.loadControllers ) self.uiInfoPath = Window.infoBaseDir + '/Widget_ctlList_%d.json' % self.index self.loadInfo()
class CorporateEventPanel(QtGui.QWidget): tableCorporateEvent = None rowCorporateEvent = 0 columnListCorporateEvent = "Asset;Gross Amount;Net Amount;Payment Date".split( ";") def __init__(self): super(self.__class__, self).__init__() self.layout = QtGui.QGridLayout(self) self.clearTables() def clearTables(self): self.row = 0 self.createCorpEventTable() def createCorpEventTable(self): self.treeCorporateEvent = QTreeWidget() self.layout.addWidget(self.treeCorporateEvent, 2, 0, 3, 3) def renderCorpEvent(self, corporateEventPositionDictAsset): self.clearTables() self.treeCorporateEvent.setColumnCount(3) self.treeCorporateEvent.setHeaderLabels(self.columnListCorporateEvent) for key, cep in corporateEventPositionDictAsset.items(): l1 = QTreeWidgetItem( [key, str(cep.accGrossAmount), str(cep.accNetAmount)]) for ce in cep.corporateEventList: l1_child = QTreeWidgetItem([ None, str(ce.grossAmount), str(ce.netAmount), str(ce.paymentDate) ]) l1.addChild(l1_child) self.treeCorporateEvent.addTopLevelItem(l1)
class PushupList(QWidget): ''' classdocs ''' deletePushup = Signal(int) deletePushups_in_a_day = Signal(tuple) def __init__(self, pushups): ''' Constructor ''' QWidget.__init__(self) self.pushups = pushups self.createGUI() def createGUI(self): self.layout = QVBoxLayout() # self.pushupsListWidget = QListWidget(self) self.pushupsListWidget = QTreeWidget(self) self.pushupsListWidget.setMinimumHeight(250) #self.pushupsListWidget.setMaximumWidth(500) self.pushupsListWidget.setAlternatingRowColors(True) self.pushupsListWidget.doubleClicked.connect(self.doubleClick_Test) self.pushupsListWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.pushupsListWidget.customContextMenuRequested.connect( self._customMenu) self._populateTree() self.layout.addWidget(self.pushupsListWidget) self.setLayout(self.layout) # Slot def _customMenu(self): selectedItems = self.pushupsListWidget.selectedItems() if selectedItems is not None: selectedItem = selectedItems[0] if selectedItem.parent() is not None: # Child Item selected menu = QMenu() delete = QAction(self.pushupsListWidget) delete.setText("Delete this pushup") delete.triggered.connect(self._emitDeleteSignal) menu.addAction(delete) menu.exec_(QCursor.pos()) else: # Top level Item selected menu = QMenu() delete = QAction(self.pushupsListWidget) delete.setText("Delete this day and all of its exercises") delete.triggered.connect(self._emitDeleteDaySignal) menu.addAction(delete) menu.exec_(QCursor.pos()) def _emitDeleteSignal(self): selectedItem = self.pushupsListWidget.selectedItems()[0] pushupId = selectedItem.data(0, Qt.UserRole)._id self.deletePushup.emit(pushupId) def _emitDeleteDaySignal(self): selectedItem = self.pushupsListWidget.selectedItems()[0] treeWidgetItems = selectedItem.takeChildren() pushupsIdList = [] for item in treeWidgetItems: pushup = item.data(0, Qt.UserRole)._id pushupsIdList.append(pushup) self.deletePushups_in_a_day.emit(pushupsIdList) def _populateTree(self): self.pushupsListWidget.clear() self.pushupsListWidget.setColumnCount(4) self.pushupsListWidget.setHeaderLabels([ "Date", "TotalPushups", "Series", "Repetitions", "Average Heart Rate" ]) self.pushupsListWidget.setSortingEnabled(True) self.pushupsListWidget.setColumnWidth(0, 180) self.pushupsListWidget.setColumnWidth(4, 150) pushupDict = self._getPushupDictionary() for it, dayOfExercise in enumerate(sorted(pushupDict.keys())): dateItem = QTreeWidgetItem() dayLabel = dayOfExercise.strftime("%Y/%m/%d") dateItem.setText(0, "\n" + dayLabel + "\nDay : " + str(it)) self.pushupsListWidget.addTopLevelItem(dateItem) totalPushups = 0 for pushup in pushupDict[dayOfExercise]: pushupItem = QTreeWidgetItem() pushupItem.setText(2, "#" + str(pushup._series)) pushupItem.setText(3, str(pushup._repetitions)) pushupItem.setText(4, str(pushup._averageHeartRate)) pushupItem.setData(0, Qt.UserRole, pushup) totalPushups = totalPushups + pushup._repetitions dateItem.addChild(pushupItem) dateItem.setText(1, str(totalPushups)) def doubleClick_Test(self): selectedItems = self.pushupsListWidget.selectedItems() if selectedItems is not None: selectedItem = selectedItems[0] if selectedItem.parent() is not None: # Child Item selected selectedPushups = self.pushupsListWidget.selectedItems( )[0].data(0, Qt.UserRole) print selectedPushups._id else: print "Top level widget double clicked" def reloadPushupsList(self, pushups): self.pushups = pushups self._populateTree() def _populateListWidget(self): ''' unused old method ''' self.pushupsListWidget.clear() pushupDict = self._getPushupDictionary() for dayOfExercise in pushupDict: listItemString = "Date : " + dayOfExercise + "\n" listItem_Data = [] for pushup in pushupDict[dayOfExercise]: listItemString += "Series : " + str(pushup._series) + \ " Repetition : " + str(pushup._repetitions) + "\n" listItem_Data.append(pushup) listItem = QListWidgetItem(listItemString) listItem.setData(Qt.UserRole, listItem_Data) self.pushupsListWidget.addItem(listItem) def _getPushupDictionary(self): ''' Returns a dictionary with the following structure : - Key : date of the exercises. Type datetime.date - Value : list containing pushups made that day . Type : [Pushup model object] example : { 2014-08-18: [pushupModelObj1, pushupModelObj2, pushupModelObj3], 2014-08-19: [pushupModelObj4, pushupModelObj5, pushupModelObj6] } ''' pushupDateList = {} # dictionary initialization for pushup in self.pushups: if not pushupDateList.has_key(pushup._date): pushupsList = [pushup] pushupDateList[pushup._date] = pushupsList else: pushupDateList[pushup._date].append(pushup) # for k in pushupDateList.keys(): # print k # # for pu in pushupDateList[k]: # print pu return pushupDateList
class PushupList(QWidget): ''' classdocs ''' deletePushup = Signal(int) deletePushups_in_a_day = Signal(tuple) def __init__(self, pushups): ''' Constructor ''' QWidget.__init__(self) self.pushups = pushups self.createGUI() def createGUI(self): self.layout = QVBoxLayout() # self.pushupsListWidget = QListWidget(self) self.pushupsListWidget = QTreeWidget(self) self.pushupsListWidget.setMinimumHeight(250) #self.pushupsListWidget.setMaximumWidth(500) self.pushupsListWidget.setAlternatingRowColors(True) self.pushupsListWidget.doubleClicked.connect(self.doubleClick_Test) self.pushupsListWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.pushupsListWidget.customContextMenuRequested.connect(self._customMenu) self._populateTree() self.layout.addWidget(self.pushupsListWidget) self.setLayout(self.layout) # Slot def _customMenu(self): selectedItems = self.pushupsListWidget.selectedItems() if selectedItems is not None : selectedItem = selectedItems[0] if selectedItem.parent() is not None : # Child Item selected menu = QMenu() delete = QAction(self.pushupsListWidget) delete.setText("Delete this pushup") delete.triggered.connect(self._emitDeleteSignal) menu.addAction(delete) menu.exec_(QCursor.pos()) else : # Top level Item selected menu = QMenu() delete = QAction(self.pushupsListWidget) delete.setText("Delete this day and all of its exercises") delete.triggered.connect(self._emitDeleteDaySignal) menu.addAction(delete) menu.exec_(QCursor.pos()) def _emitDeleteSignal(self): selectedItem = self.pushupsListWidget.selectedItems()[0] pushupId = selectedItem.data(0, Qt.UserRole)._id self.deletePushup.emit(pushupId) def _emitDeleteDaySignal(self): selectedItem = self.pushupsListWidget.selectedItems()[0] treeWidgetItems = selectedItem.takeChildren() pushupsIdList = [] for item in treeWidgetItems: pushup = item.data(0, Qt.UserRole)._id pushupsIdList.append(pushup) self.deletePushups_in_a_day.emit(pushupsIdList) def _populateTree(self): self.pushupsListWidget.clear() self.pushupsListWidget.setColumnCount(4) self.pushupsListWidget.setHeaderLabels(["Date", "TotalPushups", "Series", "Repetitions", "Average Heart Rate"]) self.pushupsListWidget.setSortingEnabled(True) self.pushupsListWidget.setColumnWidth(0, 180) self.pushupsListWidget.setColumnWidth(4, 150) pushupDict = self._getPushupDictionary() for it, dayOfExercise in enumerate(sorted(pushupDict.keys())): dateItem = QTreeWidgetItem() dayLabel = dayOfExercise.strftime("%Y/%m/%d") dateItem.setText(0, "\n" + dayLabel + "\nDay : " + str(it)) self.pushupsListWidget.addTopLevelItem(dateItem) totalPushups = 0 for pushup in pushupDict[dayOfExercise]: pushupItem = QTreeWidgetItem() pushupItem.setText(2, "#" + str(pushup._series)) pushupItem.setText(3, str(pushup._repetitions)) pushupItem.setText(4, str(pushup._averageHeartRate)) pushupItem.setData(0, Qt.UserRole, pushup) totalPushups = totalPushups + pushup._repetitions dateItem.addChild(pushupItem) dateItem.setText(1, str(totalPushups)) def doubleClick_Test(self): selectedItems = self.pushupsListWidget.selectedItems() if selectedItems is not None : selectedItem = selectedItems[0] if selectedItem.parent() is not None : # Child Item selected selectedPushups = self.pushupsListWidget.selectedItems()[0].data(0, Qt.UserRole) print selectedPushups._id else : print "Top level widget double clicked" def reloadPushupsList(self, pushups): self.pushups = pushups self._populateTree() def _populateListWidget(self): ''' unused old method ''' self.pushupsListWidget.clear() pushupDict = self._getPushupDictionary() for dayOfExercise in pushupDict: listItemString = "Date : " + dayOfExercise + "\n" listItem_Data = [] for pushup in pushupDict[dayOfExercise]: listItemString += "Series : " + str(pushup._series) + \ " Repetition : " + str(pushup._repetitions) + "\n" listItem_Data.append(pushup) listItem = QListWidgetItem(listItemString) listItem.setData(Qt.UserRole, listItem_Data) self.pushupsListWidget.addItem(listItem) def _getPushupDictionary(self): ''' Returns a dictionary with the following structure : - Key : date of the exercises. Type datetime.date - Value : list containing pushups made that day . Type : [Pushup model object] example : { 2014-08-18: [pushupModelObj1, pushupModelObj2, pushupModelObj3], 2014-08-19: [pushupModelObj4, pushupModelObj5, pushupModelObj6] } ''' pushupDateList = {} # dictionary initialization for pushup in self.pushups: if not pushupDateList.has_key(pushup._date): pushupsList = [pushup] pushupDateList[pushup._date] = pushupsList else: pushupDateList[pushup._date].append(pushup) # for k in pushupDateList.keys(): # print k # # for pu in pushupDateList[k]: # print pu return pushupDateList
class CustomWidget(QtGui.QMainWindow): def __init__(self): """ Constructor """ QtGui.QMainWindow.__init__(self) self.name = "Custom widget" self.central_widget = QtGui.QWidget() self.setCentralWidget(self.central_widget) # TODO: This is ugly, improve it self.iconp = JConfig().icons_path self._createLayout() def _createGui(self): """ Subclasses must override this depending on the elements they want to add self._createOutputTree(), self._createOutputTable(), self._createOutputWindow() and add them to the corresponding layouts. """ raise NotImplementedError def _createToolBar(self, name): """ Subclasses need to define the specific Actions """ self.toolbar = self.addToolBar(name) self.toolbar.setMovable(False) def _createLayout(self): """ This creates the basic layout: Buttons & Outputs """ # Layouts (This is a common disposition) main_layout = QtGui.QVBoxLayout() self.button_layout = QtGui.QHBoxLayout() output_layout = QtGui.QVBoxLayout() # You will need to create your buttons # and add them to your layout like this: # self.button_layout.addWidget(button_1) # Output Layout Inner (QSplitter) # Add as many widgets as you please # They will be ordered vertically and # be resizable by the user # self.splitter.addWidget(self.table_label) # self.splitter.addWidget(...) self.splitter = QSplitter(QtCore.Qt.Vertical) # Nested layouts main_layout.addLayout(self.button_layout) output_layout.addWidget(self.splitter) main_layout.addLayout(output_layout) self.central_widget.setLayout(main_layout) def _createOutputWindow(self): """ Some binary analysis commands will output to this. """ self.output_label = QtGui.QLabel('Output') self.output_window = QTextEdit() self.output_window.setFontPointSize(10) self.output_window.setReadOnly(True) # Save it for later use self.output_window.original_textcolor = self.output_window.textColor() def _createOutputTable(self): """ A vanilla QTableWidget. Callbacks modify its properties, like number of columns, etc. """ self.table_label = QtGui.QLabel('Table Output') self.table = QTableWidget() self.table.setColumnCount(3) self.table.setColumnWidth(0, 100) self.table.setColumnWidth(1, 300) self.table.setColumnWidth(2, 300) self.table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) # Connect signals to slots self.table.customContextMenuRequested.connect(self._tablePopup) self.table.horizontalHeader().sectionDoubleClicked.connect( self._tableHeaderDoubleClicked) self.table.cellDoubleClicked.connect(self._tableCellDoubleClicked) def _createOutputTree(self): """ A QtreeWidget. Initially used to display those pesky dword comparison to immediate values. """ self.tree_label = QtGui.QLabel('Tree Output') self.tree = QTreeWidget() self.tree.setColumnCount(3) self.tree.setColumnWidth(0, 150) self.tree.setColumnWidth(1, 150) self.tree.setColumnWidth(2, 50) # Connect signals to slots self.tree.itemDoubleClicked.connect(self._treeElementDoubleClicked) ################################################################# # GUI Callbacks ################################################################# def _console_output(self, s="", err=False): """ Convenience wrapper """ if err: # Error message err_color = QColor('red') self.output_window.setTextColor(err_color) self.output_window.append(s) # restore original color self.output_window.setTextColor( self.output_window.original_textcolor) else: self.output_window.append(s) def _tableCellDoubleClicked(self, row, col): """ Most of the info displayed in QTableWidgets represent addresses. Default action: try to jump to it. """ it = self.table.item(row, col).text() try: addr = int(it, 16) jump_to_address(addr) except ValueError: self._console_output("[!] That does not look like an address...", err=True) return def _tablePopup(self, pos): """ Popup menu activated clicking the secondary button on the table """ menu = QtGui.QMenu() # Add menu entries delRow = menu.addAction(QIcon(self.iconp + "close.png"), "Delete Row") selItem = menu.addAction(QIcon(self.iconp + "bookmark.png"), "Mark entry") menu.addSeparator() origFunc = menu.addAction(QIcon(self.iconp + "lightning.png"), "Select origin function") destFunc = menu.addAction(QIcon(self.iconp + "flag.png"), "Select destination function") # Get entry clicked action = menu.exec_(self.mapToGlobal(pos)) # Dispatch :) if action == delRow: self.table.removeRow(self.table.currentRow()) elif action == selItem: self.table.currentItem().setBackground(QtGui.QColor('red')) elif action == origFunc: try: addr = self.table.currentItem().text() InfoUI.function_orig_ea = int(addr, 16) except: self._console_output("This does not look like an address...", err=True) elif action == destFunc: try: addr = self.table.currentItem().text() InfoUI.function_dest_ea = int(addr, 16) except: self._console_output("This does not look like an address...", err=True) def _tableHeaderDoubleClicked(self, index): """ Used to sort the contents """ self.table.sortItems(index, order=QtCore.Qt.AscendingOrder) def _treeElementDoubleClicked(self, item, column): """ QTreeWidgetElement callback. Basically it jumps to the selected address in IDA disassembly window. """ try: # Only interested in addresses addr_int = int(item.text(column), 16) jump_to_address(addr_int) # Paint some color item.setBackground(column, QtGui.QColor('green')) except: self._console_output("[!] That does not look like an address...", err=True)
if __name__ == '__main__': app = 0 if QApplication.instance(): app = QApplication.instance() else: app = QApplication(sys.argv) l1 = QTreeWidgetItem(["ALFA", "100"]) l2 = QTreeWidgetItem(["GRUMA", "200"]) for i in range(3): l1_child = QTreeWidgetItem([None, str(i * 10), "Child C" + str(i)]) l1.addChild(l1_child) for j in range(2): l2_child = QTreeWidgetItem([None, str(j * 20), "Child CC" + str(j)]) l2.addChild(l2_child) w = QWidget() w.resize(510, 210) tw = QTreeWidget(w) tw.resize(500, 200) tw.setColumnCount(3) tw.setHeaderLabels(["Asset", "Gross Amount", "Payment Date"]) tw.addTopLevelItem(l1) tw.addTopLevelItem(l2) w.show() sys.exit(app.exec_())
class WorldViewerDebug(QDialog): def __init__(self, worldviewer, parent=None): global client super(WorldViewerDebug, self).__init__(parent) self.setWindowTitle("World Viewer Debug") pos = QApplication.instance().desktop().availableGeometry() self.move(pos.width()/2, 0) self.worldviewer = worldviewer self.objects_tree = QTreeWidget() self.objects_tree.setColumnCount(2) self.objects_tree.setHeaderLabels(["ID", "Name", "Location", "Resource", "Last Modified", "Dist to Player"]) self.objects_tree.setSortingEnabled(True) layout = QVBoxLayout() for w in (self.objects_tree,): layout.addWidget(w) self.setLayout(layout) self.obj_update_timer = QTimer(self) self.connect(self.obj_update_timer, SIGNAL("timeout()"), self.update) self.obj_update_timer.start(CLIENT_UPDATE_FREQ) def sizeHint(self): desktop = QApplication.instance().desktop() geom = desktop.availableGeometry() return QSize(geom.width()/2, geom.height()) def show(self): '''This is overridden to not allow this to be shown when running in non-debug mode''' super(WorldViewerDebug, self).show() if not DEBUG: self.hide() def update(self): items = [] playerx, playery = 0, 0 for objid, obj in self.worldviewer.world_objects.items(): if "Object.ScriptedObject.Character" in obj['_types']: playerx = obj['loc']['x'] playery = obj['loc']['y'] break for objid, obj in self.worldviewer.world_objects.items(): name = obj['name'] try: locx = obj['loc']['x'] except KeyError: continue locy = obj['loc']['y'] locz = obj['loc']['z'] resource = obj['resource'] last_modified = datetime.datetime.fromtimestamp(int(str(obj['last_modified']['$date'])[:-3])) row = self.objects_tree.findItems(objid, Qt.MatchExactly, column=0) if row: # Update it if it exists already item = row[0] if not row: # If Item does not exist in the tree widget already, make a new one. item = QTreeWidgetItem(self.objects_tree) items.append(item) for i, param in enumerate((objid, name, (locx, locy, locz), resource, last_modified, "%04d" % euclidian(locx, locy, playerx, playery))): item.setText(i, str(param)) if items: self.objects_tree.insertTopLevelItems(0, items)
class DirectoryDetectWindow(QWidget): def __init__(self): QWidget.__init__(self) self.setWindowTitle('Directory Detective Tool') main_layout = QVBoxLayout() path_layout = self._init_path_layout() guide_layout = self._init_guide_layout() detail_layout = self._init_detail_layout() main_layout.addLayout(path_layout) main_layout.addLayout(guide_layout) main_layout.addLayout(detail_layout) self.setLayout(main_layout) self.setGeometry(300, 300, 400, 350) self._connect() self._walk_folder = None self._last_path = None self.directory_info = None self._button_list = list() self._last_info = None def _init_path_layout(self): path_layout = QHBoxLayout() self.input_path = QLineEdit(self) self.input_path.setFixedHeight(35) self.input_path.setPlaceholderText('Type search path here') self.button_path = QPushButton('Scan', self) self.button_path.setFixedHeight(35) self.button_path.setFocus() path_layout.addWidget(QLabel('Path:', self)) path_layout.addWidget(self.input_path, stretch=True) path_layout.addWidget(self.button_path) return path_layout def _init_guide_layout(self): self.guide_layout = QHBoxLayout() self.guide_layout.setAlignment(Qt.AlignLeft) return self.guide_layout def refresh_trees(self, store_list, ignore_list): self._refresh_key_tree(store_list, ignore_list=ignore_list) self._refresh_value_tree(store_list) def add_button(self, name, store_list, ignore_list=None): button = QPushButton(name) button.setFixedSize(60, 35) item = (name, button, store_list, ignore_list) self._button_list.append(item) self.guide_layout.addWidget(button) self.refresh_trees(store_list=store_list, ignore_list=ignore_list) button.clicked.connect(lambda: self._set_button(item=item)) def _set_button(self, item): index_item = self._button_list.index(item) if len(self._button_list) > index_item + 1: for name, button, store_list, ignore_list in self._button_list[index_item + 1:]: button.setParent(None) name, button, store_list, ignore_list = item self.refresh_trees(store_list=store_list, ignore_list=ignore_list) def _init_detail_layout(self): detail_layout = QGridLayout() self.key_tree = QTreeWidget() self.key_tree.setColumnCount(2) self.key_tree.setColumnWidth(0, 200) self.key_tree.setHeaderLabels(['Key', 'Size']) self.value_tree = QTreeWidget() self.value_tree.setColumnCount(2) self.value_tree.setColumnWidth(0, 200) self.value_tree.setHeaderLabels(['Path', 'Size']) detail_layout.setColumnStretch(0, 1) detail_layout.setColumnStretch(1, 1) detail_layout.addWidget(self.value_tree) detail_layout.addWidget(self.key_tree) return detail_layout def _connect(self): self.button_path.clicked.connect(self.button_path_clicked) self.key_tree.doubleClicked.connect(self.key_tree_double_clicked) def button_path_clicked(self): del self._button_list[:] for _ in range(self.guide_layout.count()): current_item = self.guide_layout.takeAt(0) current_item.widget().setParent(None) path = unicode.encode(self.input_path.text()) if self._last_path != path: self._walk_folder = walk_folder.run(path=path) max_level = 4 self.directory_info = list(self._walk_folder.get_children_by_level(level=max_level)) self.add_button('/', self.directory_info) def key_tree_double_clicked(self, selected_index=QModelIndex()): select_data = selected_index.data() ignore_list = [select_data] for item in self._button_list[1:]: ignore_list.append(item[0]) store_dict = dict(self._last_info.get_children_by_key(key=select_data, ignore_list=ignore_list).sort_dictionary) store_list = list() for item in store_dict.values(): store_list.extend(item['children']) store_list = list(set(store_list)) self.add_button(select_data, store_list or list(), ignore_list=ignore_list) def _get_size(self, size): return '{} <> {}%'.format(human_size(size), round(size * 100 / self._walk_folder.total_size, 2)) def _refresh_key_tree(self, directory_info, ignore_list=None): info = LabelInfo(make_dictionary_by_classification(directory_info, ignore_list)) # Clear for _ in range(self.key_tree.topLevelItemCount()): self.key_tree.takeTopLevelItem(0) # Add for k, v in info.sort_dictionary: tree_widget = QTreeWidgetItem() tree_widget.setText(0, k) total_size = 0 for child in v['children']: total_size += child.total_size tree_widget.setText(1, self._get_size(v[constant.sort_size_name])) self.key_tree.addTopLevelItem(tree_widget) self._last_info = info def _refresh_value_tree(self, directory_info): info = sorted(directory_info, key=lambda x: x.total_size, reverse=True) # Clear for _ in range(self.value_tree.topLevelItemCount()): self.value_tree.takeTopLevelItem(0) # Add for item in info: tree_widget = QTreeWidgetItem() tree_widget.setText(0, item.part_path) tree_widget.setText(1, self._get_size(item.total_size)) self.value_tree.addTopLevelItem(tree_widget)
def __init__(self, *args, **kwargs): self.get_csv_form_google_spreadsheets(Widget_FileTree.url, Widget_FileTree.csv) self.dict_extensionList = self.get_dictList_from_csvPath( Widget_FileTree.csv) super(Widget_FileTree, self).__init__(*args, **kwargs) self.installEventFilter(self) mainLayout = QVBoxLayout(self) mainLayout.setContentsMargins(0, 5, 0, 0) w_basePath = QWidget() lay_basePath = QHBoxLayout(w_basePath) w_basePath.setStyleSheet("font-size:12px") lay_basePath.setContentsMargins(5, 0, 3, 0) label_basePath = QLabel("Base Path : ") lineEdit_basePath = QLineEdit() lineEdit_basePath.setMinimumHeight(22) lineEdit_basePath.setReadOnly(True) lay_basePath.addWidget(label_basePath) lay_basePath.addWidget(lineEdit_basePath) w_tree = QTreeWidget() w_tree.setColumnCount(2) headerItem = w_tree.headerItem() headerItem.setText(0, "File Path") headerItem.setText(1, "Target Node") w_tree.itemExpanded.connect(self.setContentsWidth) w_tree.itemCollapsed.connect(self.setContentsWidth) w_tree.setSelectionMode(QAbstractItemView.ExtendedSelection) self.w_typeAttrList = Widget_TypeAttributeList() w_tree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) QtCore.QObject.connect( w_tree, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), self.loadContextMenu) w_check = QWidget() lay_check = QHBoxLayout(w_check) lay_check.setContentsMargins(5, 5, 0, 10) lay_check.setSpacing(0) checkBox = QCheckBox() checkBox.setFixedWidth(30) label = QLabel("Show Unused files in folder") label.setStyleSheet("font-size:12px") lay_check.addWidget(checkBox) lay_check.addWidget(label) mainLayout.addWidget(w_basePath) mainLayout.addWidget(w_tree) mainLayout.addWidget(w_check) self.w_tree = w_tree self.checkBox = checkBox self.lineEdit = lineEdit_basePath self.load_checkBoxValue(checkBox, Widget_FileTree.path_uiInfo) QtCore.QObject.connect(checkBox, QtCore.SIGNAL("stateChanged(int)"), self.saveCheckBoxValue) QtCore.QObject.connect(w_tree, QtCore.SIGNAL("itemSelectionChanged()"), self.selectItem)
class CustomWidget(QtGui.QMainWindow): def __init__(self): """ Constructor """ QtGui.QMainWindow.__init__(self) self.name = "Custom widget" self.central_widget = QtGui.QWidget() self.setCentralWidget(self.central_widget) # TODO: This is ugly, improve it self.iconp = JConfig().icons_path self._createLayout() def _createGui(self): """ Subclasses must override this depending on the elements they want to add self._createOutputTree(), self._createOutputTable(), self._createOutputWindow() and add them to the corresponding layouts. """ raise NotImplementedError def _createToolBar(self, name): """ Subclasses need to define the specific Actions """ self.toolbar = self.addToolBar(name) self.toolbar.setMovable(False) def _createLayout(self): """ This creates the basic layout: Buttons & Outputs """ # Layouts (This is a common disposition) main_layout = QtGui.QVBoxLayout() self.button_layout = QtGui.QHBoxLayout() output_layout = QtGui.QVBoxLayout() # You will need to create your buttons # and add them to your layout like this: # self.button_layout.addWidget(button_1) # Output Layout Inner (QSplitter) # Add as many widgets as you please # They will be ordered vertically and # be resizable by the user # self.splitter.addWidget(self.table_label) # self.splitter.addWidget(...) self.splitter = QSplitter(QtCore.Qt.Vertical) # Nested layouts main_layout.addLayout(self.button_layout) output_layout.addWidget(self.splitter) main_layout.addLayout(output_layout) self.central_widget.setLayout(main_layout) def _createOutputWindow(self): """ Some binary analysis commands will output to this. """ self.output_label = QtGui.QLabel('Output') self.output_window = QTextEdit() self.output_window.setFontPointSize(10) self.output_window.setReadOnly(True) # Save it for later use self.output_window.original_textcolor = self.output_window.textColor() def _createOutputTable(self): """ A vanilla QTableWidget. Callbacks modify its properties, like number of columns, etc. """ self.table_label = QtGui.QLabel('Table Output') self.table = QTableWidget() self.table.setColumnCount(3) self.table.setColumnWidth(0, 100) self.table.setColumnWidth(1, 300) self.table.setColumnWidth(2, 300) self.table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) # Connect signals to slots self.table.customContextMenuRequested.connect(self._tablePopup) self.table.horizontalHeader().sectionDoubleClicked.connect(self._tableHeaderDoubleClicked) self.table.cellDoubleClicked.connect(self._tableCellDoubleClicked) def _createOutputTree(self): """ A QtreeWidget. Initially used to display those pesky dword comparison to immediate values. """ self.tree_label = QtGui.QLabel('Tree Output') self.tree = QTreeWidget() self.tree.setColumnCount(3) self.tree.setColumnWidth(0, 150) self.tree.setColumnWidth(1, 150) self.tree.setColumnWidth(2, 50) # Connect signals to slots self.tree.itemDoubleClicked.connect(self._treeElementDoubleClicked) ################################################################# # GUI Callbacks ################################################################# def _console_output(self, s = "", err = False): """ Convenience wrapper """ if err: # Error message err_color = QColor('red') self.output_window.setTextColor(err_color) self.output_window.append(s) # restore original color self.output_window.setTextColor(self.output_window.original_textcolor) else: self.output_window.append(s) def _tableCellDoubleClicked(self, row, col): """ Most of the info displayed in QTableWidgets represent addresses. Default action: try to jump to it. """ it = self.table.item(row, col).text() try: addr = int(it, 16) jump_to_address(addr) except ValueError: self._console_output("[!] That does not look like an address...", err = True) return def _tablePopup(self, pos): """ Popup menu activated clicking the secondary button on the table """ menu = QtGui.QMenu() # Add menu entries delRow = menu.addAction(QIcon(self.iconp + "close.png"), "Delete Row") selItem = menu.addAction(QIcon(self.iconp + "bookmark.png"), "Mark entry") menu.addSeparator() origFunc = menu.addAction(QIcon(self.iconp + "lightning.png"), "Select origin function") destFunc = menu.addAction(QIcon(self.iconp + "flag.png"), "Select destination function") # Get entry clicked action = menu.exec_(self.mapToGlobal(pos)) # Dispatch :) if action == delRow: self.table.removeRow(self.table.currentRow()) elif action == selItem: self.table.currentItem().setBackground(QtGui.QColor('red')) elif action == origFunc: try: addr = self.table.currentItem().text() InfoUI.function_orig_ea = int(addr, 16) except: self._console_output("This does not look like an address...", err = True) elif action == destFunc: try: addr = self.table.currentItem().text() InfoUI.function_dest_ea = int(addr, 16) except: self._console_output("This does not look like an address...", err = True) def _tableHeaderDoubleClicked(self, index): """ Used to sort the contents """ self.table.sortItems(index, order = QtCore.Qt.AscendingOrder) def _treeElementDoubleClicked(self, item, column): """ QTreeWidgetElement callback. Basically it jumps to the selected address in IDA disassembly window. """ try: # Only interested in addresses addr_int = int(item.text(column), 16) jump_to_address(addr_int) # Paint some color item.setBackground(column, QtGui.QColor('green')) except: self._console_output("[!] That does not look like an address...", err = True)
class WorldViewerDebug(QDialog): def __init__(self, worldviewer, parent=None): global client super(WorldViewerDebug, self).__init__(parent) self.setWindowTitle("World Viewer Debug") pos = QApplication.instance().desktop().availableGeometry() self.move(pos.width() / 2, 0) self.worldviewer = worldviewer self.objects_tree = QTreeWidget() self.objects_tree.setColumnCount(2) self.objects_tree.setHeaderLabels([ "ID", "Name", "Location", "Resource", "Last Modified", "Dist to Player" ]) self.objects_tree.setSortingEnabled(True) layout = QVBoxLayout() for w in (self.objects_tree, ): layout.addWidget(w) self.setLayout(layout) self.obj_update_timer = QTimer(self) self.connect(self.obj_update_timer, SIGNAL("timeout()"), self.update) self.obj_update_timer.start(CLIENT_UPDATE_FREQ) def sizeHint(self): desktop = QApplication.instance().desktop() geom = desktop.availableGeometry() return QSize(geom.width() / 2, geom.height()) def show(self): '''This is overridden to not allow this to be shown when running in non-debug mode''' super(WorldViewerDebug, self).show() if not DEBUG: self.hide() def update(self): items = [] playerx, playery = 0, 0 for objid, obj in self.worldviewer.world_objects.items(): if "Object.ScriptedObject.Character" in obj['_types']: playerx = obj['loc']['x'] playery = obj['loc']['y'] break for objid, obj in self.worldviewer.world_objects.items(): name = obj['name'] try: locx = obj['loc']['x'] except KeyError: continue locy = obj['loc']['y'] locz = obj['loc']['z'] resource = obj['resource'] last_modified = datetime.datetime.fromtimestamp( int(str(obj['last_modified']['$date'])[:-3])) row = self.objects_tree.findItems(objid, Qt.MatchExactly, column=0) if row: # Update it if it exists already item = row[0] if not row: # If Item does not exist in the tree widget already, make a new one. item = QTreeWidgetItem(self.objects_tree) items.append(item) for i, param in enumerate( (objid, name, (locx, locy, locz), resource, last_modified, "%04d" % euclidian(locx, locy, playerx, playery))): item.setText(i, str(param)) if items: self.objects_tree.insertTopLevelItems(0, items)