class LabelConfigurator(QDialog): def __init__(self, boxManager, spawnPos): super().__init__() # Variables self.spawnPos = spawnPos # Objects self.boxManager = boxManager self.layout = QVBoxLayout(self) self.contentLayout = QHBoxLayout() self.settingsLayout = QVBoxLayout() self.isOccludedButton = Check('Occluded', boxManager.getRecentIsOccluded()) self.isTruncatedButton = Check('Truncated', boxManager.getRecentIsTruncated()) self.isGroupOfButton = Check('Group Of', boxManager.getRecentIsGroupOf()) self.isDepictionButton = Check('Depiction', boxManager.getRecentIsDepiction()) self.isInsideButton = Check('Inside', boxManager.getRecentIsInside()) self.acceptButton = QPushButton('Accept') self.cancelButton = QPushButton('Cancel') self.labelsModel = QStringListModel() self.labelsView = QListView() # Layout self.setWindowFlags(Qt.Popup) self.settingsLayout.setAlignment(Qt.AlignTop | Qt.AlignCenter) self.settingsLayout.setMargin(0) self.settingsLayout.addWidget(self.isOccludedButton) self.settingsLayout.addWidget(self.isTruncatedButton) self.settingsLayout.addWidget(self.isGroupOfButton) self.settingsLayout.addWidget(self.isDepictionButton) self.settingsLayout.addWidget(self.isInsideButton) self.settingsLayout.addStretch(1) self.settingsLayout.addWidget(self.acceptButton) self.settingsLayout.addWidget(self.cancelButton) self.contentLayout.addWidget(self.labelsView) self.contentLayout.addLayout(self.settingsLayout) self.layout.addLayout(self.contentLayout) # Styling self.setStyleSheet('LabelConfigurator { ' 'background-color: ' + ThemeManager.BG_L1 + ';' 'border-top-left-radius: ' + str(ThemeManager.CURVE) + 'px;' 'border-bottom-left-radius: ' + str(ThemeManager.CURVE) + 'px;' 'border-top-right-radius: ' + str(ThemeManager.CURVE) + 'px;' 'border-bottom-right-radius: ' + str(ThemeManager.CURVE) + 'px;' 'border-width: 0px;' 'border-style: solid;' '}' 'QPushButton {' 'background-color: ' + ThemeManager.BG_L2 + ';' 'border-radius: 10px;' 'color: ' + ThemeManager.LABEL + ';' 'font-size: 14px;' '}' 'QPushButton:hover {' 'background-color: ' + ThemeManager.BG_L3 + ';' '}' 'QListView { ' 'background-color: ' + ThemeManager.BG_L2 + ';' '}') self.layout.setMargin(20) self.layout.setSpacing(10) self.contentLayout.setMargin(0) self.labelsModel.setStringList(boxManager.loadLabels()) self.labelsView.setFixedWidth(80) self.labelsView.setFrameStyle(QFrame.NoFrame) self.labelsView.setModel(self.labelsModel) self.labelsView.setItemDelegate(ListDelegate.ListDelegate()) index = None try: row = self.labelsModel.stringList().index( boxManager.getRecentLabelName()) index = self.labelsModel.index(row) except ValueError: index = self.labelsModel.index(0) if index is not None: self.labelsView.setCurrentIndex(index) # Connections self.acceptButton.clicked.connect(self.close) self.cancelButton.clicked.connect(self.reject) def showEvent(self, event): super().showEvent(event) self.move(self.spawnPos) def closeEvent(self, event): labelConfig = (self.labelsView.selectedIndexes()[0].data( role=Qt.DisplayRole), self.isOccludedButton.getEnabled(), self.isTruncatedButton.getEnabled(), self.isGroupOfButton.getEnabled(), self.isDepictionButton.getEnabled(), self.isInsideButton.getEnabled()) self.labelAccepted.emit(labelConfig) super().closeEvent(event) def getLabelConfig(self): return labelAccepted = Signal(object)
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.workers = WorkerManager() self.workers.status.connect(self.statusBar().showMessage) layout = QVBoxLayout() self.progress = QListView() self.progress.setModel(self.workers) delegate = ProgressBarDelegate() self.progress.setItemDelegate(delegate) layout.addWidget(self.progress) self.text = QPlainTextEdit() self.text.setReadOnly(True) start = QPushButton("Start a worker") start.pressed.connect(self.start_worker) stop = QPushButton("Stop") stop.pressed.connect(self.stop_worker) clear = QPushButton("Clear") clear.pressed.connect(self.workers.cleanup) layout.addWidget(self.text) layout.addWidget(start) layout.addWidget(stop) layout.addWidget(clear) w = QWidget() w.setLayout(layout) self.setCentralWidget(w) self.show() # tag::startWorker[] def start_worker(self): x = random.randint(0, 1000) y = random.randint(0, 1000) w = Worker(x, y) w.signals.result.connect(self.display_result) w.signals.error.connect(self.display_result) self.workers.enqueue(w) # end::startWorker[] # tag::stopWorker[] def stop_worker(self): selected = self.progress.selectedIndexes() for idx in selected: job_id, _ = self.workers.data(idx, Qt.DisplayRole) self.workers.kill(job_id) # end::stopWorker[] def display_result(self, job_id, data): self.text.appendPlainText("WORKER %s: %s" % (job_id, data))
class AuswahlDialog(QDialog): def __init__(self, title=None, parent=None): QDialog.__init__(self, parent) self.title = title self.listView = QListView() self.font = QFont("Arial", 14) self.okButton = QPushButton("OK") self.cancelButton = QPushButton("Abbrechen") self.model = QStandardItemModel() self.listView.setModel(self.model) self._selectedIndexes = "" self._createGui() def _createGui(self): hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(self.okButton) hbox.addWidget(self.cancelButton) vbox = QVBoxLayout(self) vbox.addWidget(self.listView, stretch=1) # vbox.addStretch(1) vbox.addLayout(hbox) self.okButton.setDefault(True) if self.title: self.setWindowTitle(self.title) else: self.setWindowTitle("Auswahl") self.okButton.clicked.connect(self.onAccepted) self.cancelButton.clicked.connect(self.reject) def appendItemList(self, itemlist: List[str]): for i in itemlist: self.appendItem(i, None) def appendItem(self, text: str, userdata: Any = None): item = CustomItem(text) if userdata: item.userdata = userdata item.setFont(self.font) self.model.appendRow(item) if self.model.rowCount() == 1: self.listView.setCurrentIndex(self.model.index(0, 0)) def onAccepted(self): self._selectedIndexes = self.listView.selectedIndexes() self.accept() def getSelectedIndexes(self): return self._selectedIndexes def getSelection(self) -> List[Tuple]: sel = self.getSelectedIndexes() l = list() for idx in sel: item: CustomItem = self.model.item(idx.row(), idx.column()) t = (item.text(), item.userdata) l.append(t) return l
class ListerView(QDialog): def __init__(self, title, message, items, parent=None): """ Constructor of ListerView which creates a new dialog with scrolled items which the user can mark Args: title (str): The dialog title that should appear message (str): The message that the user will see at the top of the dialog items ([str]): A list of strings that will be showns as options """ super(ListerView, self).__init__(parent=parent) form = QFormLayout(self) form.addRow(QLabel(message)) self.listView = QListView(self) self.listView.clicked.connect(self.mouse_click_event) form.addRow(self.listView) model = QStandardItemModel(self.listView) self.setWindowTitle(title) for item in items: standardItem = QStandardItem(item) standardItem.setCheckable(True) standardItem.setEditable(False) model.appendRow(standardItem) self.listView.setModel(model) def mouse_click_event(self): """ Callback method that will trigger then the user presses a mouse button while hovering over an item """ row = [qmi.row() for qmi in self.listView.selectedIndexes()][0] item = self.listView.model().item(row) checkState = item.checkState() if checkState == Qt.Checked: checkState = Qt.Unchecked else: checkState = Qt.Checked item.setCheckState(checkState) def enable_button_box(self): """ Method for enabling the buttons the bottom that correspond to OK and Cancel """ form = self.layout() buttonBox = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) form.addRow(buttonBox) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) def get_results(self): """ Method for quering the results of the user markings The result is a list of strings """ selected = [] model = self.listView.model() i = 0 while model.item(i): if model.item(i).checkState(): selected.append(model.item(i).text()) i += 1 return selected
class Shell(QMainWindow): def __init__(self): # constructor super().__init__() # call the parent's constructor # Test data in a model self.users = ['User 1', 'User 2', 'User 3'] self.lv_model = QStringListModel() self.lv_model.setStringList(self.users) # Create the main window content widget w = QWidget() # Setup the rest of the main window appearance self.setGeometry(300, 300, 640, 480) self.setWindowTitle('PySide2 Listview Experiments') self.setWindowIcon(QIcon('assets/icons/moon_64x64.png')) # Create and set the main layout layout = QVBoxLayout() w.setLayout(layout) # Set the layout of the main window content widget self.setCentralWidget(w) # Create and add components to the layout self.lv_label = QLabel('QListView with QStringListModel') layout.addWidget(self.lv_label) self.lv = QListView() self.lv.setSelectionMode( QListView.MultiSelection) # single selection is the default self.lv.setModel(self.lv_model) self.lv.selectionModel().selectionChanged.connect(self.item_selected) layout.addWidget(self.lv) self.button = QPushButton('Update model') self.button.clicked.connect(self.change_model) layout.addWidget(self.button) self.selected_label = QLabel('Selected item: none') layout.addWidget(self.selected_label) layout.addStretch(1) self.show() # display the UI def change_model(self): the_list = self.lv_model.stringList() the_list.append('Another User') self.lv_model.setStringList(the_list) def item_selected(self): # Get the current index (a QModelIndex object) from the QListView # From the index, get the data (a QVariant) that you can convert to a QString index = self.lv.currentIndex() # returns the primary QModelIndex indices = self.lv.selectedIndexes() # returns a list of QModelIndex selected_text = '' for i in indices: selected_text += i.data( ) + '\n' # use .data() to get the value from QModelIndex self.selected_label.setText(selected_text)
class FileSystemWidget(QWidget): def __init__(self, parent, *args, **kwargs): super().__init__(*args, **kwargs) self.currentRootPath = '/' self.currentPath = QDir.currentPath() self.mainWindow = parent self.chooseDirAction = QAction(IconFactory.getIcon('folder'), 'Root directory', self, statusTip="Change root directory", triggered=self.chooseRootDir) self.showOFAction = QAction(IconFactory.getIcon('filter_alt'), 'Show only FITS files', self, statusTip="Show only FITS/all files", triggered=self.showOFFiles) self.showOFAction.setCheckable(True) self.showOFAction.toggled.connect(self.showOFFiles) self.chooseDirBtn = QToolButton() self.chooseDirBtn.setDefaultAction(self.chooseDirAction) self.showOFBtn = QToolButton() self.showOFBtn.setDefaultAction(self.showOFAction) iconlayout = QHBoxLayout() iconlayout.setAlignment(Qt.AlignLeft) iconlayout.addWidget(self.chooseDirBtn) iconlayout.addWidget(self.showOFBtn) self.viewsSplitter = QSplitter(Qt.Horizontal) self.viewsSplitter.splitterMoved.connect(self.splitterMoved) self.dirsModel = QFileSystemModel(self) self.dirsModel.setOption(QFileSystemModel.DontWatchForChanges, True) self.dirsModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.dirsModel.setNameFilterDisables(False) self.dirs = QTreeView() self.dirs.setModel(self.dirsModel) self.dirs.hideColumn(1) self.dirs.hideColumn(2) self.dirs.hideColumn(3) self.dirs.clicked.connect(self.onDirsClick) self.dirs.doubleClicked.connect(self.onDirsDoubleClick) self.filesModel = QFileSystemModel(self) self.filesModel.setOption(QFileSystemModel.DontWatchForChanges, True) self.filesModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) self.filesModel.setNameFilterDisables(False) self.files = QListView() self.files.setModel(self.filesModel) self.files.doubleClicked.connect(self.onFilesDoubleClick) self.viewsSplitter.addWidget(self.dirs) self.viewsSplitter.addWidget(self.files) viewslayout = QHBoxLayout() viewslayout.addWidget(self.viewsSplitter) layout = QVBoxLayout() layout.addLayout(iconlayout) layout.addLayout(viewslayout) self.setLayout(layout) self.dirsModel.setRootPath(self.currentRootPath) self.dirs.setRootIndex(self.dirsModel.index(self.currentRootPath)) index = self.dirsModel.index(self.currentPath) self.dirs.setCurrentIndex(index) self.dirs.setExpanded(index, True) self.filesModel.setRootPath(self.currentPath) self.files.setRootIndex(self.filesModel.index(self.currentPath)) def splitterMoved(self, pos, index): if pos == 0: self.filesModel.setFilter(QDir.NoDot | QDir.AllEntries | QDir.DirsFirst | QDir.Type) elif pos == self.viewsSplitter.width( ) - self.viewsSplitter.handleWidth(): self.dirsModel.setFilter(QDir.NoDotAndDotDot | QDir.AllEntries) else: self.dirsModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) self.filesModel.setFilter(QDir.NoDotAndDotDot | QDir.Files) def onDirsClick(self, item): index = self.dirs.selectedIndexes()[0] info = self.dirsModel.fileInfo(index) if info.isDir(): self.currentPath = info.filePath() self.files.setRootIndex( self.filesModel.setRootPath(info.filePath())) def onDirsDoubleClick(self, item): index = self.dirs.selectedIndexes()[0] info = self.dirsModel.fileInfo(index) if info.isDir(): self.currentPath = info.filePath() self.files.setRootIndex( self.filesModel.setRootPath(info.filePath())) else: self.mainWindow.open_fits(info.filePath()) def onFilesDoubleClick(self, item): index = self.files.selectedIndexes()[0] info = self.filesModel.fileInfo(index) if info.isDir(): self.setPath(info.filePath()) else: try: self.mainWindow.open_fits(info.filePath()) except FileNotFoundError: self.setPath(self.currentPath) # refesh maybe? def setPath(self, path): self.currentPath = path index = self.dirsModel.index(self.currentPath) self.dirs.setCurrentIndex(index) self.dirs.setExpanded(index, True) self.files.setRootIndex(self.filesModel.setRootPath(self.currentPath)) def chooseRootDir(self): dir = QFileDialog.getExistingDirectory(self, 'Select directory') if dir: self.setRootPath(dir) def setRootPath(self, dir): self.currentRootPath = dir self.dirsModel.setRootPath(self.currentRootPath) self.dirs.setRootIndex(self.dirsModel.index(self.currentRootPath)) self.setPath(self.currentRootPath) def showOFFiles(self): if self.showOFAction.isChecked(): self.dirsModel.setNameFilters(["*.FITS", "*.fits"]) self.filesModel.setNameFilters(["*.FITS", "*.fits"]) else: self.dirsModel.setNameFilters(["*"]) self.filesModel.setNameFilters(["*"]) def writeSettings(self, settings): settings.beginGroup("fileWidget") settings.setValue('splitterGeometry', self.viewsSplitter.saveGeometry()) settings.setValue('splitterState', self.viewsSplitter.saveState()) settings.setValue('rootPath', self.currentRootPath) settings.setValue('path', self.currentPath) settings.endGroup() def readSettings(self, settings): settings.beginGroup("fileWidget") self.viewsSplitter.restoreGeometry(settings.value("splitterGeometry")) self.viewsSplitter.restoreState(settings.value("splitterState")) rootPath = settings.value("rootPath") path = settings.value("path") settings.endGroup() if rootPath is None: rootPath = '/' self.setRootPath(rootPath) if path is None: path = QDir.currentPath() self.setPath(path) self.splitterMoved(self.viewsSplitter.handle(1).pos().x(), 0)