def testButtonClick(self): """Indirect qt signal emission using the QPushButton.click() method """ button = QPushButton('label') QObject.connect(button, SIGNAL('clicked()'), self.cb) self.args = tuple() button.click() self.assertTrue(self.called)
def testButtonClick(self): """Indirect qt signal emission using the QPushButton.click() method """ button = QPushButton('label') QObject.connect(button, SIGNAL('clicked()'), self.cb) self.args = tuple() button.click() self.assert_(self.called)
class CheckUpdateDialog(QDialog): def __init__(self, settings, parent=None) -> None: QDialog.__init__(self) self.settings = settings self.signal = CheckUpdateSignals() self.current_version = 'Dev' self.downloadUrl = '' currentVersionLabel = QLabel('Current Version: {}'.format( self.current_version)) self.latestVersionLabel = QLabel( 'Latest Version: {}'.format('Unknown')) self.checkUpdatePushButton = QPushButton('Check Update') self.checkUpdatePushButton.clicked.connect(self.getUpdate) self.versionInformationBox = QTextEdit() self.versionInformationBox.setReadOnly(True) self.downloadButton = QPushButton('Download') self.downloadButton.setVisible(False) self.downloadButton.clicked.connect(self.downloadUpdate) self.copyUrlButton = QPushButton('Copy Download Url') self.copyUrlButton.setVisible(False) self.copyUrlButton.clicked.connect(self.copy) layout = QGridLayout() layout.addWidget(currentVersionLabel) layout.addWidget(self.latestVersionLabel) layout.addWidget(self.versionInformationBox) layout.addWidget(self.checkUpdatePushButton) layout.addWidget(self.downloadButton) layout.addWidget(self.copyUrlButton) self.versionInformationBox.setText('') self.signal.versionInformationSignal.connect( self.setVersionInformation) self.signal.versionLabelSignal.connect(self.setVersionLabel) self.signal.downloadUrlSignal.connect(self.updateDownloadUrl) self.setLayout(layout) self.setWindowTitle('Check Update') self.setWindowFlag(Qt.WindowMinMaxButtonsHint) self.checkUpdatePushButton.click() def getUpdate(self): self.checkUpdatePushButton.setDisabled(True) worker = CheckUpdateWorker(self.settings, self) worker.start() def setVersionLabel(self, text: str): self.latestVersionLabel.setText('Latest Version: {}'.format(text)) def setVersionInformation(self, text: str): self.versionInformationBox.setText(text) def updateDownloadUrl(self, url: str): self.downloadButton.setVisible(True) self.copyUrlButton.setVisible(True) self.downloadUrl = url def downloadUpdate(self): QDesktopServices.openUrl(self.downloadUrl) def copy(self): pyperclip.copy(self.downloadUrl) self.copyUrlButton.setText('Copied!')
def testButtonClickClose(self): button = QPushButton() button.connect(button, SIGNAL('clicked()'), SLOT('close()')) button.show() self.assertTrue(button.isVisible()) button.click() self.assertTrue(not button.isVisible())
def testButtonClickClose(self): button = QPushButton() button.connect(button, SIGNAL('clicked()'), SLOT('close()')) button.show() self.assert_(button.isVisible()) button.click() self.assert_(not button.isVisible())
def testButton(self): #Connecting a lambda to a QPushButton.clicked() obj = QPushButton('label') ctr = Control() func = lambda: setattr(ctr, 'arg', True) QObject.connect(obj, SIGNAL('clicked()'), func) obj.click() self.assert_(ctr.arg) QObject.disconnect(obj, SIGNAL('clicked()'), func)
def testWindowButtonClickClose(self): button = QPushButton() window = QWidget() window.connect(button, SIGNAL('clicked()'), SLOT('close()')) window.show() self.assertTrue(window.isVisible()) button.click() self.assertTrue(not window.isVisible())
def testButton(self): #Connecting a lambda to a QPushButton.clicked() obj = QPushButton('label') ctr = Control() func = lambda: setattr(ctr, 'arg', True) QObject.connect(obj, SIGNAL('clicked()'), func) obj.click() self.assert_(ctr.arg) QObject.disconnect(obj, SIGNAL('clicked()'), func)
def testWindowButtonClickClose(self): button = QPushButton() window = QWidget() window.connect(button, SIGNAL('clicked()'), SLOT('close()')) window.show() self.assert_(window.isVisible()) button.click() self.assert_(not window.isVisible())
def testQuit(self): app = Test([]) button = QPushButton("BUTTON") app.connect(button, SIGNAL("clicked()"), app.called) button.click() self.assertTrue(app._called)
class MainWindow(QMainWindow): kill_thread = Signal() def __init__(self, app): self.app = app # self.qmp = QMP('localhost', 55555) self.qmp = QMP() self.qmp.stateChanged.connect(self.handle_pause_button) self.qmp.connectionChange.connect(self.handle_connect_button) self.paused = False super().__init__() self.init_ui() self.qmp.timeUpdate.connect(self.update_time) self.t = TimeThread(self.qmp) self.time_mult = TimeMultiplier(self.qmp, self.kill_thread) self.window = [] self.default_theme = QGuiApplication.palette() def init_ui(self): # Window Setup self.setWindowTitle("QEMU Control") self.setGeometry(100, 100, 275, 225) self.setFixedSize(self.size()) # App Icon icon = QIcon('package/icons/qemu-official.png') self.setWindowIcon(icon) # User Interface self.menu_bar() self.grid_layout() self.show() def menu_bar(self): bar = self.menuBar() # Menu Bar Actions file_ = bar.addMenu("File") edit = bar.addMenu("Edit") run = bar.addMenu("Run") tools = bar.addMenu("Tools") help_ = bar.addMenu("Help") # File Menu Options open_ = QAction("Open Image", self) file_.addAction(open_) exit_ = QAction("Exit", self) exit_.triggered.connect(self.close) exit_.setShortcut('Ctrl+W') file_.addAction(exit_) # Edit Menu Options prefs = QAction("Preferences", self, triggered=lambda:self.open_new_window(Preferences(self.app, self.default_theme, self.qmp, self.t))) edit.addAction(prefs) # Run Menu Options pause = QAction("Pause", self, triggered=lambda:self.qmp.command('stop')) run.addAction(pause) play = QAction("Play", self, triggered=lambda:self.qmp.command('cont')) run.addAction(play) # Debug Menu Options hexdmp = QAction("Memory Dump", self, triggered=(lambda: self.open_new_window(MemDumpWindow(self.qmp)) if self.qmp.isSockValid() else None)) tools.addAction(hexdmp) asm = QAction("Assembly View", self, triggered=(lambda: self.open_new_window(AssemblyWindow(self.qmp)) if self.qmp.isSockValid() else None)) tools.addAction(asm) registers = QAction("CPU Register View", self, triggered=(lambda: self.open_new_window(RegisterView(self.qmp)) if self.qmp.isSockValid() else None)) tools.addAction(registers) errors = QAction("Logging View", self, triggered=lambda:self.open_new_window(LoggingWindow(self.qmp))) tools.addAction(errors) tree = QAction("Memory Tree", self, triggered=(lambda: self.open_new_window(MemTree(self.qmp, self)) if self.qmp.isSockValid() else None)) tools.addAction(tree) mult = QAction("Time Multiplier", self, triggered=(lambda: self.time_mult.show() if self.qmp.isSockValid() else None)) tools.addAction(mult) trace = QAction("Trace Event Viewer", self, triggered=lambda: self.open_new_window(TraceWindow(self.qmp))) tools.addAction(trace) self.addPlugins(tools) # Help Menu Options usage = QAction("Usage Guide", self) help_.addAction(usage) def addPlugins(self, menu): plugins = menu.addMenu('Plugins') self.manager = PluginManager() self.manager.setPluginPlaces(['plugins']) self.manager.locatePlugins() self.manager.loadPlugins() for plugin in self.manager.getAllPlugins(): plugins.addAction(QAction(plugin.name, self, triggered=(lambda: self.open_new_window(plugin.plugin_object.display(self.qmp)) if self.qmp.isSockValid() else None))) def grid_layout(self): grid = QVBoxLayout() grid.setSpacing(15) self.pause_button = QPushButton('■') self.running_state = QLabel('Current State: <font color="grey">Inactive</font>') def cont_sim(): self.pause_button.setText('■') self.running_state.setText('Current State: <font color="green">Running</font>') self.qmp.command('cont') def stop_sim(): self.pause_button.setText('▶') self.running_state.setText('Current State: <font color="red">Paused</font>') self.qmp.command('stop') subgrid = QHBoxLayout() self.pause_button.clicked.connect(lambda: stop_sim() if not self.paused else cont_sim()) self.pause_button.setFixedSize(QSize(50, 50)) subgrid.addWidget(self.pause_button, 0) # self.pause_button.setCheckable(True) # self.handle_pause_button(False) self.pause_button.setEnabled(False) meatball = QLabel(self) logo = QPixmap('package/icons/nasa.png') logo = logo.scaled(75, 75, Qt.KeepAspectRatio) meatball.setPixmap(logo) subgrid.addWidget(meatball, 1) grid.addLayout(subgrid, 0) self.time = QLabel('Time: 00:00:00') self.time.setFont(QFont('Courier New')) grid.addWidget(self.time, 1) grid.addWidget(self.running_state, 2) self.banner = QLabel('<font color="grey">Connect to QMP to get started!</font>') grid.addWidget(self.banner, 3) conn_grid = QHBoxLayout() self.connect_button = QPushButton("Connect") self.connect_button.setCheckable(True) self.connect_button.clicked.connect(self.qmp_start) self.host = QLineEdit() self.host.returnPressed.connect(lambda: self.connect_button.click() if not self.connect_button.isChecked() else None) self.port = QLineEdit() self.port.returnPressed.connect(lambda: self.connect_button.click() if not self.connect_button.isChecked() else None) conn_grid.addWidget(self.host) conn_grid.addWidget(self.port) conn_grid.addWidget(self.connect_button) grid.addLayout(conn_grid) center = QWidget() center.setLayout(grid) self.setCentralWidget(center) def throwError(self): msgBox = QMessageBox(self) msgBox.setText('Lost Connection to QMP!') msgBox.show() @Slot(bool) def handle_pause_button(self, value): # Catches signals from QMPWrapper #print('recieved: ', value) # time.sleep(0.05) # fix race condition if value: self.paused = False self.pause_button.setText('■') self.running_state.setText('Current State: <font color="green">Running</font>') elif not value and value is not None: self.paused = True self.pause_button.setText('▶') self.running_state.setText('Current State: <font color="red">Paused</font>') def handle_connect_button(self, value): self.connect_button.setChecked(value) self.host.setReadOnly(value) self.port.setReadOnly(value) def open_new_window(self, new_window): if self.qmp.isSockValid(): self.window.append(new_window) def update_time(self, time): date = datetime.fromtimestamp(time / 1000000000, timezone.utc) self.time.setText(f'Time: {date.day - 1:02}:{date.hour:02}:{date.minute:02}:{date.second:02}') # -1 for day because it starts from 1 def qmp_start(self): if self.qmp.isSockValid(): self.qmp.sock_disconnect() self.kill_thread.emit() self.banner.setText('<font color="grey">Connect to QMP to get started!</font>') self.pause_button.setText('■') self.running_state.setText('Current State: <font color="grey">Inactive</font>') self.pause_button.setEnabled(False) return else: s = self.port.text() if s.isnumeric(): self.qmp.sock_connect(self.host.text(), int(s)) if self.qmp.isSockValid(): self.time_mult.start() self.banner.setText('QEMU Version ' + str(self.qmp.banner['QMP']['version']['package'])) self.pause_button.setEnabled(True) else: self.host.setText('127.0.0.1') self.port.setText('55555') self.qmp.sock_connect('127.0.0.1', 55555) if self.qmp.isSockValid(): self.time_mult.start() self.banner.setText('QEMU Version ' + str(self.qmp.banner['QMP']['version']['package'])) self.pause_button.setEnabled(True) # check if running initally if self.qmp.running: self.paused = False self.pause_button.setText('■') self.running_state.setText('Current State: <font color="green">Running</font>') else: self.paused = True self.pause_button.setText('▶') self.running_state.setText('Current State: <font color="red">Paused</font>') if not self.qmp.isAlive(): self.qmp.start() if not self.t.isAlive(): self.t.start() def closeEvent(self, event): self.kill_thread.emit() event.accept() def show_time_mult(self): self.scene = QGraphicsScene() self.view = QGraphicsView(self.scene) self.scene.addItem(self.time_mult.chart) self.view.show()
class CourseTreeWidget(QWidget, ABookCore): def __init__(self, path, settings, session): QWidget.__init__(self) ABookCore.__init__(self, path, settings, session) self.signal = CourseTreeWidgetSignals() self.selectedList = [] self.treeWidget = QTreeWidget() self.treeWidget.setHeaderLabels(['Name', "Course ID", "Chapter ID"]) self.treeWidget.itemChanged.connect(self.checkbox_toggled) self.treeWidget.clicked.connect(self.loadResourceList) self.addDownloadTaskButton = QPushButton("Add to Downloader") self.addDownloadTaskButton.clicked.connect(self.addDownloadTask) self.importCourseButton = QPushButton("Import Courses") self.importCourseButton.clicked.connect(self.startImportCourseWidget) main_layout = QGridLayout() main_layout.addWidget(self.treeWidget, 0, 0, 1, 2) main_layout.addWidget(self.importCourseButton, 1, 0) main_layout.addWidget(self.addDownloadTaskButton, 1, 1) main_layout.setMargin(0) self.setLayout(main_layout) if settings['first_launch'] is True: settings['first_launch'] = False self.importCourseButton.click() else: self.createTreeRoot() def createTreeRoot(self): courseList = self.getCourseList() for course in courseList: courseId = course['courseInfoId'] currentChapterList = self.getChapterList(courseId) self.createTree(self.treeWidget, 'course', course, currentChapterList, courseId) def createTree(self, parentItem, itemType, itemData, chapterList, courseId): if itemType == 'course': courseName = itemData['courseTitle'] courseId = itemData['courseInfoId'] courseItem = self.createCourseTreeItem(courseName, courseId, 'None', True) parentItem.addTopLevelItem(courseItem) childChapterList = self.getChildChapterList(chapterList, {'id': 0}) self.createTree(courseItem, 'chapter', childChapterList, chapterList, courseId) elif itemType == 'chapter': for chapter in itemData: childChapterList = self.getChildChapterList( chapterList, chapter) chapterName = chapter['name'] chapterId = chapter['id'] hasChild = len(childChapterList) > 0 chapterItem = self.createCourseTreeItem( chapterName, courseId, chapterId, hasChild) parentItem.addChild(chapterItem) if hasChild: self.createTree(chapterItem, 'chapter', childChapterList, chapterList, courseId) else: raise KeyError('Wrong TODO') def checkbox_toggled(self, node: QTreeWidgetItem, column: int): if node.checkState(column) == Qt.Checked: self.selectedList.append( [node.text(0), node.text(1), node.text(2)]) elif node.checkState(column) == Qt.Unchecked: if len(self.selectedList) > 1: self.selectedList.remove( [node.text(0), node.text(1), node.text(2)]) else: self.selectedList = [] def createCourseTreeItem(self, name: str, courseId: str, chapterId: str, hasChild: bool): item = QTreeWidgetItem() item.setText(0, str(name)) item.setText(1, str(courseId)) item.setText(2, str(chapterId)) if hasChild is True: item.setFlags(item.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable) else: item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(0, Qt.Unchecked) return item def addDownloadTask(self): for item in self.selectedList: if item[1] != "None" and item[2] != "None": courseId = item[1] chapterId = item[2] downloadList = self.getResourceList(courseId, chapterId) if downloadList is not None: for resource in downloadList: fileDir, filePath, fileName, coursePath = self.getResourcePath( courseId, chapterId, resource["resourceInfoId"]) self.signal.addDownloadTask.emit( fileName, filePath, "http://abook.hep.com.cn/ICourseFiles/" + resource["resFileUrl"]) def startImportCourseWidget(self): wizard = ImportCourseWizard(self) wizard.show() def loadResourceList(self): # When triggered on click, first adjust the width of the column self.treeWidget.resizeColumnToContents(0) self.treeWidget.resizeColumnToContents(1) self.treeWidget.resizeColumnToContents(2) # Get the course_id and chapter_id courseId = self.sender().currentItem().text(1) chapterId = self.sender().currentItem().text(2) # Ignore the root nodes if courseId != "None" and chapterId != "None": # Get the resource list # resource_list = self.get_resource_info(courseId, chapterId) resourceList = self.getResourceList(courseId, chapterId) # Clear the FileListWidget self.signal.clearFileListWidget.emit() # If resource list is not empty if isinstance(resourceList, list): # Each resource item is a QStandardItem # data role -1 stores the url of the resource # data role -2 stores the url of the preview image of the resource # data role Qt.TooltipRole stores the url of the resource # data role Qt.DecorationRole stores the preview image of the resource # We need to lazy load and cache the preview image so that the main thread will not be blocked # 1. create items without the Qt.DecorationRole and add it to resourceItemList # 2. pass the resource_item_list to LoadPicWorker to cache and load resourceItemList = [] for resource in resourceList: resName = resource["resTitle"] urlBase = "http://abook.hep.com.cn/ICourseFiles/" resFileUrl = urlBase + resource["resFileUrl"] resourceItem = QStandardItem(resName) resourceItem.setData(resFileUrl, Qt.ToolTipRole) resourceItem.setData(resFileUrl, -1) resourceItem.setData(resource['picUrl'], -2) self.signal.appendRowFileListWidget.emit(resourceItem) resourceItemList.append(resourceItem) loadPicWorker = LoadPicWorker(resourceItemList, self) loadPicWorker.start()
def init_ui(self): self.setWindowTitle('Trace Event Window') self.setGeometry(100, 100, 800, 600) bar = self.menuBar() file_ = bar.addMenu('File') export_log = QAction('Save to File', self, triggered=lambda: self.save_log()) options = bar.addMenu('Options') auto_refresh = QAction( 'Auto Refresh', self, checkable=True, triggered=lambda: self.timer.start(100) if auto_refresh.isChecked() else self.timer.stop()) auto_refresh.setChecked(True) options.addAction(auto_refresh) file_.addAction(export_log) vgrid = QVBoxLayout() grid = QHBoxLayout() self.tree = QTreeWidget() self.tree.setHeaderLabels(['Name']) self.top = [] self.lst = [] for n, event in enumerate(self.trace_events): word = event.split('_')[0] if word not in self.top: self.top.append(word) item = QTreeWidgetItem(self.tree) self.lst.append(item) item.setText(0, word) subitem = QTreeWidgetItem(item) subitem.setText(0, ' ' + event.split(' : ')[0]) # subitem.setCheckState(0, Qt.Unchecked) cbox = QCheckBox() cbox.stateChanged.connect(lambda state, text=subitem.text(0): self. handle_checked(state, text)) self.tree.setItemWidget(subitem, 0, cbox) # self.tree.setColumnWidth(0, 25) self.tracelist = QLabel() self.disp_output() self.traceview = QScrollArea() self.traceview.setWidget(self.tracelist) self.traceview.setWidgetResizable(True) search = QHBoxLayout() self.search_bar = QLineEdit(self) self.completer = QCompleter(self.top, self) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.search_bar.setCompleter(self.completer) search_button = QPushButton('Search') search_button.clicked.connect(lambda: self.tree.setCurrentItem( self.lst[self.top.index(self.search_bar.text())])) expand = QPushButton('▼') expand.setFixedSize(QSize(25, 25)) expand.clicked.connect(lambda: self.tree.expandAll()) collapse = QPushButton('▲') collapse.setFixedSize(QSize(25, 25)) collapse.clicked.connect(lambda: self.tree.collapseAll()) self.search_bar.returnPressed.connect(lambda: search_button.click()) search.addWidget(self.search_bar) search.addWidget(search_button) search.addWidget(expand) search.addWidget(collapse) self.digest = QLabel() vgrid.addLayout(search) vgrid.addWidget(self.tree) vgridwid = QWidget() vgridwid.setLayout(vgrid) split = QSplitter(Qt.Horizontal) split.addWidget(vgridwid) split.addWidget(self.traceview) split.setStretchFactor(1, 1) # grid.addLayout(vgrid) grid.addWidget(split) # grid.addWidget(self.tracelist) self.disp_output() center = QWidget() center.setLayout(grid) self.setCentralWidget(center) self.show()
class SearchReplaceDialog(QDialog): """Search & Replace window """ def __init__(self, parent, initial_query=None): """Initialize the search window """ super(SearchReplaceDialog, self).__init__(parent) self.parent = parent self.prefs = parent.prefs self.items_checked = 0 self.search_button = QPushButton('Search') self.search_text = MySearchField(self.search_button) self.search_text.setPlaceholderText("Enter search query here") self.search_button.clicked.connect(self.submit_search) input_layout = QHBoxLayout() input_layout.addWidget(self.search_text) input_layout.addWidget(self.search_button) self.results_tree = QTreeView() self.results_tree.setRootIsDecorated(False) self.results_tree.setAlternatingRowColors(True) self.results_tree.setAllColumnsShowFocus(True) self.results_tree.setSelectionBehavior(QAbstractItemView.SelectRows) self.results_tree.setSelectionMode(QAbstractItemView.SingleSelection) self.results_tree.doubleClicked.connect(self.go_to_object) self.whole_field_checkbox = QCheckBox("Whole Field Only", self) self.advanced_search_checkbox = QCheckBox("Advanced Search", self) self.advanced_search_checkbox.stateChanged.connect( self.advanced_search_checked) self.ignore_geometry_checkbox = QCheckBox("Ignore Geometry", self) self.go_button = QPushButton('Go') self.go_button.clicked.connect(self.go_to_object) checks_layout = QHBoxLayout() checks_layout.addWidget(self.whole_field_checkbox) checks_layout.addWidget(self.advanced_search_checkbox) checks_layout.addWidget(self.ignore_geometry_checkbox) checks_layout.addStretch() checks_layout.addWidget(self.go_button) self.query_label = QLabel("Query:") self.query_label.setEnabled(False) self.query_text = QLineEdit() self.query_text.setEnabled(True) self.query_text.setReadOnly(True) self.query_text.setFrame(False) self.query_text.setStyleSheet("""QLineEdit { background-color: LightGray; color: white; } """) query_layout = QHBoxLayout() query_layout.addWidget(self.query_label) query_layout.addWidget(self.query_text) self.select_label = QLabel("Select:") self.select_all_button = QPushButton("All") self.select_none_button = QPushButton("None") self.select_invert_button = QPushButton("Invert") self.delete_button = QPushButton("Delete Objects") self.select_all_button.clicked.connect(self.select_all_clicked) self.select_none_button.clicked.connect(self.select_none_clicked) self.select_invert_button.clicked.connect(self.select_invert_clicked) self.delete_button.clicked.connect(self.delete_button_clicked) self.delete_button.setEnabled(False) selection_layout = QHBoxLayout() selection_layout.addWidget(self.select_label) selection_layout.addWidget(self.select_all_button) selection_layout.addWidget(self.select_none_button) selection_layout.addWidget(self.select_invert_button) selection_layout.addStretch() selection_layout.addWidget(self.delete_button) self.replace_with_text = QLineEdit() self.replace_with_label = QLabel("Replace With:") self.replace_button = QPushButton("Replace") self.replace_button.clicked.connect(self.replace_button_clicked) self.replace_button.setEnabled(False) replace_layout = QHBoxLayout() replace_layout.addWidget(self.replace_with_label) replace_layout.addWidget(self.replace_with_text) replace_layout.addWidget(self.replace_button) layout = QVBoxLayout() layout.addLayout(input_layout) layout.addLayout(checks_layout) layout.addLayout(query_layout) layout.addWidget(self.results_tree) layout.addLayout(selection_layout) layout.addLayout(replace_layout) self.resize(650, 450) self.setLayout(layout) self.setWindowTitle("IDF+ Search & Replace") self.search_text.setFocus() self.setTabOrder(self.search_text, self.search_button) self.setTabOrder(self.search_button, self.whole_field_checkbox) self.setTabOrder(self.whole_field_checkbox, self.advanced_search_checkbox) self.setTabOrder(self.advanced_search_checkbox, self.select_all_button) self.setTabOrder(self.select_all_button, self.select_none_button) self.setTabOrder(self.select_none_button, self.select_invert_button) self.setTabOrder(self.select_invert_button, self.replace_with_text) self.setTabOrder(self.replace_with_text, self.replace_button) self.setTabOrder(self.replace_button, self.search_text) self.results_tree.setModel(self.create_results_model([])) self.results_tree.setColumnHidden(2, True) if initial_query is not None: self.search_text.setText(initial_query) self.search_button.click() def create_results_model(self, results): def add_result_row(row_model, value, obj_class, uuid): row_model.insertRow(0) row_model.setData(model.index(0, 0), value) row_model.setData(model.index(0, 1), obj_class) row_model.setData(model.index(0, 2), uuid) item_0 = model.itemFromIndex(model.index(0, 0)) item_0.setCheckState(Qt.Unchecked) item_0.setFlags(item_0.flags() | Qt.ItemIsUserCheckable) item_0.setEditable(False) item_1 = model.itemFromIndex(model.index(0, 1)) item_1.setEditable(False) model = QStandardItemModel(0, 3, self) model.setHeaderData(0, Qt.Horizontal, "Value") model.setHeaderData(1, Qt.Horizontal, "Class") model.setHeaderData(2, Qt.Horizontal, "UUID") for hit in results: add_result_row(model, hit['value'], hit['obj_class_display'], hit['uuid']) return model def submit_search(self): """Submits a search based on the current query """ user_query = self.search_text.text() idf = self.parent.idf if not user_query or len(user_query) < 2 or not idf: return [], "" results, my_query = idf.search( user_query, self.whole_field_checkbox.isChecked(), self.advanced_search_checkbox.isChecked(), self.ignore_geometry_checkbox.isChecked()) self.query_text.setText(str(my_query)) self.results_tree.setModel(self.create_results_model(results)) self.results_tree.model().itemChanged.connect(self.item_checked) # self.results_tree.setColumnHidden(2, True) self.results_tree.resizeColumnToContents(0) self.results_tree.resizeColumnToContents(1) self.results_tree.setSortingEnabled(True) def item_checked(self, item): if item.checkState() == Qt.Checked: self.items_checked += 1 else: self.items_checked -= 1 if self.items_checked > 0: self.delete_button.setEnabled(True) self.replace_button.setEnabled(True) else: self.delete_button.setEnabled(False) self.replace_button.setEnabled(False) def select_all_clicked(self): model = self.results_tree.model() result_count = model.rowCount() for i in range(result_count): model.itemFromIndex(model.index(i, 0)).setCheckState(Qt.Checked) def select_none_clicked(self): model = self.results_tree.model() result_count = model.rowCount() for i in range(result_count): model.itemFromIndex(model.index(i, 0)).setCheckState(Qt.Unchecked) def select_invert_clicked(self): model = self.results_tree.model() result_count = model.rowCount() for i in range(result_count): item = model.itemFromIndex(model.index(i, 0)) if item.checkState() == Qt.Checked: new_state = Qt.Unchecked else: new_state = Qt.Checked item.setCheckState(new_state) def delete_button_clicked(self): model = self.results_tree.model() result_count = model.rowCount() if result_count <= 0 or self.items_checked <= 0: return question = "Are you sure you want to perform this deletion?\n" \ "Undo is currently NOT supported for this operation." response = self.confirm_action(question) if response is not True: return for i in range(result_count): item_0 = model.itemFromIndex(model.index(i, 0)) item_2 = model.itemFromIndex(model.index(i, 2)) if item_0.checkState() != Qt.Checked: continue field = self.parent.idf.field_by_uuid(item_2.text()) obj = field._outer obj_class = self.parent.idf.idf_objects(obj.obj_class) try: index = obj_class.index(obj) self.parent.idf.remove_objects(obj.obj_class, index, index + 1) except ValueError: pass # already deleted self.parent.set_dirty(True) self.submit_search() self.parent.load_table_view(self.parent.current_obj_class) QMessageBox.information(self, "Delete Action", "Deletion Complete!") def advanced_search_checked(self): if self.advanced_search_checkbox.isChecked(): self.whole_field_checkbox.setEnabled(False) self.whole_field_checkbox.setChecked(True) self.ignore_geometry_checkbox.setEnabled(False) self.ignore_geometry_checkbox.setChecked(False) else: self.whole_field_checkbox.setEnabled(True) self.whole_field_checkbox.setChecked(False) self.ignore_geometry_checkbox.setEnabled(True) self.ignore_geometry_checkbox.setChecked(False) def replace_button_clicked(self): search_text = self.search_text.text() replace_with_text = self.replace_with_text.text() if not search_text: return model = self.results_tree.model() result_count = model.rowCount() if result_count <= 0 or self.items_checked <= 0: return question = "Are you sure you want to perform this replacement?\n" \ "Undo is currently NOT supported for this operation." response = self.confirm_action(question) if response is not True: return for i in range(result_count): item_0 = model.itemFromIndex(model.index(i, 0)) item_2 = model.itemFromIndex(model.index(i, 2)) if item_0.checkState() != Qt.Checked: continue field = self.parent.idf.field_by_uuid(item_2.text()) if self.whole_field_checkbox.isChecked( ) or self.advanced_search_checkbox.isChecked(): field.value = replace_with_text else: regex = re.compile(re.escape(search_text), re.IGNORECASE) field.value = regex.sub(replace_with_text, field.value) self.parent.set_dirty(True) self.submit_search() self.parent.load_table_view(self.parent.current_obj_class) QMessageBox.information(self, "Replacement", "Replacement Complete!") def confirm_action(self, question): """Confirm user wants to perform action """ flags = QMessageBox.StandardButton.Yes flags |= QMessageBox.StandardButton.No response = QMessageBox.question(self, "Are you sure?", question, flags) if response == QMessageBox.Yes: return True elif QMessageBox.No: return False else: return False def go_to_object(self, index=None): if index is None: selected = self.results_tree.selectedIndexes() if not selected: return index = selected[0] model = self.results_tree.model() item = model.itemFromIndex(model.index(index.row(), 2)) field = self.parent.idf.field_by_uuid(item.text()) self.parent.activateWindow() self.parent.jump_to_field(field)
def testQuit(self): app = Test([]) button = QPushButton("BUTTON") app.connect(button, SIGNAL("clicked()"), app.called) button.click() self.assert_(app._called)