class DialogSaveFiles(QDialog): def __init__(self, files, editor_container, parent): QDialog.__init__(self, parent) self.setWindowTitle(self.tr("Archivos no guardados!")) self._event_ignore = False self._editor_container = editor_container vLayout = QVBoxLayout(self) label = QLabel(self.tr("Los siguientes archivos se han modificado. " "Guardarlos?")) vLayout.addWidget(label) self.list_widget = QListWidget() self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) for e, _file in enumerate(files): if not _file: _file = "Untitled" self.list_widget.addItem(_file) self.list_widget.item(e).setSelected(True) vLayout.addWidget(self.list_widget) box_buttons = QHBoxLayout() btn_nothing = QPushButton(self.tr("Ninguno")) btn_save = QPushButton(self.tr("Guardar Selección")) btn_cancel = QPushButton(self.tr("Cancelar")) box_buttons.addWidget(btn_nothing) box_buttons.addWidget(btn_save) box_buttons.addWidget(btn_cancel) vLayout.addLayout(box_buttons) self.key_scape = QShortcut(QKeySequence(Qt.Key_Escape), self) # Conexiones self.connect(self.key_scape, SIGNAL("activated()"), self._ignore) self.connect(btn_nothing, SIGNAL("clicked()"), self.close) self.connect(btn_save, SIGNAL("clicked()"), self._save) self.connect(btn_cancel, SIGNAL("clicked()"), self._ignore) def _ignore(self): self._event_ignore = True self.hide() def ignorado(self): return self._event_ignore def _save(self): selected_files = self.list_widget.selectedItems() for _file in selected_files: filename = _file.text() self._editor_container.save_selected(filename) self.close()
class VariableListBox(QWidget): def __init__(self, id, text, sep=","): QWidget.__init__(self) self.widget = QListWidget() self.widget.setToolTip(text) self.widget.setSelectionMode(QAbstractItemView.ExtendedSelection) label = QLabel(text) label.setBuddy(self.widget) vbox = VBoxLayout() vbox.addWidget(label) vbox.addWidget(self.widget) self.setLayout(vbox) self.id = id self.sep = sep def parameterValues(self): self.widget.selectAll() items = self.widget.selectedItems() first = True var = QString() for item in items: if first: var.append(item.text()) first = False else: var.append("%s%s" % (self.sep, item.text())) if var.isEmpty(): raise Exception("Error: Insufficient number of input variables") params = {self.id:var} return params
def __init__(self, opPixelClassification, parent): super(QDialog, self).__init__(parent=parent) self._op = opPixelClassification classifier_listwidget = QListWidget(parent=self) classifier_listwidget.setSelectionMode(QListWidget.SingleSelection) classifer_factories = self._get_available_classifier_factories() for name, classifier_factory in classifer_factories.items(): item = QListWidgetItem(name) item.setData(Qt.UserRole, QVariant(classifier_factory)) classifier_listwidget.addItem(item) buttonbox = QDialogButtonBox(Qt.Horizontal, parent=self) buttonbox.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonbox.accepted.connect(self.accept) buttonbox.rejected.connect(self.reject) layout = QVBoxLayout() layout.addWidget(classifier_listwidget) layout.addWidget(buttonbox) self.setLayout(layout) self.setWindowTitle("Select Classifier Type") # Save members self._classifier_listwidget = classifier_listwidget
def __init__(self, opPixelClassification, parent): super( QDialog, self ).__init__(parent=parent) self._op = opPixelClassification classifier_listwidget = QListWidget(parent=self) classifier_listwidget.setSelectionMode( QListWidget.SingleSelection ) classifier_factories = self._get_available_classifier_factories() for name, classifier_factory in classifier_factories.items(): item = QListWidgetItem( name ) item.setData( Qt.UserRole, QVariant(classifier_factory) ) classifier_listwidget.addItem(item) buttonbox = QDialogButtonBox( Qt.Horizontal, parent=self ) buttonbox.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel ) buttonbox.accepted.connect( self.accept ) buttonbox.rejected.connect( self.reject ) layout = QVBoxLayout() layout.addWidget( classifier_listwidget ) layout.addWidget( buttonbox ) self.setLayout(layout) self.setWindowTitle( "Select Classifier Type" ) # Save members self._classifier_listwidget = classifier_listwidget
class MergeDialog(QDialog): def __init__(self, track_panels, parent = None): QDialog.__init__(self, parent) self.track_panels = track_panels self.layout = QVBoxLayout(self) self.list = QListWidget(self) self.list.setSelectionMode(QAbstractItemView.MultiSelection) for tv in track_panels: name = tv.curve_source.name() self.list.addItem(QListWidgetItem(name, self.list)) self.ok_button = QPushButton("ok", self) minimum_size_policy(self.ok_button) QWidget.connect(self.ok_button, SIGNAL("clicked()"), self.accept) self.list.updateGeometry() self.layout.addWidget(self.list) self.layout.addWidget(self.ok_button) self.updateGeometry() self.adjustSize() def selected_track_panels(self): selected = self.list.selectedItems() names = [s.text() for s in selected] return [tv for tv in self.track_panels if tv.curve_source.name() in names]
class SnappingDock(DockWidget): def __init__(self, iface, parent=None): super(SnappingDock, self).__init__(parent) self._iface = iface self.setWindowTitle(u'Snapping Panel') self.setObjectName(u'snappingDock') self._listWidget = QListWidget(self) self._listWidget.setSelectionMode(QAbstractItemView.NoSelection) self._listWidget.setDropIndicatorShown(False) self._dockLayout = QVBoxLayout(self) self._dockLayout.setObjectName(u'dockLayout') self._dockLayout.addWidget(self._listWidget) self._dockContents = QWidget(self) self._dockContents.setObjectName(u'dockContents') self._dockContents.setLayout(self._dockLayout) self.setWidget(self._dockContents) # Keep up-to-date with layers added and removed QgsMapLayerRegistry.instance().layersAdded.connect(self._layersAdded) QgsMapLayerRegistry.instance().layersRemoved.connect( self._layersRemoved) def refresh(self): self._listWidget.clear() layers = QgsMapLayerRegistry.instance().mapLayers() layerIds = layers.keys() sorted(layerIds) for layerId in layerIds: self.addLayer(layers[layerId]) def addLayer(self, layer): if (layer is None or not layer.isValid() or layer.type() != QgsMapLayer.VectorLayer): return newItem = QListWidgetItem() newItem.setData(Qt.UserRole, layer.id()) # newItem.setSizeHint(layerWidget.minimumSizeHint()) self._listWidget.addItem(newItem) self._listWidget.setItemWidget(newItem, LayerSnappingWidget(layer, self)) def removeLayer(self, layerId): for idx in range(0, self._listWidget.count() - 1): if self._listWidget.item(idx).data() == layerId: self._listWidget.takeItem(idx) return def _layersAdded(self, layers): for layer in layers: self.addLayer(layer) def _layersRemoved(self, layerIds): for idx in range(self._listWidget.count() - 1, 0): if self._listWidget.item(idx).data() in layerIds: self._listWidget.takeItem(idx)
class SnappingDock(DockWidget): def __init__(self, iface, parent=None): super(SnappingDock, self).__init__(parent) self._iface = iface self.setWindowTitle(u'Snapping Panel') self.setObjectName(u'snappingDock') self._listWidget = QListWidget(self) self._listWidget.setSelectionMode(QAbstractItemView.NoSelection) self._listWidget.setDropIndicatorShown(False) self._dockLayout = QVBoxLayout(self) self._dockLayout.setObjectName(u'dockLayout') self._dockLayout.addWidget(self._listWidget) self._dockContents = QWidget(self) self._dockContents.setObjectName(u'dockContents') self._dockContents.setLayout(self._dockLayout) self.setWidget(self._dockContents) # Keep up-to-date with layers added and removed QgsMapLayerRegistry.instance().layersAdded.connect(self._layersAdded) QgsMapLayerRegistry.instance().layersRemoved.connect(self._layersRemoved) def refresh(self): self._listWidget.clear() layers = QgsMapLayerRegistry.instance().mapLayers() layerIds = layers.keys() sorted(layerIds) for layerId in layerIds: self.addLayer(layers[layerId]) def addLayer(self, layer): if (layer is None or not layer.isValid() or layer.type() != QgsMapLayer.VectorLayer): return newItem = QListWidgetItem() newItem.setData(Qt.UserRole, layer.id()) # newItem.setSizeHint(layerWidget.minimumSizeHint()) self._listWidget.addItem(newItem) self._listWidget.setItemWidget(newItem, LayerSnappingWidget(layer, self)) def removeLayer(self, layerId): for idx in range(0, self._listWidget.count() - 1): if self._listWidget.item(idx).data() == layerId: self._listWidget.takeItem(idx) return def _layersAdded(self, layers): for layer in layers: self.addLayer(layer) def _layersRemoved(self, layerIds): for idx in range(self._listWidget.count() - 1, 0): if self._listWidget.item(idx).data() in layerIds: self._listWidget.takeItem(idx)
class CaseList(QWidget): def __init__(self): QWidget.__init__(self) addHelpToWidget(self, "init/case_list") layout = QVBoxLayout() self._list = QListWidget(self) self._list.setMinimumHeight(100) self._list.setMaximumHeight(250) self._default_selection_mode = self._list.selectionMode() self.setSelectable(False) layout.addWidget(QLabel("Available Cases:")) layout.addWidget(self._list) self._addRemoveWidget = AddRemoveWidget(self.addItem, self.removeItem, horizontal=True) self._addRemoveWidget.enableRemoveButton(False) layout.addWidget(self._addRemoveWidget) self._title = "New keyword" self._description = "Enter name of keyword:" self.setLayout(layout) ERT.ertChanged.connect(self.updateList) self.updateList() def setSelectable(self, selectable): if selectable: self._list.setSelectionMode(self._default_selection_mode) else: self._list.setSelectionMode(QAbstractItemView.NoSelection) def addItem(self): dialog = ValidatedDialog("New case", "Enter name of new case:", getAllCases()) new_case_name = dialog.showAndTell() if not new_case_name == "": selectOrCreateNewCase(new_case_name) def removeItem(self): message = "Support for removal of items has not been implemented!" QMessageBox.information(self, "Not implemented!", message) def updateList(self): """Retrieves data from the model and inserts it into the list""" case_list = getAllCases() self._list.clear() for case in case_list: self._list.addItem(case)
class ResultDialog(QDialog): def __init__(self, result, parent): super(QDialog, self).__init__(parent) self.list = QListWidget(self) self.list.setSelectionMode(QListWidget.NoSelection) self.buttons = QDialogButtonBox(QDialogButtonBox.Ok) self.buttons.accepted.connect(self.accept) self.setWindowTitle('Result') self.resize(380, 200) self._insertResult(result) self._createLayout() def _insertResult(self, result): for track, res in result: item = QListWidgetItem() item.setText('{0} - {1}'.format(track[0]['name'], res['msg'])) if res['status'] == 'OK': # item.setBackground(Qt.green) pass elif res['status'] == 'ERROR': item.setForeground(Qt.red) self.list.addItem(item) def _createLayout(self): l = QVBoxLayout() l.addWidget(self.list) l.addWidget(self.buttons) self.setLayout(l)
class CustomFieldsEditor(QDialog): def __init__(self, parent, fields): QDialog.__init__(self, parent) layout = QVBoxLayout(self) self._list_elements = QListWidget(self) self._fields = dict(fields) for field, ftype in fields.items(): self._list_elements.addItem(field + ' (' + ftype + ')') self._list_elements.setSelectionMode( QAbstractItemView.ExtendedSelection) layout.addWidget(self._list_elements) add_remove = AddRemoveButtonBar(self, 'Remove selected field(s)', self.remove, 'Add field', self.add) layout.addWidget(add_remove) buttons = QWidget(self) buttons_layout = QHBoxLayout() buttons.setLayout(buttons_layout) buttons_layout.addStretch() ok_button = QPushButton("Ok") cancel_button = QPushButton("Cancel") ok_button.clicked.connect(self.accept) cancel_button.clicked.connect(self.reject) buttons_layout.addWidget(ok_button) buttons_layout.addWidget(cancel_button) layout.addWidget(buttons) self.setLayout(layout) def remove(self): res = [] for item in self._list_elements.selectedItems(): del self._fields[str(item.text()).split(' ')[0]] res.append(self._list_elements.row(item)) for row in sorted(res, key=lambda x: -x): self._list_elements.takeItem(row) def add(self): dialog = AddFieldDialog(self) if dialog.exec_(): self._fields[str(dialog.name)] = dialog.ftype self._list_elements.addItem(dialog.name + ' (' + dialog.ftype + ')') def get_fields(self): return self._fields
class RMirrorBrowser(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) kwargs = {"local.only":False} m = robjects.r.getCRANmirrors(all=False, **kwargs) names = QStringList(list(m.rx('Name')[0])) urls = list(m.rx('URL')[0]) self.links = dict(zip(names, urls)) names = QStringList(names) self.setWindowTitle("manageR - Choose CRAN Mirror") self.setWindowIcon(QIcon(":icon")) self.links = dict(zip(names, urls)) self.currentMirror = None self.mirrorList = QListWidget(self) self.mirrorList.setAlternatingRowColors(True) self.mirrorList.setEditTriggers(QAbstractItemView.NoEditTriggers) self.mirrorList.setSortingEnabled(True) self.mirrorList.setSelectionMode(QAbstractItemView.SingleSelection) self.mirrorList.setToolTip("Double-click to select mirror location") self.mirrorList.setWhatsThis("List of CRAN mirrors") self.mirrorList.insertItems(0, names) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) vbox = QVBoxLayout(self) vbox.addWidget(self.mirrorList) vbox.addWidget(buttonBox) self.connect(buttonBox, SIGNAL("accepted()"), self.accept) self.connect(buttonBox, SIGNAL("rejected()"), self.reject) self.connect(self.mirrorList, SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self.accept) def currentMirror(self): return robjects.r("getOption('repos')")[0] def setCurrentMirror(self, mirror): robjects.r("options('repos'='%s')" % mirror) def accept(self): items = self.mirrorList.selectedItems() if len(items) > 0: name = items[0].text() url = self.links[name] self.setCurrentMirror(url) QDialog.accept(self) else: QMessageBox.warning(self, "manageR - Warning", "Please choose a valid CRAN mirror")
class PythonDetectDialog(QDialog): def __init__(self, suggested, parent=None): super(PythonDetectDialog, self).__init__(parent, Qt.Dialog) self.setMaximumSize(QSize(0, 0)) self.setWindowTitle("Configure Python Path") vbox = QVBoxLayout(self) msg_str = ("We have detected that you are using " "Windows,\nplease choose the proper " "Python application for you:") lblMessage = QLabel(self.tr(msg_str)) vbox.addWidget(lblMessage) self.listPaths = QListWidget() self.listPaths.setSelectionMode(QListWidget.SingleSelection) vbox.addWidget(self.listPaths) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) btnCancel = QPushButton(self.tr("Cancel")) btnAccept = QPushButton(self.tr("Accept")) hbox.addWidget(btnCancel) hbox.addWidget(btnAccept) vbox.addLayout(hbox) self.connect(btnAccept, SIGNAL("clicked()"), self._set_python_path) self.connect(btnCancel, SIGNAL("clicked()"), self.close) for path in suggested: self.listPaths.addItem(path) self.listPaths.setCurrentRow(0) def _set_python_path(self): python_path = self.listPaths.currentItem().text() qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) settings.PYTHON_PATH = python_path settings.PYTHON_EXEC = python_path settings.PYTHON_EXEC_CONFIGURED_BY_USER = True qsettings.setValue('preferences/execution/pythonExec', python_path) qsettings.setValue('preferences/execution/pythonExecConfigured', True) self.close()
class PythonDetectDialog(QDialog): def __init__(self, suggested, parent=None): super(PythonDetectDialog, self).__init__(parent, Qt.Dialog) self.setMaximumSize(QSize(0, 0)) self.setWindowTitle("Configure Python Path") vbox = QVBoxLayout(self) lblMessage = QLabel(self.tr("We have detected that you are using " + "Windows,\nplease choose the proper " + "Python application for you:")) vbox.addWidget(lblMessage) self.listPaths = QListWidget() self.listPaths.setSelectionMode(QListWidget.SingleSelection) vbox.addWidget(self.listPaths) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) btnCancel = QPushButton(self.tr("Cancel")) btnAccept = QPushButton(self.tr("Accept")) hbox.addWidget(btnCancel) hbox.addWidget(btnAccept) vbox.addLayout(hbox) self.connect(btnAccept, SIGNAL("clicked()"), self._set_python_path) self.connect(btnCancel, SIGNAL("clicked()"), self.close) for path in suggested: self.listPaths.addItem(path) self.listPaths.setCurrentRow(0) def _set_python_path(self): python_path = self.listPaths.currentItem().text() qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) settings.PYTHON_PATH = python_path settings.PYTHON_EXEC = python_path settings.PYTHON_EXEC_CONFIGURED_BY_USER = True qsettings.setValue('preferences/execution/pythonPath', python_path) qsettings.setValue('preferences/execution/pythonPathConfigured', True) self.close()
class MultipleChoiceDialog(QDialog): def __init__(self, parent, title, text, items): QDialog.__init__(self, parent) self.setWindowTitle(title) self.layout = QVBoxLayout() label = QLabel(text) self.layout.addWidget(label) self.listwidget = QListWidget(self) self.listwidget.setSelectionMode(QAbstractItemView.ExtendedSelection) for item in items: self.listwidget.addItem(item) self.layout.addWidget(self.listwidget) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) self.layout.addWidget(buttonBox) self.setLayout(self.layout) def selectedItems(self): return self.listwidget.selectedItems()
def add_slice(self, param=[]): """Add a row to the slice table and append it to the daqCollection instance for analysis. param -- [name, start (ms), end (ms), channels]""" try: name, start, end, channels = param except TypeError: name = 'Slice' + str(self.slices.rowCount()) start = 0 end = self.stats['Duration (ms)'] channels = list(self.stats['channels'].keys()) i = self.slices.rowCount() # index to add row at self.slices.insertRow(i) # add row to table validator = QDoubleValidator(0., float(self.stats['Duration (ms)']), 3) for j, text in enumerate([name, str(start), str(end)]): item = QLineEdit(text) item.pos = (i, j) if j > 0: item.setValidator(validator) item.textChanged.connect(self.update_slices) self.slices.setCellWidget(i, j, item) chanbox = QListWidget(self) chanbox.setSelectionMode( 3) # extended selection, allows multiple selection chanbox.itemSelectionChanged.connect(self.update_slices) chanbox.pos = (i, 3) chanbox.text = chanbox.objectName chanlist = list(self.stats['channels'].keys()) chanbox.addItems(chanlist) self.slices.setCellWidget(i, j + 1, chanbox) self.slices.resizeRowToContents(i) # add to the dc list of slices t = np.linspace(0, self.stats['Duration (ms)'] / 1000, self.n_samples) self.dc.add_slice( name, np.argmin(np.abs(t - start)), np.argmin(np.abs(t - end)), OrderedDict([(chan, chanlist.index(chan)) for chan in channels])) self.reset_lines()
class RRepositoryBrowser(QDialog): def __init__(self, pipe, parent=None): QDialog.__init__(self, parent) mirror = robjects.r.getOption('repos') contrib_url = robjects.r.get('contrib.url', mode='function') available_packages = robjects.r.get('available.packages', mode='function') self.setWindowTitle("manageR - Install R Packages") self.setWindowIcon(QIcon(":icon")) p = available_packages() self.pipe = pipe self.names = QStringList(p.rownames) self.parent = parent self.packageList = QListWidget(self) self.packageList.setAlternatingRowColors(True) self.packageList.setEditTriggers(QAbstractItemView.NoEditTriggers) self.packageList.setSortingEnabled(True) self.packageList.setSelectionMode(QAbstractItemView.ExtendedSelection) self.packageList.setToolTip("Select packages to install") self.packageList.setWhatsThis("List of packages available on CRAN") self.packageList.insertItems(0, self.names) self.dependCheckbox = QCheckBox(self) self.dependCheckbox.setText("Install all dependencies") self.dependCheckbox.setChecked(True) self.closeCheckbox = QCheckBox(self) self.closeCheckbox.setText("Close dialog on completion") self.closeCheckbox.setChecked(False) filterEdit = QLineEdit(self) filterLabel = QLabel("Filter packages", self) self.outputEdit = QTextEdit(self) self.outputEdit.setReadOnly(True) self.outputEdit.setVisible(False) self.buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Close) self.buttonBox.addButton("Details >>", QDialogButtonBox.ActionRole) vbox = QVBoxLayout(self) hbox = QHBoxLayout() hbox.addWidget(filterLabel) hbox.addWidget(filterEdit) vbox.addLayout(hbox) vbox.addWidget(self.dependCheckbox) vbox.addWidget(self.packageList) vbox.addWidget(self.closeCheckbox) vbox.addWidget(self.outputEdit) vbox.addWidget(self.buttonBox) self.started = False self.setMinimumSize(80,50) self.connect(filterEdit, SIGNAL("textChanged(QString)"), self.filterPackages) #self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject) self.connect(self.buttonBox, SIGNAL("clicked(QAbstractButton*)"), self.buttonClicked) def buttonClicked(self, button): if button.text() == "Details >>": self.showDetails() button.setText("Details <<") elif button.text() == "Details <<": self.hideDetails() button.setText("Details >>") if not self.started: if self.buttonBox.standardButton(button) == QDialogButtonBox.Apply: self.installPackages() else: self.reject() def showDetails(self): self.outputEdit.setVisible(True) def hideDetails(self): self.outputEdit.setVisible(False) def filterPackages(self, text): self.packageList.clear() self.packageList.insertItems(0, self.names.filter(QRegExp(r"^%s" % text))) firstItem = self.packageList.item(0) if firstItem.text().startsWith(text): self.packageList.setCurrentItem(firstItem) # else: # self.packageList.clearSelection() def currentPackages(self): return [unicode(item.text()) for item in self.packageList.selectedItems()] def installPackages(self): pkgs = self.currentPackages() count = len(pkgs) if count < 1: QMessageBox.warning(self, "manageR - Warning", "Please choose at least one valid package") return False pkgs = QStringList(pkgs).join("','") checked = self.dependCheckbox.isChecked() if checked: depends = "TRUE" else: depends = "FALSE" self.pipe.send("install.packages(c('%s'), dependencies=%s, repos=%s)" % (pkgs, depends, robjects.r.getOption("repos"))) self.started = True self.startTimer(30) return True def timerEvent(self, e): if self.started: try: output = self.pipe.recv() if output is None: self.started=False self.killTimer(e.timerId()) else: self.printOutput(output) except EOFError: pass QApplication.processEvents() def printOutput(self, output): self.outputEdit.insertPlainText(output) self.outputEdit.ensureCursorVisible()
class MultipleFilesWidget(QWidget): """Widget that allows the selection of multiple files.""" def __init__(self, title, file_name_filter='', check_file_function=None): """Creates a new widget for selecting multiple files. - `title`: title of the file selection dialog that is opened when the user clicks on 'Add File'. - `file_name_filter`: filter to use for the selection of files (See the documentation of QFileDialog). - `check_file_function`: function that receives a file name and returns True if its contents are correct. If None, files are not checked. An error dialog is shown for the files that are not correct. The rest are just added. """ super(MultipleFilesWidget, self).__init__() self.title = title self.file_name_filter = file_name_filter self._check_file = check_file_function self.file_list = QListWidget() self.file_list.setSelectionMode(QAbstractItemView.ExtendedSelection) button_add = QPushButton(_('Add files')) self.button_remove = QPushButton(_('Remove selected')) self.button_remove.setEnabled(False) buttons = QWidget() buttons_layout = QVBoxLayout() buttons_layout.setAlignment(Qt.AlignTop) buttons.setLayout(buttons_layout) buttons_layout.addWidget(button_add) buttons_layout.addWidget(self.button_remove) main_layout = QHBoxLayout() self.setLayout(main_layout) main_layout.addWidget(self.file_list) main_layout.addWidget(buttons) button_add.clicked.connect(self._add_files) self.button_remove.clicked.connect(self._remove_files) self.file_list.selectionModel().selectionChanged.connect( \ self._selection_changed) def get_files(self): """Returns the list of selected file names.""" files = [] model = self.file_list.model() count = model.rowCount() for i in range(0, count): index = model.index(i, 0) files.append(unicode(model.data(index).toString())) return files def _add_files(self): file_list_q = QFileDialog.getOpenFileNames( self, self.title, '', self.file_name_filter, None, QFileDialog.DontUseNativeDialog) model = self.file_list.model() for file_name in file_list_q: valid = True if self._check_file is not None: valid, msg = self._check_file(unicode(file_name)) if valid: # Check if the file is already in the list: match = model.match(model.index(0, 0), 0, file_name, 1, Qt.MatchExactly) if len(match) == 0: self.file_list.addItem(file_name) def _remove_files(self): ranges = self.file_list.selectionModel().selection() model = self.file_list.model() to_remove = [] for r in ranges: to_remove.extend(range(r.top(), r.bottom() + 1)) for row in sorted(to_remove, reverse=True): model.removeRow(row) def _selection_changed(self, deselected, selected): if len(self.file_list.selectionModel().selection()) > 0: self.button_remove.setEnabled(True) else: self.button_remove.setEnabled(False)
class mainwindow(QtGui.QMainWindow): '''主窗体''' def __init__(self): super(mainwindow,self).__init__() self.setWindowTitle('组件设计工具') self.showMaximized() self.menuBar().show() self.createMenus() cwHLayout = QHBoxLayout() lLayout = QVBoxLayout() rLayout = QVBoxLayout() self.lw = QListWidget() self.lw.setSelectionMode(QAbstractItemView.SingleSelection ) lLayout.addWidget(self.lw) self.lw.itemSelectionChanged.connect(self.on_select) lGroup = QGroupBox('项目列表') lGroup.setLayout(lLayout) cwHLayout.addWidget(lGroup,2) cwHLayout.addLayout(rLayout,8) tLayout = QVBoxLayout() bLayout = QVBoxLayout() tGroup = QGroupBox('配置信息') self.bGroup = QGroupBox('生成代码') tGroup.setLayout(tLayout) self.bGroup.setLayout(bLayout) self.bGroup.setEnabled(False) rLayout.addWidget(tGroup) rLayout.addWidget(self.bGroup) self.tw_config = QTreeWidget() headerLabels = QStringList() headerLabels.append('项目') headerLabels.append('值') self.tw_config.setHeaderLabels(headerLabels) thLayout = QHBoxLayout() thLayout.addStretch(0) modify_btn = QPushButton('修改') modify_btn.clicked.connect(self.on_modify) del_btn = QPushButton('删除') del_btn.clicked.connect(self.on_del) thLayout.addWidget(modify_btn) thLayout.addWidget(del_btn) tLayout.addWidget(self.tw_config) tLayout.addLayout(thLayout) bhLayout = QHBoxLayout() bhLayout.addStretch(0) gen_btn = QPushButton('生成') gen_btn.clicked.connect(self.on_gen) bhLayout.addWidget(gen_btn) row1 = QHBoxLayout() lable1 = QLabel('工程名称:') self.et_project_name = QLineEdit() row1.addSpacing(10) row1.addWidget(lable1) row1.addWidget(self.et_project_name) row1.addStretch(0) row2 = QHBoxLayout() lable2 = QLabel('工程位置:') self.et_project_location = QLineEdit() self.et_project_location.setReadOnly(True) btn_location = QPushButton('...') btn_location.setFixedWidth(50) btn_location.clicked.connect(self.getProjectLocation) row2.addSpacing(10) row2.addWidget(lable2) row2.addWidget(self.et_project_location) row2.addWidget(btn_location) row2.addStretch(0) bLayout.addLayout(row1) bLayout.addLayout(row2) bLayout.addLayout(bhLayout) cw = QWidget() cw.setLayout(cwHLayout) self.setCentralWidget(cw) self._initByConfig() self.setMinimumSize(400,200) def _initByConfig(self): '''初始化''' pass def createMenus(self): '''创建菜单''' menueBar = self.menuBar() menuSys = menueBar.addMenu('系统') actNew = menuSys.addAction('新建工程') actOpen = menuSys.addAction('打开工程') actNew.triggered.connect(self.on_new) actOpen.triggered.connect(self.on_open) menueBar.addMenu(menuSys) def on_new(self): '''新建向导''' app.g_configurations = Configuration() # 用来渲染的配置数据 dlg = wizard.MyWizard() if dlg.exec_(): app.g_configurations.initialized = True app.g_projects.append(app.g_configurations) content = app.g_configurations.toJson() path = QFileDialog.getSaveFileName(self,"选择模板保存的路径", app.g_pwd + os.sep + "configurations" + os.sep + app.g_configurations.project_name + ".json" ,"Config (*.json)") if not path.isEmpty(): path = app.QString2str(path) with open(path,'w+') as f: f.write(content) self.lw.addItem(app.g_configurations.project_name) def getProjectLocation(self): '''获取项目路径''' path = QFileDialog.getExistingDirectory() path = QDir.fromNativeSeparators(path) self.et_project_location.setText(path) def on_open(self): '''打开现有配置''' fileName = QFileDialog.getOpenFileName(self,"选择现有模板",app.g_pwd + os.sep + "configurations","Config (*.json)") if fileName.isEmpty(): return with open(app.QString2str(fileName), 'r') as f: content = f.read() config = Configuration() config.fromJson(content) app.g_projects.append(config) self.lw.addItem(config.project_name) def on_del(self): index = self.lw.currentRow() if index < app.g_projects: self.bGroup.setEnabled(False) self.lw.takeItem(index) config = app.g_projects[index] app.g_projects.remove(config) self.tw_config.clear() return def on_select(self): '''选取配置''' index = self.lw.currentRow() if index < app.g_projects: self.bGroup.setEnabled(True) self.currentConfig = app.g_projects[index] self.showConfigInfo(self.currentConfig) def showConfigInfo(self,cf): '''显示配置信息''' self.tw_config.clear() self.et_project_name.setText(cf.project_name) self.et_project_location.setText(cf.project_location) sr = QStringList() sr.append('信息') root1 = QTreeWidgetItem(sr) sr = QStringList() sr.append('Qt库') root2 = QTreeWidgetItem(sr) sr = QStringList() sr.append('模块') root3 = QTreeWidgetItem(sr) sr = QStringList() sr.append('接口') root4 = QTreeWidgetItem(sr) self.tw_config.addTopLevelItem(root1) self.tw_config.addTopLevelItem(root2) self.tw_config.addTopLevelItem(root3) self.tw_config.addTopLevelItem(root4) sr1c00 = QStringList() sr1c00.append("项目名称") sr1c00.append(cf.project_name) r1c00 = QTreeWidgetItem(sr1c00) root1.addChild(r1c00) # sr1c0 = QStringList() # sr1c0.append("项目位置") # sr1c0.append(cf.project_location) # r1c0 = QTreeWidgetItem(sr1c0) # root1.addChild(r1c0) sr1c1 = QStringList() sr1c1.append("组件类型") sr1c1.append(cf.component_type) r1c1 = QTreeWidgetItem(sr1c1) root1.addChild(r1c1) sr1c2 = QStringList() sr1c2.append("源模板") sr1c2.append(cf.template_source) r1c2 = QTreeWidgetItem(sr1c2) root1.addChild(r1c2) sr1c3 = QStringList() sr1c3.append("平台类型") tmp_pt = "" if cf.platform_type & configuration.PT_WIN32: tmp_pt += "win32;" if cf.platform_type & configuration.PT_LINUX: tmp_pt += "linux" sr1c3.append(tmp_pt) r1c3 = QTreeWidgetItem(sr1c3) root1.addChild(r1c3) sr1c4 = QStringList() sr1c4.append("平台级别") sr1c4.append(cf.platform_version) r1c4 = QTreeWidgetItem(sr1c4) root1.addChild(r1c4) for qt in cf.qt_libs: sr2 = QStringList() sr2.append(qt['name']) sr2.append(qt['qt']) r2 = QTreeWidgetItem(sr2) root2.addChild(r2) for module in cf.modules: sr3 = QStringList() sr3.append(module['name']) sr3.append(module['description']) r3 = QTreeWidgetItem(sr3) root3.addChild(r3) for key in cf.interfaces.keys(): sr4 = QStringList() sr4.append(key) if cf.interfaces[key]: sr4.append('实现') else: sr4.append('未实现') r4 = QTreeWidgetItem(sr4) root4.addChild(r4) self.tw_config.expandAll() self.tw_config.header().resizeSection(0,300) def on_modify(self): '''修改配置''' if self.currentConfig: app.g_configurations = copy.copy(self.currentConfig) dlg = wizard.MyWizard() if dlg.exec_(): index = self.lw.currentRow() if index < app.g_projects: self.currentConfig = app.g_configurations app.g_projects[index] = self.currentConfig self.showConfigInfo(self.currentConfig) def on_gen(self): '''生成工程''' if not self.currentConfig: return #获取工程名及有效路径 project_name = self.et_project_name.text() project_location = self.et_project_location.text() qdir = QDir(project_location) if not qdir.exists(): if not qdir.mkpath(project_location): QMessageBox.warning(self, '警告', '路径无效!') return project_location = qdir.absolutePath() if not project_location.endsWith('/') and not project_location.endsWith('\\'): project_location += os.sep if project_name.isEmpty() or project_location.isEmpty(): QMessageBox.warning(self, '警告', '项目名称或路径不能为空!') return self.currentConfig.project_name = app.QString2str(project_name) self.currentConfig.project_location = app.QString2str(project_location) template_name = self.currentConfig.template_source template_dir = app.g_pwd + os.sep + 'templates' + os.sep + template_name with open(template_dir + os.sep + 'config.json', 'r') as f: self.currentConfig.config_content = f.read() ret_json = app.render(self.currentConfig.config_content, config=self.currentConfig) self.currentConfig.config = json.loads(ret_json) for file in self.currentConfig.config['files']: sourcepath = template_dir + os.sep + file['source'] targetdir = self.currentConfig.project_location + self.currentConfig.project_name targetpath = targetdir + os.sep + file['target'] fi = QFileInfo(targetpath) qdir = fi.absoluteDir() if not qdir.exists(): qdir.mkpath(fi.absolutePath()) with open(sourcepath, 'r') as f: content = f.read() content = app.render(content, config=self.currentConfig) #渲染文件 with open(targetpath, 'w+') as f: f.write(content.encode('utf-8')) QMessageBox.information(self,'提示','生成成功!')
class Theme(QWidget): """Theme widget class.""" def __init__(self, parent): super(Theme, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) vbox.addWidget(QLabel(self.tr("<b>Select Theme:</b>"))) self.list_skins = QListWidget() self.list_skins.setSelectionMode(QListWidget.SingleSelection) vbox.addWidget(self.list_skins) self.btn_delete = QPushButton(self.tr("Delete Theme")) self.btn_preview = QPushButton(self.tr("Preview Theme")) self.btn_create = QPushButton(self.tr("Create Theme")) hbox = QHBoxLayout() hbox.addWidget(self.btn_delete) hbox.addSpacerItem(QSpacerItem(10, 0, QSizePolicy.Expanding, QSizePolicy.Fixed)) hbox.addWidget(self.btn_preview) hbox.addWidget(self.btn_create) vbox.addLayout(hbox) self._refresh_list() self.connect(self.btn_preview, SIGNAL("clicked()"), self.preview_theme) self.connect(self.btn_delete, SIGNAL("clicked()"), self.delete_theme) self.connect(self.btn_create, SIGNAL("clicked()"), self.create_theme) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def delete_theme(self): if self.list_skins.currentRow() != 0: file_name = ("%s.qss" % self.list_skins.currentItem().text()) qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD, file_name) file_manager.delete_file(qss_file) self._refresh_list() def create_theme(self): designer = preferences_theme_editor.ThemeEditor(self) designer.exec_() self._refresh_list() def showEvent(self, event): self._refresh_list() super(Theme, self).showEvent(event) def _refresh_list(self): self.list_skins.clear() self.list_skins.addItem("Default") files = [file_manager.get_file_name(filename) for filename in file_manager.get_files_from_folder( resources.NINJA_THEME_DOWNLOAD, "qss")] files.sort() self.list_skins.addItems(files) if settings.NINJA_SKIN in files: index = files.index(settings.NINJA_SKIN) self.list_skins.setCurrentRow(index + 1) else: self.list_skins.setCurrentRow(0) def save(self): qsettings = IDE.ninja_settings() settings.NINJA_SKIN = self.list_skins.currentItem().text() qsettings.setValue("preferences/theme/skin", settings.NINJA_SKIN) self.preview_theme() def preview_theme(self): if self.list_skins.currentRow() == 0: qss_file = resources.NINJA_THEME else: file_name = ("%s.qss" % self.list_skins.currentItem().text()) qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD, file_name) with open(qss_file) as f: qss = f.read() QApplication.instance().setStyleSheet(qss)
class GUI(object): def __init__(self, MainWindow): MainWindow.setObjectName("MainWindow") # Set size of window MainWindow.resize(800, 589) MainWindow.setFocusPolicy(QtCore.Qt.NoFocus) MainWindow.setWindowTitle("Text to Kill") self.centralwidget = QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.gridLayout = QGridLayout(self.centralwidget) self.gridLayout.setMargin(0) self.gridLayout.setObjectName("gridLayout") self.stackedWidget = QStackedWidget(self.centralwidget) self.stackedWidget.setEnabled(True) self.stackedWidget.setObjectName("stackedWidget") font = QFont() font.setFamily("Times New Roman") # Main menu page self.menuPage = QWidget() self.menuPage.setObjectName("menuPage") self.titleLabel = QLabel(self.menuPage) self.titleLabel.setGeometry(QtCore.QRect(250, 60, 300, 50)) font.setPointSize(45) self.titleLabel.setFont(font) self.titleLabel.setAlignment(QtCore.Qt.AlignCenter) self.titleLabel.setObjectName("titleLabel") self.titleLabel.setText("Text to Kill") self.subtitleLabel = QLabel(self.menuPage) self.subtitleLabel.setGeometry(QtCore.QRect(100, 140, 600, 40)) font.setPointSize(25) self.subtitleLabel.setFont(font) self.subtitleLabel.setAlignment(QtCore.Qt.AlignCenter) self.subtitleLabel.setObjectName("subtitleLabel") self.subtitleLabel.setText("The Murder Mystery Automation System") self.createButton = QPushButton(self.menuPage) self.createButton.setGeometry(QtCore.QRect(310, 260, 180, 60)) self.createButton.setObjectName("createButton") self.createButton.setText("Create Game") self.runButton = QPushButton(self.menuPage) self.runButton.setGeometry(QtCore.QRect(310, 350, 180, 60)) self.runButton.setObjectName("runButton") self.runButton.setText("Run Game") self.stackedWidget.addWidget(self.menuPage) # Create page self.createPage = QWidget() self.createPage.setObjectName("createPage") self.createTabWidget = QTabWidget(self.createPage) self.createTabWidget.setGeometry(QtCore.QRect(0, 0, 800, 600)) self.createTabWidget.setFocusPolicy(QtCore.Qt.NoFocus) self.createTabWidget.setObjectName("createTabWidget") # Create game tab self.createTab = QWidget() self.createTab.setObjectName("createTab") self.createDoneButton = QPushButton(self.createTab) self.createDoneButton.setGeometry(QtCore.QRect(580, 470, 180, 60)) self.createDoneButton.setObjectName("createDoneButton") self.createDoneButton.setText("Done") self.gameNameEdit = QLineEdit(self.createTab) self.gameNameEdit.setGeometry(QtCore.QRect(140, 20, 160, 30)) self.gameNameEdit.setObjectName("gameNameEdit") self.gameNameLabel = QLabel(self.createTab) self.gameNameLabel.setGeometry(QtCore.QRect(20, 25, 110, 20)) font.setPointSize(15) self.gameNameLabel.setFont(font) self.gameNameLabel.setAlignment(QtCore.Qt.AlignCenter) self.gameNameLabel.setObjectName("gameNameLabel") self.gameNameLabel.setText("Game name") self.line = QFrame(self.createTab) self.line.setGeometry(QtCore.QRect(20, 150, 311, 20)) self.line.setFrameShape(QFrame.HLine) self.line.setFrameShadow(QFrame.Sunken) self.line.setObjectName("line") self.addCharLabel = QLabel(self.createTab) self.addCharLabel.setGeometry(QtCore.QRect(20, 180, 160, 20)) font.setPointSize(20) self.addCharLabel.setFont(font) self.addCharLabel.setAlignment(QtCore.Qt.AlignCenter) self.addCharLabel.setObjectName("addCharLabel") self.addCharLabel.setText("Add Character") self.charNameLabel = QLabel(self.createTab) self.charNameLabel.setGeometry(QtCore.QRect(20, 230, 66, 20)) font.setPointSize(15) self.charNameLabel.setFont(font) self.charNameLabel.setAlignment(QtCore.Qt.AlignCenter) self.charNameLabel.setObjectName("charNameLabel") self.charNameLabel.setText("Name") self.charNameEdit = QLineEdit(self.createTab) self.charNameEdit.setGeometry(QtCore.QRect(140, 220, 160, 30)) self.charNameEdit.setObjectName("charNameEdit") self.charAbilScroll = QListWidget(self.createTab) self.charAbilScroll.setGeometry(QtCore.QRect(140, 260, 161, 51)) self.charAbilScroll.setObjectName("charAbilScroll") self.characterTable = QTableWidget(self.createTab) self.characterTable.setGeometry(QtCore.QRect(405, 20, 381, 401)) self.characterTable.setFocusPolicy(QtCore.Qt.NoFocus) self.characterTable.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) self.characterTable.setRowCount(1) self.characterTable.setColumnCount(2) self.characterTable.setObjectName("characterTable") self.characterTable.horizontalHeader().setVisible(False) self.characterTable.horizontalHeader().setCascadingSectionResizes(False) self.characterTable.horizontalHeader().setMinimumSectionSize(50) self.characterTable.horizontalHeader().setStretchLastSection(True) self.characterTable.verticalHeader().setVisible(False) self.characterTable.verticalHeader().setDefaultSectionSize(30) self.scrollArea = QListWidget(self.createTab) self.scrollArea.setGeometry(QtCore.QRect(140, 60, 161, 71)) self.scrollArea.setObjectName("scrollArea") self.scrollArea.setSelectionMode(3) self.createSaveButton = QPushButton(self.createTab) self.createSaveButton.setGeometry(QtCore.QRect(380, 470, 180, 60)) self.createSaveButton.setObjectName("createSaveButton") self.createSaveButton.setText("Save") self.charAbilitiesLabel = QLabel(self.createTab) self.charAbilitiesLabel.setGeometry(QtCore.QRect(30, 280, 71, 20)) font.setPointSize(15) self.charAbilitiesLabel.setFont(font) self.charAbilitiesLabel.setObjectName("charAbilitiesLabel") self.charAbilitiesLabel.setText("Abilities") self.abilitiesDropdown = QComboBox(self.createTab) self.abilitiesDropdown.setGeometry(QtCore.QRect(140, 330, 151, 25)) self.abilitiesDropdown.setObjectName("abilitiesDropdown") self.addCharButton = QPushButton(self.createTab) self.addCharButton.setGeometry(QtCore.QRect(30, 370, 98, 27)) self.addCharButton.setObjectName("addCharButton") self.addCharButton.setText("Add") self.gameAbilitiesLabel = QLabel(self.createTab) self.gameAbilitiesLabel.setGeometry(QtCore.QRect(30, 80, 71, 20)) self.setGameAbilButton = QPushButton(self.createTab) self.setGameAbilButton.setGeometry(QtCore.QRect(30, 110, 71, 27)) self.setGameAbilButton.setObjectName("setGameAbilButton") self.setGameAbilButton.setText("Set") self.saveCharButton = QPushButton(self.createTab) self.saveCharButton.setGeometry(QtCore.QRect(70, 430, 180, 60)) self.saveCharButton.setObjectName("saveCharButton") self.saveCharButton.setText("Save Character") font.setPointSize(15) self.gameAbilitiesLabel.setFont(font) self.gameAbilitiesLabel.setObjectName("gameAbilitiesLabel") self.gameAbilitiesLabel.setText("Abilities") self.createTabWidget.addTab(self.createTab, "") # Setup tab widget self.setupTab = QWidget() self.setupTab.setObjectName("setupTab") self.setupDoneButton = QPushButton(self.setupTab) self.setupDoneButton.setGeometry(QtCore.QRect(580, 470, 180, 60)) self.setupDoneButton.setObjectName("setupDoneButton") self.setupDoneButton.setText("Done") self.setupTable = QTableWidget(self.setupTab) self.setupTable.setGeometry(QtCore.QRect(20, 20, 750, 400)) self.setupTable.setFocusPolicy(QtCore.Qt.TabFocus) self.setupTable.setRowCount(1) self.setupTable.setColumnCount(3) self.setupTable.setObjectName("setupTable") self.setupTable.horizontalHeader().setVisible(False) self.setupTable.horizontalHeader().setCascadingSectionResizes(False) self.setupTable.horizontalHeader().setDefaultSectionSize(187) self.setupTable.horizontalHeader().setHighlightSections(False) self.setupTable.horizontalHeader().setStretchLastSection(True) self.setupTable.verticalHeader().setVisible(False) self.setupTable.verticalHeader().setHighlightSections(False) self.setupSaveButton = QPushButton(self.setupTab) self.setupSaveButton.setGeometry(QtCore.QRect(380, 470, 180, 60)) self.setupSaveButton.setObjectName("setupSaveButton") self.setupSaveButton.setText("Save") self.createTabWidget.addTab(self.setupTab, "") self.createTabWidget.setTabText(self.createTabWidget.indexOf(self.createTab), "Create New Game") self.createTabWidget.setTabText(self.createTabWidget.indexOf(self.setupTab), "Set Up Game") self.stackedWidget.addWidget(self.createPage) # Game page self.gamePage = QWidget() self.gamePage.setObjectName("gamePage") self.gameTabWidget = QTabWidget(self.gamePage) self.gameTabWidget.setGeometry(QtCore.QRect(0, 0, 800, 600)) self.gameTabWidget.setFocusPolicy(QtCore.Qt.NoFocus) self.gameTabWidget.setObjectName("gameTabWidget") self.statusTab = QWidget() self.statusTab.setObjectName("statusTab") self.startGameButton = QPushButton(self.statusTab) self.startGameButton.setGeometry(QtCore.QRect(60, 180, 180, 60)) self.startGameButton.setObjectName("startGameButton") self.startGameButton.setText("Start Game") self.endGameButton = QPushButton(self.statusTab) self.endGameButton.setGeometry(QtCore.QRect(60, 260, 180, 60)) self.endGameButton.setObjectName("endGameButton") self.endGameButton.setText("End Game") self.loadGameLabel = QLabel(self.statusTab) self.loadGameLabel.setGeometry(QtCore.QRect(20, 65, 101, 21)) font.setPointSize(15) self.loadGameLabel.setFont(font) self.loadGameLabel.setObjectName("loadGameLabel") self.loadGameLabel.setText("Load Game") self.gameTabWidget.addTab(self.statusTab, "") self.logTab = QWidget() self.logTab.setObjectName("logTab") self.logList = QListWidget(self.logTab) self.logList.setGeometry(QtCore.QRect(30, 30, 730, 500)) self.logList.setObjectName("logList") self.gameTabWidget.addTab(self.logTab, "") self.inputTab = QWidget() self.inputTab.setObjectName("inputTab") self.gameTabWidget.addTab(self.inputTab, "") self.gameTabWidget.setTabText(self.gameTabWidget.indexOf(self.statusTab), "Game Status") self.gameTabWidget.setTabText(self.gameTabWidget.indexOf(self.logTab), "Game Log") self.gameTabWidget.setTabText(self.gameTabWidget.indexOf(self.inputTab), "Input") self.stackedWidget.addWidget(self.gamePage) self.gridLayout.addWidget(self.stackedWidget, 0, 0, 1, 1) MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) self.stackedWidget.setCurrentIndex(0) self.createTabWidget.setCurrentIndex(0) self.gameTabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): pass
class ListParameterWidget(GenericParameterWidget): """Widget class for List parameter.""" def __init__(self, parameter, parent=None): """Constructor .. versionadded:: 2.2 :param parameter: A ListParameter object. :type parameter: ListParameter """ super(ListParameterWidget, self).__init__(parameter, parent) self._input = QListWidget() self._input.setSelectionMode(QAbstractItemView.MultiSelection) if self._parameter.maximum_item_count != \ self._parameter.minimum_item_count: tool_tip = 'Select between %d and %d items' % ( self._parameter.minimum_item_count, self._parameter.maximum_item_count) else: tool_tip = 'Select exactly %d items' % ( self._parameter.maximum_item_count) self._input.setToolTip(tool_tip) for opt in self._parameter.options_list: item = QListWidgetItem() item.setFlags(item.flags() | Qt.ItemIsEditable) item.setText(str(opt)) self._input.addItem(item) if opt in self._parameter.value: item.setSelected(True) self._inner_input_layout.addWidget(self._input) # override self._input_layout arrangement to make the label at the top # reset the layout self._input_layout.setParent(None) self._help_layout.setParent(None) self._label.setParent(None) self._inner_input_layout.setParent(None) self._input_layout = QVBoxLayout() self._input_layout.setSpacing(0) # put element into layout self._input_layout.addWidget(self._label) self._input_layout.addLayout(self._inner_input_layout) self._main_layout.addLayout(self._input_layout) self._main_layout.addLayout(self._help_layout) def raise_invalid_type_exception(self): message = 'Expecting element type of %s' % ( self._parameter.element_type.__name__) err = ValueError(message) return err def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A ListParameter from the current state of widget """ selected_value = [] for opt in self._input.selectedItems(): index = self._input.indexFromItem(opt) selected_value.append(self._parameter.options_list[index.row()]) try: self._parameter.value = selected_value except ValueError: err = self.raise_invalid_type_exception() raise err return self._parameter
class CheckList(QWidget): def __init__(self, model, label="", help_link="", custom_filter_button=None): """ :param custom_filter_button: if needed, add a button that opens a custom filter menu. Useful when search alone isn't enough to filter the list. :type custom_filter_button: QToolButton """ QWidget.__init__(self) self._model = model if help_link != "": addHelpToWidget(self, help_link) layout = QVBoxLayout() self._createCheckButtons() self._list = QListWidget() self._list.setContextMenuPolicy(Qt.CustomContextMenu) self._list.setSelectionMode(QAbstractItemView.ExtendedSelection) self._search_box = SearchBox() check_button_layout = QHBoxLayout() check_button_layout.setMargin(0) check_button_layout.setSpacing(0) check_button_layout.addWidget(QLabel(label)) check_button_layout.addStretch(1) check_button_layout.addWidget(self._checkAllButton) check_button_layout.addWidget(self._uncheckAllButton) layout.addLayout(check_button_layout) layout.addWidget(self._list) """ Inserts the custom filter button, if provided. The caller is responsible for all related actions. """ if custom_filter_button is not None: search_bar_layout = QHBoxLayout() search_bar_layout.addWidget(self._search_box) search_bar_layout.addWidget(custom_filter_button) layout.addLayout(search_bar_layout) else: layout.addWidget(self._search_box) self.setLayout(layout) self._checkAllButton.clicked.connect(self.checkAll) self._uncheckAllButton.clicked.connect(self.uncheckAll) self._list.itemChanged.connect(self.itemChanged) self._search_box.filterChanged.connect(self.filterList) self._list.customContextMenuRequested.connect(self.showContextMenu) self._model.selectionChanged.connect(self.modelChanged) self._model.modelChanged.connect(self.modelChanged) self.modelChanged() def _createCheckButtons(self): self._checkAllButton = QToolButton() self._checkAllButton.setIcon(resourceIcon("checked")) self._checkAllButton.setIconSize(QSize(16, 16)) self._checkAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self._checkAllButton.setAutoRaise(True) self._checkAllButton.setToolTip("Select all") self._uncheckAllButton = QToolButton() self._uncheckAllButton.setIcon(resourceIcon("notchecked")) self._uncheckAllButton.setIconSize(QSize(16, 16)) self._uncheckAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self._uncheckAllButton.setAutoRaise(True) self._uncheckAllButton.setToolTip("Unselect all") def itemChanged(self, item): """@type item: QListWidgetItem""" if item.checkState() == Qt.Checked: self._model.selectValue(str(item.text())) elif item.checkState() == Qt.Unchecked: self._model.unselectValue(str(item.text())) else: raise AssertionError("Unhandled checkstate!") def modelChanged(self): self._list.clear() items = self._model.getList() for item in items: list_item = QListWidgetItem(item) list_item.setFlags(list_item.flags() | Qt.ItemIsUserCheckable) if self._model.isValueSelected(item): list_item.setCheckState(Qt.Checked) else: list_item.setCheckState(Qt.Unchecked) self._list.addItem(list_item) self.filterList(self._search_box.filter()) def setSelectionEnabled(self, enabled): self.setEnabled(enabled) self._checkAllButton.setEnabled(enabled) self._uncheckAllButton.setEnabled(enabled) def filterList(self, filter): filter = filter.lower() for index in range(0, self._list.count()): item = self._list.item(index) text = str(item.text()).lower() if filter == "": item.setHidden(False) elif filter in text: item.setHidden(False) else: item.setHidden(True) def checkAll(self): """ Checks all visible items in the list. """ for index in range(0, self._list.count()): item = self._list.item(index) if not item.isHidden(): self._model.selectValue(str(item.text())) def uncheckAll(self): """ Unchecks all items in the list, visible or not """ self._model.unselectAll() def checkSelected(self): items = [] for item in self._list.selectedItems(): items.append(str(item.text())) for item in items: self._model.selectValue(item) def uncheckSelected(self): items = [] for item in self._list.selectedItems(): items.append(str(item.text())) for item in items: self._model.unselectValue(item) def showContextMenu(self, point): p = self._list.mapToGlobal(point) menu = QMenu() check_selected = menu.addAction("Check selected") uncheck_selected = menu.addAction("Uncheck selected") menu.addSeparator() clear_selection = menu.addAction("Clear selection") selected_item = menu.exec_(p) if selected_item == check_selected: self.checkSelected() elif selected_item == uncheck_selected: self.uncheckSelected() elif selected_item == clear_selection: self._list.clearSelection()
class GroupSelectParameterWidget(GenericParameterWidget): """Widget class for Group Select Parameter.""" def __init__(self, parameter, parent=None): """Constructor. :param parameter: A GroupSelectParameter object. :type parameter: GroupSelectParameter """ QWidget.__init__(self, parent) self._parameter = parameter # Store spin box self.spin_boxes = {} # Create elements # Label (name) self.label = QLabel(self._parameter.name) # Layouts self.main_layout = QVBoxLayout() self.input_layout = QVBoxLayout() # _inner_input_layout must be filled with widget in the child class self.inner_input_layout = QVBoxLayout() self.radio_button_layout = QGridLayout() # Create radio button group self.input_button_group = QButtonGroup() # List widget self.list_widget = QListWidget() self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.list_widget.setDragDropMode(QAbstractItemView.DragDrop) self.list_widget.setDefaultDropAction(Qt.MoveAction) self.list_widget.setEnabled(False) self.list_widget.setSizePolicy( QSizePolicy.Maximum, QSizePolicy.Expanding) for i, key in enumerate(self._parameter.options): value = self._parameter.options[key] radio_button = QRadioButton(value.get('label')) self.radio_button_layout.addWidget(radio_button, i, 0) if value.get('type') == SINGLE_DYNAMIC: double_spin_box = QDoubleSpinBox() self.radio_button_layout.addWidget(double_spin_box, i, 1) double_spin_box.setValue(value.get('value', 0)) double_spin_box.setMinimum( value.get('constraint', {}).get('min', 0)) double_spin_box.setMaximum(value.get( 'constraint', {}).get('max', 1)) double_spin_box.setSingleStep( value.get('constraint', {}).get('step', 0.01)) step = double_spin_box.singleStep() if step > 1: precision = 0 else: precision = len(str(step).split('.')[1]) if precision > 3: precision = 3 double_spin_box.setDecimals(precision) self.spin_boxes[key] = double_spin_box # Enable spin box depends on the selected option if self._parameter.selected == key: double_spin_box.setEnabled(True) else: double_spin_box.setEnabled(False) elif value.get('type') == STATIC: static_value = value.get('value', 0) if static_value is not None: self.radio_button_layout.addWidget( QLabel(str(static_value)), i, 1) elif value.get('type') == MULTIPLE_DYNAMIC: selected_fields = value.get('value', []) if self._parameter.selected == key: self.list_widget.setEnabled(True) else: self.list_widget.setEnabled(False) self.input_button_group.addButton(radio_button, i) if self._parameter.selected == key: radio_button.setChecked(True) # Help text self.help_label = QLabel(self._parameter.help_text) self.help_label.setSizePolicy( QSizePolicy.Maximum, QSizePolicy.Expanding) self.help_label.setWordWrap(True) self.help_label.setAlignment(Qt.AlignTop) self.inner_input_layout.addLayout(self.radio_button_layout) self.inner_input_layout.addWidget(self.list_widget) # Put elements into layouts self.input_layout.addWidget(self.label) self.input_layout.addLayout(self.inner_input_layout) self.help_layout = QVBoxLayout() self.help_layout.addWidget(self.help_label) self.main_layout.addLayout(self.input_layout) self.main_layout.addLayout(self.help_layout) self.setLayout(self.main_layout) self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding) # Update list widget self.update_list_widget() # Connect signal self.input_button_group.buttonClicked.connect( self.radio_buttons_clicked) def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A DefaultValueParameter from the current state of widget :rtype: DefaultValueParameter """ # Set value for each key for key, value in self._parameter.options.items(): if value.get('type') == STATIC: continue elif value.get('type') == SINGLE_DYNAMIC: new_value = self.spin_boxes.get(key).value() self._parameter.set_value_for_key(key, new_value) elif value.get('type') == MULTIPLE_DYNAMIC: # Need to iterate through all items items = [] for index in xrange(self.list_widget.count()): items.append(self.list_widget.item(index)) new_value = [i.text() for i in items] self._parameter.set_value_for_key(key, new_value) # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id == -1: self._parameter.selected = None else: self._parameter.selected = self._parameter.options.keys()[ radio_button_checked_id] return self._parameter def update_list_widget(self): """Update list widget when radio button is clicked.""" # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id > -1: selected_dict = self._parameter.options.values()[ radio_button_checked_id] if selected_dict.get('type') == MULTIPLE_DYNAMIC: for field in selected_dict.get('value'): # Update list widget field_item = QListWidgetItem(self.list_widget) field_item.setFlags( Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) field_item.setData(Qt.UserRole, field) field_item.setText(field) self.list_widget.addItem(field_item) def radio_buttons_clicked(self): """Handler when selected radio button changed.""" # Disable all spin boxes for spin_box in self.spin_boxes.values(): spin_box.setEnabled(False) # Disable list widget self.list_widget.setEnabled(False) # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() if radio_button_checked_id > -1: selected_value = self._parameter.options.values()[ radio_button_checked_id] if selected_value.get('type') == MULTIPLE_DYNAMIC: # Enable list widget self.list_widget.setEnabled(True) elif selected_value.get('type') == SINGLE_DYNAMIC: selected_key = self._parameter.options.keys()[ radio_button_checked_id] self.spin_boxes[selected_key].setEnabled(True) def select_radio_button(self, key): """Helper to select a radio button with key. :param key: The key of the radio button. :type key: str """ key_index = self._parameter.options.keys().index(key) radio_button = self.input_button_group.button(key_index) radio_button.click()
class GroupSelectParameterWidget(GenericParameterWidget): """Widget class for Group Select Parameter.""" def __init__(self, parameter, parent=None): """Constructor. :param parameter: A GroupSelectParameter object. :type parameter: GroupSelectParameter """ QWidget.__init__(self, parent) self._parameter = parameter # Store spin box self.spin_boxes = {} # Create elements # Label (name) self.label = QLabel(self._parameter.name) # Layouts self.main_layout = QVBoxLayout() self.input_layout = QVBoxLayout() # _inner_input_layout must be filled with widget in the child class self.inner_input_layout = QVBoxLayout() self.radio_button_layout = QGridLayout() # Create radio button group self.input_button_group = QButtonGroup() # List widget self.list_widget = QListWidget() self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) self.list_widget.setDragDropMode(QAbstractItemView.DragDrop) self.list_widget.setDefaultDropAction(Qt.MoveAction) self.list_widget.setEnabled(False) self.list_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding) for i, key in enumerate(self._parameter.options): value = self._parameter.options[key] radio_button = QRadioButton(value.get('label')) self.radio_button_layout.addWidget(radio_button, i, 0) if value.get('type') == SINGLE_DYNAMIC: double_spin_box = QDoubleSpinBox() self.radio_button_layout.addWidget(double_spin_box, i, 1) double_spin_box.setValue(value.get('value', 0)) double_spin_box.setMinimum( value.get('constraint', {}).get('min', 0)) double_spin_box.setMaximum( value.get('constraint', {}).get('max', 1)) double_spin_box.setSingleStep( value.get('constraint', {}).get('step', 0.01)) step = double_spin_box.singleStep() if step > 1: precision = 0 else: precision = len(str(step).split('.')[1]) if precision > 3: precision = 3 double_spin_box.setDecimals(precision) self.spin_boxes[key] = double_spin_box # Enable spin box depends on the selected option if self._parameter.selected == key: double_spin_box.setEnabled(True) else: double_spin_box.setEnabled(False) elif value.get('type') == STATIC: static_value = value.get('value', 0) if static_value is not None: self.radio_button_layout.addWidget( QLabel(str(static_value)), i, 1) elif value.get('type') == MULTIPLE_DYNAMIC: selected_fields = value.get('value', []) if self._parameter.selected == key: self.list_widget.setEnabled(True) else: self.list_widget.setEnabled(False) self.input_button_group.addButton(radio_button, i) if self._parameter.selected == key: radio_button.setChecked(True) # Help text self.help_label = QLabel(self._parameter.help_text) self.help_label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding) self.help_label.setWordWrap(True) self.help_label.setAlignment(Qt.AlignTop) self.inner_input_layout.addLayout(self.radio_button_layout) self.inner_input_layout.addWidget(self.list_widget) # Put elements into layouts self.input_layout.addWidget(self.label) self.input_layout.addLayout(self.inner_input_layout) self.help_layout = QVBoxLayout() self.help_layout.addWidget(self.help_label) self.main_layout.addLayout(self.input_layout) self.main_layout.addLayout(self.help_layout) self.setLayout(self.main_layout) self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding) # Update list widget self.update_list_widget() # Connect signal self.input_button_group.buttonClicked.connect( self.radio_buttons_clicked) def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A DefaultValueParameter from the current state of widget :rtype: DefaultValueParameter """ # Set value for each key for key, value in self._parameter.options.items(): if value.get('type') == STATIC: continue elif value.get('type') == SINGLE_DYNAMIC: new_value = self.spin_boxes.get(key).value() self._parameter.set_value_for_key(key, new_value) elif value.get('type') == MULTIPLE_DYNAMIC: # Need to iterate through all items items = [] for index in xrange(self.list_widget.count()): items.append(self.list_widget.item(index)) new_value = [i.text() for i in items] self._parameter.set_value_for_key(key, new_value) # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id == -1: self._parameter.selected = None else: self._parameter.selected = self._parameter.options.keys( )[radio_button_checked_id] return self._parameter def update_list_widget(self): """Update list widget when radio button is clicked.""" # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id > -1: selected_dict = self._parameter.options.values( )[radio_button_checked_id] if selected_dict.get('type') == MULTIPLE_DYNAMIC: for field in selected_dict.get('value'): # Update list widget field_item = QListWidgetItem(self.list_widget) field_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) field_item.setData(Qt.UserRole, field) field_item.setText(field) self.list_widget.addItem(field_item) def radio_buttons_clicked(self): """Handler when selected radio button changed.""" # Disable all spin boxes for spin_box in self.spin_boxes.values(): spin_box.setEnabled(False) # Disable list widget self.list_widget.setEnabled(False) # Get selected radio button radio_button_checked_id = self.input_button_group.checkedId() if radio_button_checked_id > -1: selected_value = self._parameter.options.values( )[radio_button_checked_id] if selected_value.get('type') == MULTIPLE_DYNAMIC: # Enable list widget self.list_widget.setEnabled(True) elif selected_value.get('type') == SINGLE_DYNAMIC: selected_key = self._parameter.options.keys( )[radio_button_checked_id] self.spin_boxes[selected_key].setEnabled(True) def select_radio_button(self, key): """Helper to select a radio button with key. :param key: The key of the radio button. :type key: str """ key_index = self._parameter.options.keys().index(key) radio_button = self.input_button_group.button(key_index) radio_button.click()
class KeywordList(HelpedWidget): """Shows a list of keywords. The data structure expected and sent to the getter and setter is an array of values.""" def __init__(self, model, list_label="", help_link=""): HelpedWidget.__init__(self, list_label, help_link) assert isinstance(model, ListModelMixin) self.model = model self.keyword_list = [] self.list = QListWidget(self) self.list.setMinimumHeight(100) self.list.setMaximumHeight(150) self.default_selection_mode = self.list.selectionMode() self.addWidget(self.list) self.addRemoveWidget = AddRemoveWidget(self.addItem, self.removeItem) self.addWidget(self.addRemoveWidget) self.title = "New keyword" self.description = "Enter name of keyword:" self.model.observable().attach(ListModelMixin.LIST_CHANGED_EVENT, self.modelChanged) self.modelChanged() def setSelectable(self, selectable): if selectable: self.list.setSelectionMode(self.default_selection_mode) else: self.list.setSelectionMode(QAbstractItemView.NoSelection) def setPopupLabels(self, title, description): """Change the labels of the default popup.""" self.title = title self.description = description def newKeywordPopup(self, keyword_list): """ Pops up a message box asking for a new keyword. Override this and return a string to customize the input dialog - Empty string equals canceled. The provided list are the already defined keywords """ new_keyword, ok = QInputDialog.getText(self, self.tr(self.title), self.tr(self.description), QLineEdit.Normal) if ok: return str(new_keyword).strip() else: return "" def addItem(self): """Called by the add button to insert a new keyword""" new_keyword = self.newKeywordPopup(self.keyword_list) if not new_keyword == "": self.model.addItem(new_keyword) def removeItem(self): """Called by the remove button to remove a selected keyword""" if not self.list.currentItem() is None: row = self.list.currentRow() try: self.model.removeItem(self.keyword_list[row]) except NotImplementedError: message = "Support for removal of items has not been implemented!" QMessageBox.information(self, "Not implemented!", message) def modelChanged(self): """Retrieves data from the model and inserts it into the list""" keywords = self.model.getList() self.list.clear() self.keyword_list = keywords for keyword in keywords: self.list.addItem(keyword)
class CheckList(HelpedWidget): def __init__(self, model, label="", help_link=""): HelpedWidget.__init__(self, "", help_link) layout = QVBoxLayout() widget = QWidget() widget.setLayout(layout) self.checkAllButton = QToolButton() self.checkAllButton.setIcon(resourceIcon("checked")) self.checkAllButton.setIconSize(QSize(16, 16)) self.checkAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.checkAllButton.setAutoRaise(True) self.checkAllButton.setToolTip("Select all") self.uncheckAllButton = QToolButton() self.uncheckAllButton.setIcon(resourceIcon("notchecked")) self.uncheckAllButton.setIconSize(QSize(16, 16)) self.uncheckAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.uncheckAllButton.setAutoRaise(True) self.uncheckAllButton.setToolTip("Unselect all") self.list = QListWidget() self.list.setContextMenuPolicy(Qt.CustomContextMenu) self.list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.search_box = SearchBox() check_button_layout = QHBoxLayout() check_button_layout.setMargin(0) check_button_layout.setSpacing(0) check_button_layout.addWidget(QLabel(label)) check_button_layout.addStretch(1) check_button_layout.addWidget(self.checkAllButton) check_button_layout.addWidget(self.uncheckAllButton) layout.addLayout(check_button_layout) layout.addWidget(self.list) layout.addWidget(self.search_box) self.addWidget(widget) self.connect(self.checkAllButton, SIGNAL('clicked()'), self.checkAll) self.connect(self.uncheckAllButton, SIGNAL('clicked()'), self.uncheckAll) self.connect(self.list, SIGNAL('itemChanged(QListWidgetItem*)'), self.itemChanged) self.search_box.filterChanged.connect(self.filterList) # self.connect(self.search_box, SIGNAL('filterChanged(str)'), self.filterList) self.connect(self.list, SIGNAL('customContextMenuRequested(QPoint)'), self.showContextMenu) assert isinstance(model, (SelectableModelMixin, ListModelMixin)) self.model = model self.model.observable().attach(SelectableModelMixin.SELECTION_CHANGED_EVENT, self.modelChanged) self.model.observable().attach(ListModelMixin.LIST_CHANGED_EVENT, self.modelChanged) self.modelChanged() def itemChanged(self, item): """@type item: QListWidgetItem""" if item.checkState() == Qt.Checked: self.model.selectValue(str(item.text())) elif item.checkState() == Qt.Unchecked: self.model.unselectValue(str(item.text())) else: raise AssertionError("Unhandled checkstate!") def modelChanged(self): self.list.clear() items = self.model.getList() for item in items: list_item = QListWidgetItem(item) list_item.setFlags(list_item.flags() | Qt.ItemIsUserCheckable) if self.model.isValueSelected(item): list_item.setCheckState(Qt.Checked) else: list_item.setCheckState(Qt.Unchecked) self.list.addItem(list_item) self.filterList(self.search_box.filter()) def setSelectionEnabled(self, enabled): self.setEnabled(enabled) self.checkAllButton.setEnabled(enabled) self.uncheckAllButton.setEnabled(enabled) def filterList(self, filter): filter = filter.lower() for index in range(0, self.list.count()): item = self.list.item(index) text = str(item.text()).lower() if filter == "": item.setHidden(False) elif filter in text: item.setHidden(False) else: item.setHidden(True) def checkAll(self): self.model.selectAll() def uncheckAll(self): self.model.unselectAll() def checkSelected(self): items = [] for item in self.list.selectedItems(): items.append(str(item.text())) for item in items: self.model.selectValue(item) def uncheckSelected(self): items = [] for item in self.list.selectedItems(): items.append(str(item.text())) for item in items: self.model.unselectValue(item) def showContextMenu(self, point): p = self.list.mapToGlobal(point) menu = QMenu() check_selected = menu.addAction("Check selected") uncheck_selected = menu.addAction("Uncheck selected") menu.addSeparator() clear_selection = menu.addAction("Clear selection") selected_item = menu.exec_(p) if selected_item == check_selected: self.checkSelected() elif selected_item == uncheck_selected: self.uncheckSelected() elif selected_item == clear_selection: self.list.clearSelection()
class DoubleListWidget(QWidget): __pyqtSignals__ = ('stateChanged') def __init__(self, parent, list, active_list): QWidget.__init__(self, parent) self.list = list self.list_active = active_list self.item_list = {} layout = QHBoxLayout(self) self.setLayout(layout) self.layout = layout self.addActiveListView() self.addButtons() self.addInactiveListView() self.fillListView() def addButtons(self): frame = QFrame(self) layout_v = QVBoxLayout(frame) frame.setLayout(layout_v) button_left = QPushButton('<- Left') self.connect(button_left, SIGNAL('clicked()'), lambda: self.MoveToActive()) layout_v.addWidget(button_left) button_right = QPushButton('Right ->') self.connect(button_right, SIGNAL('clicked()'), lambda: self.MoveToInactive()) layout_v.addWidget(button_right) layout_v.addStretch(100) self.layout.addWidget(frame) def addActiveListView(self): self.listview_active = QListWidget(self) self.listview_active.setSelectionMode(QAbstractItemView.ExtendedSelection) self.layout.addWidget(self.listview_active) def addInactiveListView(self): self.listview_inactive = QListWidget(self) self.listview_inactive.setSelectionMode(QAbstractItemView.ExtendedSelection) self.layout.addWidget(self.listview_inactive) def fillListView(self): self.listview_active.clear() self.listview_inactive.clear() for i in self.list_active: self.listview_active.addItem(i) for i in self.list: if not i in self.list_active: self.listview_inactive.addItem(i) self.listview_inactive.sortItems() self.listview_active.sortItems() def MoveToActive(self): for i in self.listview_inactive.selectedItems(): self.list_active.append(i.text()) self.fillListView() self.emit(SIGNAL("stateChanged")) def MoveToInactive(self): for i in self.listview_active.selectedItems(): self.list_active.remove(i.text()) self.fillListView() self.emit(SIGNAL("stateChanged")) def getActiveList(self): return self.list_active
class KeywordList(HelpedWidget): """Shows a list of keywords. The data structure expected and sent to the getter and setter is an array of values.""" def __init__(self, model, list_label="", help_link=""): HelpedWidget.__init__(self, list_label, help_link) assert isinstance(model, ListModelMixin) self.model = model self.keyword_list = [] self.list = QListWidget(self) self.list.setMinimumHeight(100) self.list.setMaximumHeight(150) self.default_selection_mode = self.list.selectionMode() self.addWidget(self.list) self.addRemoveWidget = AddRemoveWidget(self.addItem, self.removeItem) self.addWidget(self.addRemoveWidget) self.title = "New keyword" self.description = "Enter name of keyword:" self.model.observable().attach(ListModelMixin.LIST_CHANGED_EVENT, self.modelChanged) self.modelChanged() def setSelectable(self, selectable): if selectable: self.list.setSelectionMode(self.default_selection_mode) else: self.list.setSelectionMode(QAbstractItemView.NoSelection) def setPopupLabels(self, title, description): """Change the labels of the default popup.""" self.title = title self.description = description def newKeywordPopup(self, keyword_list): """ Pops up a message box asking for a new keyword. Override this and return a string to customize the input dialog - Empty string equals canceled. The provided list are the already defined keywords """ new_keyword, ok = QInputDialog.getText(self, self.tr(self.title), self.tr(self.description), QLineEdit.Normal) if ok: return str(new_keyword).strip() else: return "" def addItem(self): """Called by the add button to insert a new keyword""" new_keyword = self.newKeywordPopup(self.keyword_list) if not new_keyword == "": self.model.addItem(new_keyword) def removeItem(self): """Called by the remove button to remove a selected keyword""" if not self.list.currentItem() is None: row = self.list.currentRow() try: self.model.removeItem(self.keyword_list[row]) except NotImplementedError: message = "Support for removal of items has not been implemented!" QMessageBox.information(self, "Not implemented!", message) def modelChanged(self): """Retrieves data from the model and inserts it into the list""" keywords = self.model.getList() self.list.clear() self.keyword_list = keywords for keyword in keywords: self.list.addItem(keyword) def cleanup(self): self.model.observable().detach(ListModelMixin.LIST_CHANGED_EVENT, self.modelChanged)
class Theme(QWidget): """Theme widget class.""" def __init__(self, parent): super(Theme, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) vbox.addWidget(QLabel(self.tr("<b>Select Theme:</b>"))) self.list_skins = QListWidget() self.list_skins.setSelectionMode(QListWidget.SingleSelection) vbox.addWidget(self.list_skins) self.btn_delete = QPushButton(self.tr("Delete Theme")) self.btn_preview = QPushButton(self.tr("Preview Theme")) self.btn_create = QPushButton(self.tr("Create Theme")) hbox = QHBoxLayout() hbox.addWidget(self.btn_delete) hbox.addSpacerItem( QSpacerItem(10, 0, QSizePolicy.Expanding, QSizePolicy.Fixed)) hbox.addWidget(self.btn_preview) hbox.addWidget(self.btn_create) vbox.addLayout(hbox) self._refresh_list() self.connect(self.btn_preview, SIGNAL("clicked()"), self.preview_theme) self.connect(self.btn_delete, SIGNAL("clicked()"), self.delete_theme) self.connect(self.btn_create, SIGNAL("clicked()"), self.create_theme) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def delete_theme(self): if self.list_skins.currentRow() != 0: file_name = ("%s.qss" % self.list_skins.currentItem().text()) qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD, file_name) file_manager.delete_file(qss_file) self._refresh_list() def create_theme(self): designer = preferences_theme_editor.ThemeEditor(self) designer.exec_() self._refresh_list() def showEvent(self, event): self._refresh_list() super(Theme, self).showEvent(event) def _refresh_list(self): self.list_skins.clear() self.list_skins.addItem("Default") files = sorted([ file_manager.get_file_name(filename) for filename in file_manager.get_files_from_folder( resources.NINJA_THEME_DOWNLOAD, "qss") ]) self.list_skins.addItems(files) if settings.NINJA_SKIN in files: index = files.index(settings.NINJA_SKIN) self.list_skins.setCurrentRow(index + 1) else: self.list_skins.setCurrentRow(0) def save(self): qsettings = IDE.ninja_settings() settings.NINJA_SKIN = self.list_skins.currentItem().text() qsettings.setValue("preferences/theme/skin", settings.NINJA_SKIN) self.preview_theme() def preview_theme(self): if self.list_skins.currentRow() == 0: qss_file = resources.NINJA_THEME else: file_name = ("%s.qss" % self.list_skins.currentItem().text()) qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD, file_name) with open(qss_file) as f: qss = f.read() QApplication.instance().setStyleSheet(qss)
class FieldMappingTab(QWidget, object): """Widget class for field mapping.""" def __init__(self, field_group=None, parent=None, iface=None): """Constructor.""" # Init from parent class QWidget.__init__(self, parent) # Attributes self.layer = None self.metadata = {} self.parent = parent self.iface = iface self.field_group = field_group self.setting = QSettings() # TODO(IS): Make dynamic # Main container self.main_layout = QVBoxLayout() # Inner layout self.header_layout = QHBoxLayout() self.content_layout = QHBoxLayout() self.footer_layout = QHBoxLayout() # Header self.header_label = QLabel() self.header_label.setWordWrap(True) # Content self.field_layout = QVBoxLayout() self.parameter_layout = QHBoxLayout() self.field_description = QLabel(tr('List of fields')) self.field_list = QListWidget() self.field_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.field_list.setDragDropMode(QAbstractItemView.DragDrop) self.field_list.setDefaultDropAction(Qt.MoveAction) self.field_list.setSizePolicy( QSizePolicy.Maximum, QSizePolicy.Expanding) # noinspection PyUnresolvedReferences self.field_list.itemSelectionChanged.connect(self.update_footer) # Footer self.footer_label = QLabel() # Parameters self.extra_parameters = [ (GroupSelectParameter, GroupSelectParameterWidget) ] self.parameters = [] self.parameter_container = None # Adding to layout self.header_layout.addWidget(self.header_label) self.field_layout.addWidget(self.field_description) self.field_layout.addWidget(self.field_list) self.field_layout.setSizeConstraint(QLayout.SetMaximumSize) self.content_layout.addLayout(self.field_layout) self.content_layout.addLayout(self.parameter_layout) self.footer_layout.addWidget(self.footer_label) self.main_layout.addLayout(self.header_layout) self.main_layout.addLayout(self.content_layout) self.main_layout.addLayout(self.footer_layout) self.setLayout(self.main_layout) def set_layer(self, layer, keywords=None): """Set layer and update UI accordingly. :param layer: A vector layer that has been already patched with metadata. :type layer: QgsVectorLayer :param keywords: Custom keyword for the layer. :type keywords: dict, None """ self.layer = layer if keywords is not None: self.metadata = keywords else: # Check if it has keywords if not hasattr(layer, 'keywords'): message = 'Layer {layer_name} does not have keywords.'.format( layer_name=layer.name()) raise KeywordNotFoundError(message) self.metadata = layer.keywords self.populate_parameter() def populate_field_list(self, excluded_fields=None): """Helper to add field of the layer to the list. :param excluded_fields: List of field that want to be excluded. :type excluded_fields: list """ # Populate fields list if excluded_fields is None: excluded_fields = [] self.field_list.clear() for field in self.layer.dataProvider().fields(): # Skip if it's excluded if field.name() in excluded_fields: continue # Skip if it's not number (float, int, etc) if field.type() not in qvariant_numbers: continue field_item = QListWidgetItem(self.field_list) field_item.setFlags( Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) field_item.setData(Qt.UserRole, field.name()) field_item.setText(field.name()) self.field_list.addItem(field_item) def populate_parameter(self): """Helper to setup the parameter widget.""" used_fields = [] self.parameters = [] for field in self.field_group.get('fields', []): selected_option = DO_NOT_USE options = OrderedDict([ (DO_NOT_USE, { 'label': tr('Do not use'), 'value': None, 'type': STATIC, 'constraint': {} }), ]) # Example: count if field['absolute']: # Used in field options field_label = tr('Count fields') else: # Example: ratio # Used in field options field_label = tr('Ratio fields') global_default_value = get_inasafe_default_value_qsetting( self.setting, GLOBAL, field['key']) options[GLOBAL_DEFAULT] = { 'label': tr('Global default'), 'value': global_default_value, 'type': STATIC, 'constraint': {} } default_custom_value = get_inasafe_default_value_qsetting( self.setting, RECENT, field['key']) custom_value = self.metadata.get( 'inasafe_default_values', {}).get( field['key'], default_custom_value) if field['key'] in self.metadata.get( 'inasafe_default_values', {}): if custom_value == global_default_value: selected_option = GLOBAL_DEFAULT else: selected_option = CUSTOM_VALUE min_value = field['default_value'].get('min_value', 0) max_value = field['default_value'].get('max_value', 100) default_step = (max_value - min_value) / 100.0 step = field['default_value'].get('increment', default_step) options[CUSTOM_VALUE] = { 'label': tr('Custom'), 'value': custom_value, 'type': SINGLE_DYNAMIC, 'constraint': { 'min': min_value, 'max': max_value, 'step': step } } custom_fields = self.metadata.get('inasafe_fields', {}).get( field['key'], []) if field['key'] in self.metadata.get('inasafe_fields', {}): selected_option = FIELDS if isinstance(custom_fields, basestring): custom_fields = [custom_fields] options[FIELDS] = { 'label': field_label, 'value': custom_fields, 'type': MULTIPLE_DYNAMIC, 'constraint': {} } used_fields.extend(custom_fields) parameter = GroupSelectParameter() parameter.guid = field['key'] parameter.name = field['name'] parameter.options = options parameter.selected = selected_option parameter.help_text = field['help_text'] parameter.description = field['description'] self.parameters.append(parameter) self.parameter_container = ParameterContainer( parameters=self.parameters, extra_parameters=self.extra_parameters, vertical=False ) self.parameter_container.setup_ui() constraints = self.field_group.get('constraints', {}) for key, value in constraints.items(): self.parameter_container.add_validator( validators[key], kwargs=value['kwargs'], validation_message=value['message']) self.parameter_layout.addWidget(self.parameter_container) # Set move or copy if self.field_group.get('exclusive', False): # If exclusive, do not add used field. self.populate_field_list(excluded_fields=used_fields) # Use move action since it's exclusive self.field_list.setDefaultDropAction(Qt.MoveAction) # Just make sure that the signal is disconnected try: # noinspection PyUnresolvedReferences self.field_list.itemChanged.disconnect(self.drop_remove) except TypeError: pass # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can only map one field to one concept.') else: # If not exclusive, add all field. self.populate_field_list() # Use copy action since it's not exclusive self.field_list.setDefaultDropAction(Qt.CopyAction) # noinspection PyUnresolvedReferences self.field_list.itemChanged.connect( partial(self.drop_remove, field_list=self.field_list)) self.connect_drop_remove_parameter() # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can map one field to more than one concepts.') self.header_label.setText(header_text) def get_parameter_value(self): """Get parameter of the tab. :returns: Dictionary of parameters by type in this format: {'fields': {}, 'values': {}}. :rtype: dict """ try: parameters = self.parameter_container.get_parameters(True) except InvalidValidationException as e: raise OriginalValidationException(e) field_parameters = {} value_parameters = {} for parameter in parameters: if parameter.selected_option_type() in [SINGLE_DYNAMIC, STATIC]: value_parameters[parameter.guid] = parameter.value elif parameter.selected_option_type() == MULTIPLE_DYNAMIC: field_parameters[parameter.guid] = parameter.value return { 'fields': field_parameters, 'values': value_parameters } def update_footer(self): """Update footer when the field list change.""" field_item = self.field_list.currentItem() if not field_item: self.footer_label.setText('') return field_name = field_item.data(Qt.UserRole) field = self.layer.fields().field(field_name) index = self.layer.fieldNameIndex(field_name) unique_values = self.layer.uniqueValues(index) pretty_unique_values = ', '.join([str(v) for v in unique_values[:10]]) footer_text = tr('Field type: {0}\n').format(field.typeName()) footer_text += tr('Unique values: {0}').format(pretty_unique_values) self.footer_label.setText(footer_text) def connect_drop_remove_parameter(self): parameter_widgets = self.parameter_container.get_parameter_widgets() for parameter_widget in parameter_widgets: field_list = parameter_widget.widget().list_widget field_list.itemChanged.connect( partial(self.drop_remove, field_list=field_list)) @staticmethod def drop_remove(*args, **kwargs): """Action when we need to remove dropped item. :param args: Position arguments. :type args: list :param kwargs: Keywords arguments. :type kwargs: dict """ dropped_item = args[0] field_list = kwargs['field_list'] num_duplicate = 0 for i in range(field_list.count()): if dropped_item.text() == field_list.item(i).text(): num_duplicate += 1 if num_duplicate > 1: # Notes(IS): For some reason, removeItemWidget is not working. field_list.takeItem(field_list.row(dropped_item))
class InputListParameterWidget(GenericParameterWidget): """Widget class for List parameter.""" def __init__(self, parameter, parent=None): """Constructor .. versionadded:: 2.2 :param parameter: A ListParameter object. :type parameter: InputListParameter """ super(InputListParameterWidget, self).__init__(parameter, parent) # value cache for self._parameter.value # copy the list so the original is unaffected self._value_cache = list(self._parameter.value) self._input = QListWidget() self._input.setSelectionMode(QAbstractItemView.SingleSelection) if self._parameter.maximum_item_count != \ self._parameter.minimum_item_count: tool_tip = 'Select between %d and %d items' % ( self._parameter.minimum_item_count, self._parameter.maximum_item_count) else: tool_tip = 'Select exactly %d items' % ( self._parameter.maximum_item_count) self._input.setToolTip(tool_tip) # arrange widget self._insert_item_input = QLineEdit() vbox_layout = QVBoxLayout() hbox_layout = QHBoxLayout() self._input_add_button = QPushButton('Add') self._input_remove_button = QPushButton('Remove') # arrange line edit, add button, remove button in horizontal layout hbox_layout.addWidget(self._insert_item_input) hbox_layout.addWidget(self._input_add_button) hbox_layout.addWidget(self._input_remove_button) # arrange vertical layout vbox_layout.addLayout(hbox_layout) vbox_layout.addWidget(self._input) self._inner_input_layout.addLayout(vbox_layout) # override self._input_layout arrangement to make the label at the top # reset the layout self._input_layout.setParent(None) self._help_layout.setParent(None) self._label.setParent(None) self._inner_input_layout.setParent(None) self._input_layout = QVBoxLayout() self._input_layout.setSpacing(0) # put element into layout self._input_layout.addWidget(self._label) self._input_layout.addLayout(self._inner_input_layout) self._main_layout.addLayout(self._input_layout) self._main_layout.addLayout(self._help_layout) # connect handler # noinspection PyUnresolvedReferences self._input_add_button.clicked.connect(self.on_add_button_click) # noinspection PyUnresolvedReferences self._input_remove_button.clicked.connect(self.on_remove_button_click) # noinspection PyUnresolvedReferences self._insert_item_input.returnPressed.connect( self._input_add_button.click) # noinspection PyUnresolvedReferences self._input.itemChanged.connect(self.on_row_changed) self.refresh_list() # init row add error handler self._add_row_error_handler = None @property def add_row_error_handler(self): """return error handler if user mistakenly add row of unexpected type :return: a function handler :rtype: () -> None """ return self._add_row_error_handler @add_row_error_handler.setter def add_row_error_handler(self, value): """Set error handler to handle user mistakenly add row of unexpected type """ self._add_row_error_handler = value def refresh_list(self): self._input.clear() if not self._parameter.ordering == InputListParameter.NotOrdered: self._value_cache.sort() if self._parameter.ordering == InputListParameter.DescendingOrder: self._value_cache.reverse() for opt in self._value_cache: item = QListWidgetItem() item.setText(str(opt)) item.setFlags(item.flags() | Qt.ItemIsEditable) self._input.addItem(item) def on_add_button_click(self): try: value = self._parameter.element_type( self._insert_item_input.text()) self._value_cache.append(value) self.refresh_list() except ValueError: err = self.raise_invalid_type_exception() if self.add_row_error_handler is not None: self.add_row_error_handler(err) else: raise err def on_remove_button_click(self): for opt in self._input.selectedItems(): index = self._input.indexFromItem(opt) del self._value_cache[index.row()] self.refresh_list() def on_row_changed(self, item): try: index = self._input.indexFromItem(item).row() prev_value = self._value_cache[index] self._value_cache[index] = self._parameter.element_type( item.text()) self.refresh_list() except ValueError: item.setText(str(prev_value)) self.raise_invalid_type_exception() def raise_invalid_type_exception(self): message = 'Expecting element type of %s' % ( self._parameter.element_type.__name__) err = ValueError(message) return err def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A ListParameter from the current state of widget """ try: self._parameter.value = self._value_cache except ValueError: err = self.raise_invalid_type_exception() raise err return self._parameter
class TraceWindow(QMainWindow): def __init__(self, params_pipe, number_pipe, data_pipe, mads_pipe, peaks_pipe, probe_path=None, screen_resolution=None): QMainWindow.__init__(self) # Receive parameters. params = params_pipe[0].recv() self.probe = load_probe(probe_path) self._nb_samples = params['nb_samples'] self._sampling_rate = params['sampling_rate'] self._display_list = list(range(self.probe.nb_channels)) self._params = { 'nb_samples': self._nb_samples, 'sampling_rate': self._sampling_rate, 'time': { 'min': 10.0, # ms 'max': 1000.0, # ms 'init': 100.0, # ms }, 'voltage': { 'min': 10.0, # µV 'max': 10e+3, # µV 'init': 20.0, # µV }, 'mads': { 'min': 0.0, # µV 'max': 100, # µV 'init': 3, # µV }, 'channels': self._display_list } self._canvas = TraceCanvas(probe_path=probe_path, params=self._params) central_widget = self._canvas.native # Create controls widgets. label_time = QLabel() label_time.setText(u"time") label_time_unit = QLabel() label_time_unit.setText(u"ms") self._dsp_time = QDoubleSpinBox() self._dsp_time.setMinimum(self._params['time']['min']) self._dsp_time.setMaximum(self._params['time']['max']) self._dsp_time.setValue(self._params['time']['init']) self._dsp_time.valueChanged.connect(self._on_time_changed) label_display_mads = QLabel() label_display_mads.setText(u"Display Mads") self._display_mads = QCheckBox() self._display_mads.stateChanged.connect(self._on_mads_display) label_display_peaks = QLabel() label_display_peaks.setText(u"Display Peaks") self._display_peaks = QCheckBox() self._display_peaks.stateChanged.connect(self._on_peaks_display) label_mads = QLabel() label_mads.setText(u"Mads") label_mads_unit = QLabel() label_mads_unit.setText(u"unit") self._dsp_mads = QDoubleSpinBox() self._dsp_mads.setMinimum(self._params['mads']['min']) self._dsp_mads.setMaximum(self._params['mads']['max']) self._dsp_mads.setValue(self._params['mads']['init']) self._dsp_mads.valueChanged.connect(self._on_mads_changed) label_voltage = QLabel() label_voltage.setText(u"voltage") label_voltage_unit = QLabel() label_voltage_unit.setText(u"µV") self._dsp_voltage = QDoubleSpinBox() self._dsp_voltage.setMinimum(self._params['voltage']['min']) self._dsp_voltage.setMaximum(self._params['voltage']['max']) self._dsp_voltage.setValue(self._params['voltage']['init']) self._dsp_voltage.valueChanged.connect(self._on_voltage_changed) # Color spikes self._color_spikes = QCheckBox() self._color_spikes.setText('See Spikes color') self._color_spikes.setCheckState(Qt.Checked) self._color_spikes.stateChanged.connect(self.display_spikes_color) # self._selection_channels.setGeometry(QtCore.QRect(10, 10, 211, 291)) spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) # Create controls grid. grid = QGridLayout() # # Add time row. grid.addWidget(label_time, 0, 0) grid.addWidget(self._dsp_time, 0, 1) grid.addWidget(label_time_unit, 0, 2) # # Add voltage row. grid.addWidget(label_voltage, 1, 0) grid.addWidget(self._dsp_voltage, 1, 1) grid.addWidget(label_voltage_unit, 1, 2) # # Add Mads widgets grid.addWidget(label_display_mads, 3, 0) grid.addWidget(self._display_mads, 3, 1) grid.addWidget(label_mads, 4, 0) grid.addWidget(self._dsp_mads, 4, 1) grid.addWidget(label_mads_unit, 4, 2) grid.addWidget(self._color_spikes, 5, 0) # # Add spacer. grid.addItem(spacer) # # Create info group. controls_group = QGroupBox() controls_group.setLayout(grid) self._selection_channels = QListWidget() self._selection_channels.setSelectionMode( QAbstractItemView.ExtendedSelection ) for i in range(self.probe.nb_channels): item = QListWidgetItem("Channel %i" % i) self._selection_channels.addItem(item) self._selection_channels.item(i).setSelected(True) def add_channel(): items = self._selection_channels.selectedItems() self._display_list = [] for i in range(len(items)): self._display_list.append(i) self._on_channels_changed() # self._selection_channels.itemClicked.connect(add_channel) nb_channel = self.probe.nb_channels self._selection_channels.itemSelectionChanged.connect(lambda: self.selected_channels(nb_channel)) # Create info grid. channels_grid = QGridLayout() # # Add Channel selection # grid.addWidget(label_selection, 3, 0) channels_grid.addWidget(self._selection_channels, 0, 1) # # Add spacer. channels_grid.addItem(spacer) # Create controls group. channels_group = QGroupBox() channels_group.setLayout(channels_grid) # # Create controls dock. channels_dock = QDockWidget() channels_dock.setWidget(channels_group) channels_dock.setWindowTitle("Channels selection") # # Create controls dock. control_dock = QDockWidget() control_dock.setWidget(controls_group) control_dock.setWindowTitle("Controls") # Create info widgets. label_time = QLabel() label_time.setText(u"time") self._label_time_value = QLineEdit() self._label_time_value.setText(u"0") self._label_time_value.setReadOnly(True) self._label_time_value.setAlignment(Qt.AlignRight) label_time_unit = QLabel() label_time_unit.setText(u"s") info_buffer_label = QLabel() info_buffer_label.setText(u"buffer") self._info_buffer_value_label = QLineEdit() self._info_buffer_value_label.setText(u"0") self._info_buffer_value_label.setReadOnly(True) self._info_buffer_value_label.setAlignment(Qt.AlignRight) info_buffer_unit_label = QLabel() info_buffer_unit_label.setText(u"") info_probe_label = QLabel() info_probe_label.setText(u"probe") info_probe_value_label = QLineEdit() info_probe_value_label.setText(u"{}".format(probe_path)) info_probe_value_label.setReadOnly(True) # TODO place the following info in another grid? info_probe_unit_label = QLabel() info_probe_unit_label.setText(u"") info_spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) # Create info grid. info_grid = QGridLayout() # # Time row. info_grid.addWidget(label_time, 0, 0) info_grid.addWidget(self._label_time_value, 0, 1) info_grid.addWidget(label_time_unit, 0, 2) # # Buffer row. info_grid.addWidget(info_buffer_label, 1, 0) info_grid.addWidget(self._info_buffer_value_label, 1, 1) info_grid.addWidget(info_buffer_unit_label, 1, 2) # # Probe row. info_grid.addWidget(info_probe_label, 2, 0) info_grid.addWidget(info_probe_value_label, 2, 1) info_grid.addWidget(info_probe_unit_label, 2, 2) # # Spacer. info_grid.addItem(info_spacer) # Create info group. info_group = QGroupBox() info_group.setLayout(info_grid) # Create info dock. info_dock = QDockWidget() info_dock.setWidget(info_group) info_dock.setWindowTitle("Info") # Create thread. thread = Thread(number_pipe, data_pipe, mads_pipe, peaks_pipe) thread.number_signal.connect(self._number_callback) thread.reception_signal.connect(self._reception_callback) thread.start() # Add dockable windows. self.addDockWidget(Qt.LeftDockWidgetArea, control_dock) self.addDockWidget(Qt.LeftDockWidgetArea, info_dock) self.addDockWidget(Qt.LeftDockWidgetArea, channels_dock) # Set central widget. self.setCentralWidget(central_widget) # Set window size. if screen_resolution is not None: screen_width = screen_resolution.width() screen_height = screen_resolution.height() self.resize(screen_width, screen_height) # Set window title. self.setWindowTitle("SpyKING Circus ORT - Read 'n' Qt display") print(" ") # TODO remove? def _number_callback(self, number): text = u"{}".format(number) self._info_buffer_value_label.setText(text) text = u"{:8.3f}".format(float(number) * float(self._nb_samples) / self._sampling_rate) self._label_time_value.setText(text) return def _reception_callback(self, data, mads, peaks): self._canvas.on_reception(data, mads, peaks) return def _on_time_changed(self): time = self._dsp_time.value() self._canvas.set_time(time) return def _on_voltage_changed(self): voltage = self._dsp_voltage.value() self._canvas.set_voltage(voltage) return def _on_mads_changed(self): mads = self._dsp_mads.value() self._canvas.set_mads(mads) return def _on_mads_display(self): value = self._display_mads.isChecked() self._canvas.show_mads(value) return def _on_peaks_display(self): value = self._display_peaks.isChecked() self._canvas.show_peaks(value) return def _on_channels_changed(self): self._canvas.set_channels(self._display_list) return def display_spikes_color(self, s): self._canvas.color_spikes(s) def selected_channels(self, max_channel): # print(self._selection_channels.selectedItems()) list_channel = [] for i in range(max_channel): if self._selection_channels.item(i).isSelected(): list_channel.append(i) self._canvas.selected_channels(list_channel) return
class HistoryWidget(QWidget): currentTrackChanged = pyqtSignal(dict) def __init__(self, bbclient, config, parent=None): super(HistoryWidget, self).__init__(parent) self.bbclient = bbclient self.config = config self.track_list = [] self.list = QListWidget(self) self.list.setUniformItemSizes(True) self.list.setSelectionMode(QListWidget.ExtendedSelection) self.list.currentRowChanged.connect(self._onRowChanged) self.delete_btn = QPushButton(QIcon(resource_path('img/delete.png')), '', self) self.save_btn = QPushButton(QIcon(resource_path('img/save.png')), '', self) self.upload_btn = QPushButton(QIcon(resource_path('img/upload.png')), '', self) for i, w in enumerate((self.delete_btn, self.save_btn, self.upload_btn)): w.setIconSize(QSize(22, 22)) if i < 1: w.setMinimumSize(32, 32) w.setMaximumSize(32, 32) else: w.setMinimumSize(58, 32) w.setMaximumSize(58, 32) save_menu = QMenu('Export tracks', self) act = save_menu.addAction('Save as TCX') act.triggered.connect(self._onSaveAsTCX) act = save_menu.addAction('Save as BDX (Bryton GPX extension)') act.triggered.connect(self._onSaveAsBDX) self.save_btn.setMenu(save_menu) upload_menu = QMenu('Upload tracks', self) act = upload_menu.addAction(QIcon(resource_path('img/strava-icon.png')), 'Upload to Strava.com') act.triggered.connect(self._onUploadStrava) act = upload_menu.addAction(QIcon(resource_path('img/bryton-icon.png')), 'Upload to Brytonsport.com') act.triggered.connect(self._onUploadBrytonSport) self.upload_btn.setMenu(upload_menu) self.delete_btn.clicked.connect(self._onDeleteTracks) self._createLayout() self.message_overlay = MessageWidget(self) self.message_overlay.setLoading('Loading tracklist') bbclient.refreshingTrackList.connect(self.message_overlay.show) def setTrackList(self, track_list, device_info): self.list.clear() self.device_info = device_info self.track_list = track_list for track in track_list: item = QListWidgetItem(track['name']) item.setData(TRACK_ITEM_ROLE, track['id']) self.list.addItem(item) self.message_overlay.hide() def resizeEvent(self, event): self.message_overlay.resize(event.size()) super(HistoryWidget, self).resizeEvent(event) def _onDeleteTracks(self): tracks = self._getSelectedTracks() if not tracks: tracks = self.track_list ids = map(lambda t: t['id'], tracks) names = map(lambda t: t['name'], tracks) msg = 'Are you sure you want to delete the following {} track(s):'.format(len(tracks)) msg += '\n' + '\n'.join(names) res = QMessageBox.question(self, 'Delete tracks?', msg, QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Cancel) print res if res == QMessageBox.Ok: print ids # self.bbclient._refreshTrackList() d = ProgressDialog('Finalizing', "Don't close this window\n(It may stall for a little while on 93%)", self) d.progress.setRange(0, 100) d.resize(250, 80) self.bbclient.finalizingProgress.connect(d.progress.setValue) self.bbclient.tracksDeleted.connect(d.accept) def _onFail(): QMessageBox.warning(self, 'Delete failed') d.accept() self.bbclient.deleteFailed.connect(_onFail) self.bbclient.deleteTracks(ids) d.exec_() def _onUploadStrava(self): tracks = self._getSelectedTracks() if not tracks: tracks = self.track_list strava.upload_to_strava(tracks, self.device_info, self, auth_token=self.config.get('strava_auth_token'), password=self.config.get('strava_password'), username=self.config.get('strava_email')) def _onUploadBrytonSport(self): brytonsport.upload_to_brytonsport(self.bbclient, self, username=self.config.get('bryton_email'), password=self.config.get('bryton_password'), session_id=self.config.get('bryton_session_id')) def _onSaveAsTCX(self): tracks = self._getSelectedTracks() if not tracks: tracks = self.track_list # QMessageBox.information(self, 'No tracks selected', 'You need to select the tracks you want to save.') if not tracks: return if len(tracks) == 1: name = QFileDialog.getSaveFileName(self, 'Save file %s' % tracks[0]['name'], self._trackFilename(tracks[0]['name'], 'tcx'), filter='TCX (*.tcx)') if name: self._saveContent(name, tcx.bryton_gpx_to_tcx(tracks[0]['gpx'], pretty=True, device=self.device_info)) else: dir = QFileDialog.getExistingDirectory(self, 'Open Directory', '', QFileDialog.ShowDirsOnly) if not dir: return for t in tracks: name = path.join(str(dir), self._trackFilename(t['name'], 'tcx')) self._saveContent(name, tcx.bryton_gpx_to_tcx(t['gpx'], pretty=True, device=self.device_info)) def _onSaveAsBDX(self): tracks = self._getSelectedTracks() if not tracks: tracks = self.track_list if not tracks: return if len(tracks) == 1: name = QFileDialog.getSaveFileName(self, 'Save file %s' % tracks[0]['name'], self._trackFilename(tracks[0]['name'], 'bdx'), filter='BDX (*.bdx)') if name: self._saveContent(name, tracks[0]['gpx'].toString(pretty=True)) else: dir = QFileDialog.getExistingDirectory(self, 'Open Directory', '', QFileDialog.ShowDirsOnly) if not dir: return for t in tracks: name = path.join(str(dir), self._trackFilename(t['name'], 'gpx')) self._saveContent(name, t['gpx'].toString(pretty=True)) def _saveContent(self, filename, content): with open(filename, 'w') as f: f.write(content) def _trackFilename(self, name, ext): return name.replace('/', '').replace(' ', '-').replace(':', '') + '.' + ext def _getSelectedTracks(self): items = self.list.selectedItems() tracks = [] for item in items: index = self.list.row(item) tracks.append(self.track_list[index]) return tracks def _onRowChanged(self, row): track = self.track_list[row] self.currentTrackChanged.emit(track) def _createLayout(self): l = QVBoxLayout() l.addWidget(self.list) h = QHBoxLayout() h.addWidget(self.delete_btn) h.addStretch() h.addWidget(self.save_btn) h.addWidget(self.upload_btn) l.addLayout(h) self.setLayout(l)
def __init__(self, parent): QSplitter.__init__(self, parent) parent.addPage(self, i18n("Parts")) # The part types overview widget. v = KVBox() self.addWidget(v) QLabel('<b>{0}</b>'.format(i18n("Available parts:")), v) allParts = QTreeWidget(v) addButton = KPushButton(KStandardGuiItem.add(), v) addButton.setToolTip(i18n("Add selected part to your score.")) # The listbox with selected parts v = KVBox() self.addWidget(v) QLabel('<b>{0}</b>'.format(i18n("Score:")), v) score = QListWidget(v) self.score = score # so the partList method can find us h = KHBox(v) removeButton = KPushButton(KStandardGuiItem.remove(), h) upButton = QToolButton(h) upButton.setIcon(KIcon("go-up")) downButton = QToolButton(h) downButton.setIcon(KIcon("go-down")) # The StackedWidget with settings partSettings = QStackedWidget() self.addWidget(partSettings) self.setStretchFactor(0, 1) self.setStretchFactor(1, 1) self.setStretchFactor(2, 1) self.setSizes((100, 100, 100)) allParts.setSelectionMode(QTreeWidget.ExtendedSelection) allParts.setRootIsDecorated(False) allParts.headerItem().setHidden(True) score.setSelectionMode(QListWidget.ExtendedSelection) score.setDragDropMode(QListWidget.InternalMove) class PartItem(QListWidgetItem): """ A part from the score, instantiating a config widget as well. """ def __init__(self, partClass): name = partClass.name() # partClass.name is a ki18n object QListWidgetItem.__init__(self, name, score) self.w = QGroupBox(name) partSettings.addWidget(self.w) self.part = partClass() layout = QVBoxLayout(self.w) self.part.widgets(layout) layout.addStretch(1) if score.count() == 1: score.setCurrentRow(0) self.setSelected(True) parent.enableButton(KPageDialog.Try, True) def showSettingsWidget(self): partSettings.setCurrentWidget(self.w) def remove(self): if score.count() == 1: parent.enableButton(KPageDialog.Try, False) sip.delete(self.w) sip.delete(self) # TODO: check if necessary @allParts.itemDoubleClicked.connect def addPart(item, col): if hasattr(item, "partClass"): PartItem(item.partClass) @allParts.itemClicked.connect def toggleExpand(item, col): item.setExpanded(not item.isExpanded()) @addButton.clicked.connect def addSelectedParts(): for item in allParts.selectedItems(): PartItem(item.partClass) @removeButton.clicked.connect def removeSelectedParts(): for item in score.selectedItems(): item.remove() def keepSel(func): """ Restore the selection and current element after reordering parts. """ def decorator(): selItems = score.selectedItems() curItem = score.currentItem() func() score.setCurrentItem(curItem) for i in selItems: i.setSelected(True) return decorator @upButton.clicked.connect @keepSel def moveUp(): """ Move selected parts up. """ for row in range(1, score.count()): if score.item(row).isSelected(): item = score.takeItem(row) score.insertItem(row - 1, item) @downButton.clicked.connect @keepSel def moveDown(): """ Move selected parts down. """ for row in range(score.count() - 1, -1, -1): if score.item(row).isSelected(): item = score.takeItem(row) score.insertItem(row + 1, item) @score.currentItemChanged.connect def showItem(cur, prev): if cur: cur.showSettingsWidget() from frescobaldi_app.scorewiz.parts import categories for name, parts in categories(): group = QTreeWidgetItem(allParts, [name]) group.setFlags(Qt.ItemIsEnabled) group.setIcon(0, KIcon("inode-directory")) for part in parts: p = QTreeWidgetItem(group, [part.name()]) p.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) p.partClass = part
class TracklistWidget(QWidget): requestUpload = pyqtSignal(list) def __init__(self, parent=None): super(TracklistWidget, self).__init__(parent) self.tracklist = QListWidget(self) self.tracklist.setSelectionMode(QListWidget.NoSelection) self.upload_button = QPushButton( QIcon(resource_path('images/strava-button.png')), 'Upload to Strava', self) self.upload_button.setMinimumHeight(50) self.upload_button.setIconSize(QSize(40, 40)) self.clear_password = QPushButton( QIcon(resource_path('images/cross.png')), 'Clear password', self) self.clear_password.setMinimumHeight(50) self.clear_password.setIconSize(QSize(20, 20)) self.clear_password.hide() self.upload_button.clicked.connect(self._onUploadClicked) self._createLayout() def setTracks(self, tracks): self.tracklist.clear() self.tracklist.addItems(tracks) for i, name in enumerate(tracks): self.tracklist.item(i).setCheckState(Qt.Unchecked) self.tracklist.item(i).setSizeHint(QSize(200, 25)) if tracks: self.tracklist.item(i).setCheckState(Qt.Checked) self.upload_button.setEnabled(True) else: self.upload_button.setEnabled(False) def _onUploadClicked(self): ids = [] for i in range(self.tracklist.count()): item = self.tracklist.item(i) if item.checkState() == Qt.Checked: ids.append(i) if ids: self.requestUpload.emit(ids) def _createLayout(self): l = QVBoxLayout() l.addWidget(self.tracklist) h = QHBoxLayout() h.addWidget(self.upload_button) h.addWidget(self.clear_password) l.addLayout(h) self.setLayout(l)
class ListParameterWidget(GenericParameterWidget): """Widget class for List parameter.""" def __init__(self, parameter, parent=None): """Constructor .. versionadded:: 2.2 :param parameter: A ListParameter object. :type parameter: ListParameter """ super(ListParameterWidget, self).__init__(parameter, parent) self._input = QListWidget() self._input.setSelectionMode(QAbstractItemView.MultiSelection) if self._parameter.maximum_item_count != \ self._parameter.minimum_item_count: tool_tip = 'Select between %d and %d items' % ( self._parameter.minimum_item_count, self._parameter.maximum_item_count) else: tool_tip = 'Select exactly %d items' % ( self._parameter.maximum_item_count) self._input.setToolTip(tool_tip) for opt in self._parameter.options_list: item = QListWidgetItem() item.setFlags(item.flags() | Qt.ItemIsEditable) item.setText(str(opt)) self._input.addItem(item) if opt in self._parameter.value: item.setSelected(True) self.inner_input_layout.addWidget(self._input) # override self._input_layout arrangement to make the label at the top # reset the layout self.input_layout.setParent(None) self.help_layout.setParent(None) self.label.setParent(None) self.inner_input_layout.setParent(None) self.input_layout = QVBoxLayout() self.input_layout.setSpacing(0) # put element into layout self.input_layout.addWidget(self.label) self.input_layout.addLayout(self.inner_input_layout) self.main_layout.addLayout(self.input_layout) self.main_layout.addLayout(self.help_layout) def raise_invalid_type_exception(self): message = 'Expecting element type of %s' % ( self._parameter.element_type.__name__) err = ValueError(message) return err def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A ListParameter from the current state of widget """ selected_value = [] for opt in self._input.selectedItems(): index = self._input.indexFromItem(opt) selected_value.append(self._parameter.options_list[index.row()]) try: self._parameter.value = selected_value except ValueError: err = self.raise_invalid_type_exception() raise err return self._parameter
grade2 = QTreeWidgetItem(treeWidget, grade1) grade2.setText(0, "Grade2") treeWidget.show() #********************* 3. QTableWidget ********************/ # 创建表格部件,同时指定行数和列数 tableWidget = QTableWidget(3, 2) # 创建表格项目,并插入到指定单元 tableWidgetItem = QTableWidgetItem("qt") tableWidget.setItem(1, 1, tableWidgetItem) # 创建表格项目,并将它们作为标头 headerV = QTableWidgetItem("first") tableWidget.setVerticalHeaderItem(0, headerV) headerH = QTableWidgetItem("ID") tableWidget.setHorizontalHeaderItem(0, headerH) tableWidget.show() #/************ 4. 为listWidget启用拖放 *************/ # 设置选择模式为单选 listWidget.setSelectionMode(QAbstractItemView.SingleSelection) # 启用拖动 listWidget.setDragEnabled(True) # 设置接受拖放 listWidget.viewport().setAcceptDrops(True) # 设置显示将要被放置的位置 listWidget.setDropIndicatorShown(True) # 设置拖放模式为移动项目,如果不设置,默认为复制项目 listWidget.setDragDropMode(QAbstractItemView.InternalMove) app.exec_()
class CheckList(HelpedWidget): def __init__(self, model, label="", help_link=""): HelpedWidget.__init__(self, "", help_link) layout = QVBoxLayout() widget = QWidget() widget.setLayout(layout) self.checkAllButton = QToolButton() self.checkAllButton.setIcon(resourceIcon("checked")) self.checkAllButton.setIconSize(QSize(16, 16)) self.checkAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.checkAllButton.setAutoRaise(True) self.checkAllButton.setToolTip("Select all") self.uncheckAllButton = QToolButton() self.uncheckAllButton.setIcon(resourceIcon("notchecked")) self.uncheckAllButton.setIconSize(QSize(16, 16)) self.uncheckAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly) self.uncheckAllButton.setAutoRaise(True) self.uncheckAllButton.setToolTip("Unselect all") self.list = QListWidget() self.list.setContextMenuPolicy(Qt.CustomContextMenu) self.list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.search_box = SearchBox() check_button_layout = QHBoxLayout() check_button_layout.setMargin(0) check_button_layout.setSpacing(0) check_button_layout.addWidget(QLabel(label)) check_button_layout.addStretch(1) check_button_layout.addWidget(self.checkAllButton) check_button_layout.addWidget(self.uncheckAllButton) layout.addLayout(check_button_layout) layout.addWidget(self.list) layout.addWidget(self.search_box) self.addWidget(widget) self.connect(self.checkAllButton, SIGNAL('clicked()'), self.checkAll) self.connect(self.uncheckAllButton, SIGNAL('clicked()'), self.uncheckAll) self.connect(self.list, SIGNAL('itemChanged(QListWidgetItem*)'), self.itemChanged) self.search_box.filterChanged.connect(self.filterList) # self.connect(self.search_box, SIGNAL('filterChanged(str)'), self.filterList) self.connect(self.list, SIGNAL('customContextMenuRequested(QPoint)'), self.showContextMenu) assert isinstance(model, (SelectableModelMixin, ListModelMixin)) self.model = model self.model.observable().attach( SelectableModelMixin.SELECTION_CHANGED_EVENT, self.modelChanged) self.model.observable().attach(ListModelMixin.LIST_CHANGED_EVENT, self.modelChanged) self.modelChanged() def itemChanged(self, item): """@type item: QListWidgetItem""" if item.checkState() == Qt.Checked: self.model.selectValue(str(item.text())) elif item.checkState() == Qt.Unchecked: self.model.unselectValue(str(item.text())) else: raise AssertionError("Unhandled checkstate!") def modelChanged(self): self.list.clear() items = self.model.getList() for item in items: list_item = QListWidgetItem(item) list_item.setFlags(list_item.flags() | Qt.ItemIsUserCheckable) if self.model.isValueSelected(item): list_item.setCheckState(Qt.Checked) else: list_item.setCheckState(Qt.Unchecked) self.list.addItem(list_item) self.filterList(self.search_box.filter()) def setSelectionEnabled(self, enabled): self.setEnabled(enabled) self.checkAllButton.setEnabled(enabled) self.uncheckAllButton.setEnabled(enabled) def filterList(self, filter): filter = filter.lower() for index in range(0, self.list.count()): item = self.list.item(index) text = str(item.text()).lower() if filter == "": item.setHidden(False) elif filter in text: item.setHidden(False) else: item.setHidden(True) def checkAll(self): self.model.selectAll() def uncheckAll(self): self.model.unselectAll() def checkSelected(self): items = [] for item in self.list.selectedItems(): items.append(str(item.text())) for item in items: self.model.selectValue(item) def uncheckSelected(self): items = [] for item in self.list.selectedItems(): items.append(str(item.text())) for item in items: self.model.unselectValue(item) def showContextMenu(self, point): p = self.list.mapToGlobal(point) menu = QMenu() check_selected = menu.addAction("Check selected") uncheck_selected = menu.addAction("Uncheck selected") menu.addSeparator() clear_selection = menu.addAction("Clear selection") selected_item = menu.exec_(p) if selected_item == check_selected: self.checkSelected() elif selected_item == uncheck_selected: self.uncheckSelected() elif selected_item == clear_selection: self.list.clearSelection()
class SeriesPreview(QDialog): def __init__(self, parent=None): super(SeriesPreview, self).__init__(parent) self.data = None self.workingSet = None self.list = QListWidget() self.cancel = QPushButton('Close') self.apply = QPushButton('Update') self.layout = QGridLayout() self.layout.addWidget(self.list, 0, 0, 1, 2) self.layout.addWidget(self.apply, 1, 0) self.layout.addWidget(self.cancel, 1, 1) self.setLayout(self.layout) self.initComponents() self.initActions() def initComponents(self): self.setWindowFlags(Qt.Tool) self.setWindowTitle("Time series") self.setStyleSheet('''QPushButton { color: #333; border: 1px solid #555; border-radius: 11px; padding: 2px; background: qradialgradient(cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4, radius: 1.35, stop: 0 #fff, stop: 1 #888); min-width: 80px; } QPushButton:hover { color: #fff; background: qradialgradient(cx: 0.3, cy: -0.4, fx: 0.3, fy: -0.4, radius: 1.35, stop: 0 #fff, stop: 1 #bbb);} QPushButton:pressed { background: qradialgradient(cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1, radius: 1.35, stop: 0 #fff, stop: 1 #ddd);} QPushButton:checked { background: qradialgradient(cx: 0.4, cy: -0.1, fx: 0.4, fy: -0.1, radius: 1.35, stop: 0 #fff, stop: 1 #ddd);} QListView::focus { border: 2px solid black; border-radius: 6px; } QScrollBar:vertical { width: 20px; border: 1px solid grey; border-radius: 6px; background-color: transparent; margin: 28px 0 28px 0; } QScrollBar::add-line:vertical { background: transparent; height: 32px; subcontrol-position: bottom; subcontrol-origin: margin; } QScrollBar::sub-line:vertical { background: transparent; height: 32px; subcontrol-position: top; subcontrol-origin: margin; } QScrollBar::up-arrow:vertical { width: 20px; height: 32px; background: transparent; image: url(../res/icons/arrow_up.png); } QScrollBar::up-arrow:hover { bottom: 2px; } QScrollBar::down-arrow:vertical { width: 20px; height: 32px; background: transparent; image: url(../res/icons/arrow_down.png); } QScrollBar::down-arrow:hover { top: 2px; } QScrollBar::handle:vertical { border-radius: 6px; background: url(../res/icons/handle.png) 0% center no-repeat; background-color: white; min-height: 32px; } QScrollBar::handle:hover { background: url(../res/icons/handle_hover.png) 0% center no-repeat; background-color: white; border: 1px solid gray; }''') self.list.setAlternatingRowColors(True) self.list.setStyleSheet('''QListView::item:selected:active { background: qlineargradient(x1: 1, y1: 0, x2: 0, y2: 3, stop: 0 #cbdaf1, stop: 1 #bfcde4); } QListView::item { border: 1px solid #d9d9d9; border-top-color: transparent; border-bottom-color: transparent; } QListView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1); border: 1px solid #bfcde4; }''') self.list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.list.setContextMenuPolicy(Qt.ActionsContextMenu) def initActions(self): self.apply.clicked.connect(self.applyChanges) self.cancel.clicked.connect(self.close) self.list.itemDoubleClicked.connect(self.removeFromList) self.list.addAction(QAction('&Remove selected', self, triggered=self.removeItems)) #--- actions ---# def updateData(self, data): self.data = data self.workingSet = data[0][:] self.updateList() def updateList(self): self.list.clear() for item in self.workingSet: item = QListWidgetItem(str(item)) item.setTextAlignment(Qt.AlignCenter) self.list.addItem(item) def applyChanges(self): self.data = (self.workingSet, self.data[1]) def removeFromList(self, item): self.workingSet.remove(float(item.text())) self.list.takeItem(self.list.indexFromItem(item).row()) def removeItems(self): for item in self.list.selectedItems(): self.workingSet.remove(float(item.text())) self.list.takeItem(self.list.indexFromItem(item).row())
class ProjectPropertiesDialog( QDialog, object ): """ project properties dialog implementation """ def __init__( self, project = None, parent = None ): QDialog.__init__( self, parent ) # The dialog caller reads this member if the dialog was finished # successfully. self.absProjectFileName = None self.__createLayout() self.__project = project if project is None: # It a new project creation self.setWindowTitle( "New Project Properties" ) userRecord = pwd.getpwuid( os.getuid() ) if not userRecord[ 5 ].endswith( os.path.sep ): self.dirEdit.setText( userRecord[ 5 ] + os.path.sep ) else: self.dirEdit.setText( userRecord[ 5 ] ) self.initialDirName = self.dirEdit.text() self.lastProjectName = "" if userRecord[ 4 ] != "": self.authorEdit.setText( userRecord[ 4 ].split( ',' )[ 0 ].strip() ) else: self.authorEdit.setText( userRecord[ 0 ] ) try: self.emailEdit.setText( userRecord[ 0 ] + "@" + socket.gethostname() ) except: pass self.versionEdit.setText( "0.0.1" ) self.licenseEdit.setText( "GPL v3" ) self.copyrightEdit.setText( "Copyright (c) " + self.authorEdit.text() + ", " + str( datetime.date.today().year ) ) self.creationDateEdit.setText( getLocaleDate() ) self.nameEdit.setFocus() elif type( project ) == type( "" ): self.setWindowTitle( "Viewing Project Properties" ) # This is viewing properties and the argument is the path to the # project file scriptName, importDirs, creationDate, author, lic, \ copy_right, description, \ version, email, uuid = getProjectProperties( project ) if not os.path.isabs( scriptName ) and scriptName != "": scriptName = os.path.normpath( os.path.dirname( project ) + os.path.sep + scriptName ) self.nameEdit.setText( os.path.basename( project ) ) self.nameEdit.setToolTip( "" ) self.dirEdit.setText( os.path.dirname( project ) ) self.dirEdit.setToolTip( "" ) self.scriptEdit.setText( scriptName ) self.versionEdit.setText( version ) self.authorEdit.setText( author ) self.emailEdit.setText( email ) self.licenseEdit.setText( lic ) self.copyrightEdit.setText( copy_right ) self.descriptionEdit.setText( description ) self.creationDateEdit.setText( creationDate ) self.uuidEdit.setText( str( uuid ) ) self.uuidEdit.setToolTip( settingsDir + str( uuid ) + os.path.sep + " (double click to copy path)" ) for item in importDirs: self.importDirList.addItem( item ) self.disableEditing() else: self.setWindowTitle( "Editing Project Properties" ) # This is editing the loaded project. self.nameEdit.setText( os.path.basename( project.fileName ) ) self.nameEdit.setToolTip( "" ) self.dirEdit.setText( project.getProjectDir() ) self.dirEdit.setToolTip( "" ) self.scriptEdit.setText( project.getProjectScript() ) self.versionEdit.setText( project.version ) self.authorEdit.setText( project.author ) self.emailEdit.setText( project.email ) self.licenseEdit.setText( project.license ) self.copyrightEdit.setText( project.copyright ) self.descriptionEdit.setText( project.description ) self.creationDateEdit.setText( project.creationDate ) self.uuidEdit.setText( str( project.uuid ) ) self.uuidEdit.setToolTip( project.userProjectDir + " (double click to copy path)" ) self.setReadOnly() for item in project.importDirs: self.importDirList.addItem( item ) if self.importDirList.count() > 0: self.importDirList.setCurrentRow( 0 ) self.delImportDirButton.setEnabled( True ) # The project could be the one belonging to another user # so there might be no write permissions. if not os.access( project.fileName, os.W_OK ): # Disable editing self.setWindowTitle( "Viewing Project Properties (no write permissions)" ) self.disableEditing() else: self.scriptEdit.setFocus() return def __createLayout( self ): """ Creates the dialog layout """ self.resize( 600, 400 ) self.setSizeGripEnabled( True ) verticalLayout = QVBoxLayout( self ) gridLayout = QGridLayout() # Project name nameLabel = QLabel( self ) nameLabel.setText( "Project name:" ) gridLayout.addWidget( nameLabel, 0, 0, 1, 1 ) self.nameEdit = QLineEdit( self ) self.nameEdit.setToolTip( "Type a project name without a path" ) self.nameEdit.installEventFilter( self ) gridLayout.addWidget( self.nameEdit, 0, 1, 1, 1 ) # Project dir dirLabel = QLabel( self ) dirLabel.setText( "Project directory:" ) gridLayout.addWidget( dirLabel, 1, 0, 1, 1 ) self.dirEdit = QLineEdit( self ) self.dirEdit.setToolTip( "Not existed directories will be created" ) gridLayout.addWidget( self.dirEdit, 1, 1, 1, 1 ) self.dirButton = QPushButton( self ) self.dirButton.setText( "..." ) gridLayout.addWidget( self.dirButton, 1, 2, 1, 1 ) self.dirCompleter = DirCompleter( self.dirEdit ) # Project script mainScriptLabel = QLabel( "Main script:", self ) gridLayout.addWidget( mainScriptLabel, 2, 0, 1, 1 ) self.scriptEdit = QLineEdit( self ) self.scriptEdit.setToolTip( "Project main script, " "used when the project is run" ) gridLayout.addWidget( self.scriptEdit, 2, 1, 1, 1 ) self.scriptButton = QPushButton( "...", self ) gridLayout.addWidget( self.scriptButton, 2, 2, 1, 1 ) self.fileCompleter = FileCompleter( self.scriptEdit ) # Import dirs importLabel = QLabel( self ) importLabel.setText( "Import directories:" ) importLabel.setAlignment( Qt.AlignTop ) gridLayout.addWidget( importLabel, 3, 0, 1, 1 ) self.importDirList = QListWidget( self ) self.importDirList.setAlternatingRowColors( True ) self.importDirList.setSelectionMode( QAbstractItemView.SingleSelection ) self.importDirList.setSelectionBehavior( QAbstractItemView.SelectRows ) self.importDirList.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) self.importDirList.setToolTip( "Directories where to look for " "project specific imports" ) gridLayout.addWidget( self.importDirList, 3, 1, 1, 1 ) self.addImportDirButton = QPushButton( self ) self.addImportDirButton.setText( "Add dir" ) self.delImportDirButton = QPushButton( self ) self.delImportDirButton.setText( "Delete dir" ) self.delImportDirButton.setEnabled( False ) vLayout = QVBoxLayout() vLayout.addWidget( self.addImportDirButton ) vLayout.addWidget( self.delImportDirButton ) vLayout.addStretch( 0 ) gridLayout.addLayout( vLayout, 3, 2, 1, 1 ) # Version versionLabel = QLabel( self ) versionLabel.setText( "Version:" ) gridLayout.addWidget( versionLabel, 4, 0, 1, 1 ) self.versionEdit = QLineEdit( self ) gridLayout.addWidget( self.versionEdit, 4, 1, 1, 1 ) # Author authorLabel = QLabel( self ) authorLabel.setText( "Author:" ) gridLayout.addWidget( authorLabel, 5, 0, 1, 1 ) self.authorEdit = QLineEdit( self ) gridLayout.addWidget( self.authorEdit, 5, 1, 1, 1 ) # E-mail emailLabel = QLabel( self ) emailLabel.setText( "E-mail:" ) gridLayout.addWidget( emailLabel, 6, 0, 1, 1 ) self.emailEdit = QLineEdit( self ) gridLayout.addWidget( self.emailEdit, 6, 1, 1, 1 ) # License licenseLabel = QLabel( self ) licenseLabel.setText( "License:" ) gridLayout.addWidget( licenseLabel, 7, 0, 1, 1 ) self.licenseEdit = QLineEdit( self ) gridLayout.addWidget( self.licenseEdit, 7, 1, 1, 1 ) # Copyright copyrightLabel = QLabel( self ) copyrightLabel.setText( "Copyright:" ) gridLayout.addWidget( copyrightLabel, 8, 0, 1, 1 ) self.copyrightEdit = QLineEdit( self ) gridLayout.addWidget( self.copyrightEdit, 8, 1, 1, 1 ) # Description descriptionLabel = QLabel( self ) descriptionLabel.setText( "Description:" ) descriptionLabel.setAlignment( Qt.AlignTop ) gridLayout.addWidget( descriptionLabel, 9, 0, 1, 1 ) self.descriptionEdit = QTextEdit( self ) self.descriptionEdit.setTabChangesFocus( True ) self.descriptionEdit.setAcceptRichText( False ) gridLayout.addWidget( self.descriptionEdit, 9, 1, 1, 1 ) # Creation date creationDateLabel = QLabel( self ) creationDateLabel.setText( "Creation date:" ) gridLayout.addWidget( creationDateLabel, 10, 0, 1, 1 ) self.creationDateEdit = FramedLabelWithDoubleClick() self.creationDateEdit.setToolTip( "Double click to copy" ) gridLayout.addWidget( self.creationDateEdit, 10, 1, 1, 1 ) # Project UUID uuidLabel = QLabel( self ) uuidLabel.setText( "UUID:" ) gridLayout.addWidget( uuidLabel, 11, 0, 1, 1 ) self.uuidEdit = FramedLabelWithDoubleClick( "", self.__copyProjectPath ) gridLayout.addWidget( self.uuidEdit, 11, 1, 1, 1 ) verticalLayout.addLayout( gridLayout ) # Buttons at the bottom buttonBox = QDialogButtonBox( self ) buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Cancel | \ QDialogButtonBox.Ok ) verticalLayout.addWidget( buttonBox ) nameLabel.setBuddy( self.nameEdit ) dirLabel.setBuddy( self.dirEdit ) versionLabel.setBuddy( self.versionEdit ) authorLabel.setBuddy( self.authorEdit ) emailLabel.setBuddy( self.emailEdit ) licenseLabel.setBuddy( self.licenseEdit ) copyrightLabel.setBuddy( self.copyrightEdit ) descriptionLabel.setBuddy( self.descriptionEdit ) buttonBox.accepted.connect( self.onOKButton ) buttonBox.rejected.connect( self.reject ) self.dirButton.clicked.connect( self.onDirButton ) self.scriptButton.clicked.connect( self.onScriptButton ) self.importDirList.currentRowChanged.connect( self.onImportDirRowChanged ) self.addImportDirButton.clicked.connect( self.onAddImportDir ) self.delImportDirButton.clicked.connect( self.onDelImportDir ) self.nameEdit.textEdited.connect( self.onProjectNameChanged ) self.setTabOrder( self.nameEdit, self.dirEdit ) self.setTabOrder( self.dirEdit, self.dirButton ) self.setTabOrder( self.dirButton, self.scriptEdit ) self.setTabOrder( self.scriptEdit, self.scriptButton ) self.setTabOrder( self.scriptButton, self.importDirList ) self.setTabOrder( self.importDirList, self.addImportDirButton ) self.setTabOrder( self.addImportDirButton, self.delImportDirButton ) self.setTabOrder( self.delImportDirButton, self.versionEdit ) self.setTabOrder( self.versionEdit, self.authorEdit ) self.setTabOrder( self.authorEdit, self.emailEdit ) self.setTabOrder( self.emailEdit, self.licenseEdit ) self.setTabOrder( self.licenseEdit, self.copyrightEdit ) self.setTabOrder( self.copyrightEdit, self.descriptionEdit ) self.setTabOrder( self.descriptionEdit, buttonBox ) return def eventFilter( self, obj, event ): " Event filter for the project name field " # Do not allow path separators if event.type() == QEvent.KeyPress: if event.key() == ord( os.path.sep ): return True return QObject.eventFilter( self, obj, event ) def onDirButton( self ): " Displays a directory selection dialog " dirName = QFileDialog.getExistingDirectory( self, "Select project directory", self.dirEdit.text(), QFileDialog.Options( QFileDialog.ShowDirsOnly ) ) if dirName: self.dirEdit.setText( os.path.normpath( dirName ) ) return def onScriptButton( self ): " Displays a file selection dialog " scriptName = QFileDialog.getOpenFileName( self, "Select project main script", self.dirEdit.text() ) if scriptName: self.scriptEdit.setText( os.path.normpath( scriptName ) ) return def onImportDirRowChanged( self, row ): " Triggered when a current row in the import dirs is changed " self.delImportDirButton.setEnabled( row != -1 ) return def onAddImportDir( self ): " Displays a directory selection dialog " dirName = QFileDialog.getExistingDirectory( self, "Select import directory", self.dirEdit.text(), QFileDialog.Options( QFileDialog.ShowDirsOnly ) ) if not dirName: return # There are 2 cases: new project or # editing the existed project properties if self.__project is None: # It a new project; the project path could be editedd dirToInsert = dirName else: # This is an existed project; no way the project path is changed # Let's decide it a relative path should be used here if self.__project.isProjectDir( dirName ): dirToInsert = relpath( dirName, self.dirEdit.text() ) else: dirToInsert = dirName index = 0 while index < self.importDirList.count(): if self.importDirList.item( index ).text() == dirToInsert: logging.warning( "The directory '" + dirName + "' is already in the list of " "imported directories and is not added." ) return index += 1 self.importDirList.addItem( dirToInsert ) self.importDirList.setCurrentRow( self.importDirList.count() - 1 ) return def onDelImportDir( self ): " Triggered when an import dir should be deleted " rowToDelete = self.importDirList.currentRow() if rowToDelete == -1: self.delImportDirButton.setEnabled( False ) return self.importDirList.takeItem( rowToDelete ) if self.importDirList.count() == 0: self.delImportDirButton.setEnabled( False ) else: self.importDirList.setCurrentRow( self.importDirList.count() - 1 ) return def onOKButton( self ): " Checks that the mandatory fields are filled properly " # The checks must be done for a new project only if not self.nameEdit.isEnabled(): self.accept() return # Check that the project name does not have path separators and is not # empty if not self.nameEdit.text().strip(): QMessageBox.critical( self, "Error", "The project name must not be empty" ) return if os.path.sep in self.nameEdit.text(): QMessageBox.critical( self, "Error", "The project name must not " "contain path separators" ) return # Check that the project directory is given dirName = self.dirEdit.text().strip() if not dirName: QMessageBox.critical( self, "Error", "The project directory must not be empty" ) return dirName = os.path.abspath( dirName ) self.dirEdit.setText( dirName ) # Check that the project file does not exist projectFileName = dirName if not projectFileName.endswith( os.path.sep ): projectFileName += os.path.sep projectFileName += self.nameEdit.text().strip() if not projectFileName.endswith( ".cdm" ): projectFileName += ".cdm" if os.path.exists( projectFileName ): QMessageBox.critical( self, "Error", "The project file " + projectFileName + " exists. Please provide another " "directory / project name." ) return # Check that the project dir is not a file if os.path.exists( dirName ): # It might be a link, so read it first dirName = os.path.realpath( dirName ) if not os.path.exists( dirName ): QMessageBox.critical( self, "Error", "Broken link: " + dirName ) return if not os.path.isdir( dirName ): QMessageBox.critical( self, "Error", "The project directory " "may not be a file" ) return # Check that the dir is writable if not os.access( dirName, os.W_OK ): QMessageBox.critical( self, "Error", "You don't have write permissions on " + dirName ) return else: # Create the directory try: os.makedirs( dirName ) except OSError: QMessageBox.critical( self, "Error", "Cannot create the project directory" ) return # Save the absolute file name for further reading it by the caller self.absProjectFileName = projectFileName # The minimum is provided so we can accept it self.accept() return def onProjectNameChanged( self, newName ): " Called when the project name changed " if newName.endswith( ".cdm" ): newName = newName[ :-4 ] if self.dirEdit.text().strip() == (self.initialDirName + self.lastProjectName): self.dirEdit.setText( self.initialDirName + newName ) self.lastProjectName = newName return def setReadOnly( self ): """ Disables editing some fields """ self.dirEdit.setReadOnly( True ) self.dirEdit.setFocusPolicy( Qt.NoFocus ) self.dirEdit.setDisabled( True ) self.dirButton.setDisabled( True ) self.dirButton.setFocusPolicy( Qt.NoFocus ) self.nameEdit.setReadOnly( True ) self.nameEdit.setFocusPolicy( Qt.NoFocus ) self.nameEdit.setDisabled( True ) return def disableEditing( self ): " Disables all the editing " self.nameEdit.setDisabled( True ) self.dirEdit.setDisabled( True ) self.dirButton.setDisabled( True ) self.scriptEdit.setDisabled( True ) self.scriptButton.setDisabled( True ) self.importDirList.setDisabled( True ) self.addImportDirButton.setDisabled( True ) self.delImportDirButton.setDisabled( True ) self.versionEdit.setDisabled( True ) self.authorEdit.setDisabled( True ) self.emailEdit.setDisabled( True ) self.licenseEdit.setDisabled( True ) self.copyrightEdit.setDisabled( True ) self.descriptionEdit.setDisabled( True ) return def __copyProjectPath( self ): " Copies the project path when a label is double clicked " text = self.uuidEdit.text().strip() if text: path = settingsDir + text + os.path.sep QApplication.clipboard().setText( path ) return
class mainwindow(QtGui.QMainWindow): '''主窗体''' def __init__(self): super(mainwindow, self).__init__() self.setWindowTitle('组件设计工具') self.setWindowIcon(QIcon(':/image/组件设计工具.png')) self.setMinimumWidth(1024) self.setMinimumHeight(800) self.showMaximized() self.menuBar().show() self.createMenus() #self.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint) labelSizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) editSizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) cwVLayout = QVBoxLayout() cwHLayout = QHBoxLayout() lLayout = QVBoxLayout() rLayout = QVBoxLayout() self.lw = QListWidget() self.lw.setSelectionMode(QAbstractItemView.SingleSelection) lLayout.addWidget(self.lw) self.lw.itemSelectionChanged.connect(self.on_select) lGroup = QGroupBox('项目列表') lGroup.setLayout(lLayout) cwHLayout.addWidget(lGroup, 2) lGroup.setContentsMargins(0, 12, 0, 22) tLayout = QVBoxLayout() bLayout = QHBoxLayout() self.tGroup = QGroupBox('配置信息') self.bGroup = QGroupBox('生成代码') self.tGroup.setLayout(tLayout) self.tGroup.setEnabled(False) self.bGroup.setLayout(bLayout) self.bGroup.setEnabled(False) cwHLayout.addWidget(self.tGroup, 8) cwVLayout.addLayout(cwHLayout) cwVLayout.addWidget(self.bGroup) self.tw_config = QTreeWidget() headerLabels = QStringList() headerLabels.append(' 项目') headerLabels.append(' 值') self.tw_config.setHeaderLabels(headerLabels) self.tw_config.setColumnWidth(0, 312) self.tw_config.setColumnWidth(1, 660) thLayout = QHBoxLayout() thLayout.setContentsMargins(0, 6, 0, 0) thLayout.addSpacing(10) modify_btn = QPushButton('') #修改 modify_btn.setObjectName('modify_btn') modify_btn.clicked.connect(self.on_modify) del_btn = QPushButton('') #删除 del_btn.setObjectName('del_btn') del_btn.clicked.connect(self.on_del) thLayout.addWidget(modify_btn) thLayout.addWidget(del_btn) thLayout.addStretch(0) tLayout.addLayout(thLayout) tLayout.addWidget(self.tw_config) bhLayout = QHBoxLayout() lable1 = QLabel('工程名称:') lable1.setSizePolicy(labelSizePolicy) self.et_project_name = QLineEdit() self.et_project_name.setSizePolicy(editSizePolicy) bhLayout.addWidget(lable1) bhLayout.addWidget(self.et_project_name) bhLayout.addSpacing(16) lable2 = QLabel('工程位置:') lable2.setSizePolicy(labelSizePolicy) self.et_project_location = QLineEdit() self.et_project_location.setReadOnly(True) self.et_project_location.setSizePolicy(editSizePolicy) btn_location = QPushButton('') #打开 btn_location.setObjectName('btn_location') btn_location.setSizePolicy(labelSizePolicy) btn_location.clicked.connect(self.getProjectLocation) bhLayout.addWidget(lable2) bhLayout.addWidget(self.et_project_location) bhLayout.addSpacing(10) bhLayout.addWidget(btn_location) #bhLayout.addStretch(0) gen_btn = QPushButton('') # 生成 gen_btn.setObjectName('gen_btn') gen_btn.setSizePolicy(labelSizePolicy) gen_btn.clicked.connect(self.on_gen) bhLayout.addSpacing(45) bhLayout.addWidget(gen_btn) bLayout.addLayout(bhLayout) bLayout.setContentsMargins(10, 24, 22, 34) statusBar = self.statusBar() sBH = QHBoxLayout() copyright = QLabel('') copyright.setAlignment(QtCore.Qt.AlignCenter) copyright.setStyleSheet("color:#acacac") statusBar.setMinimumHeight(30) statusBar.addWidget(copyright, 10) cw = QWidget() cw.setLayout(cwVLayout) self.setCentralWidget(cw) self._initByConfig() self.setMinimumSize(400, 200) def _initByConfig(self): '''初始化''' pass def createMenus(self): '''创建菜单''' self.ToolBar = self.addToolBar('') self.ToolBar.setMinimumHeight(54) newBtn = QToolButton() newBtn.setText('创建项目') newBtn.setIcon(QIcon(':/image/创建项目.png')) newBtn.setToolButtonStyle(3) newBtn.setFixedWidth(99) OpenBtn = QToolButton() OpenBtn.setText('打开项目') OpenBtn.setIcon(QIcon(':/image/打开.png')) OpenBtn.setToolButtonStyle(3) OpenBtn.setFixedWidth(99) AboutBtn = QToolButton() AboutBtn.setText('关于') AboutBtn.setIcon(QIcon(':/image/关于.png')) AboutBtn.setToolButtonStyle(3) AboutBtn.setFixedWidth(99) HelpBtn = QToolButton() HelpBtn.setText('帮助') HelpBtn.setIcon(QIcon(':/image/帮助.png')) HelpBtn.setToolButtonStyle(3) HelpBtn.setFixedWidth(99) newBtn.clicked.connect(self.on_new) OpenBtn.clicked.connect(self.on_open) AboutBtn.clicked.connect(self.on_about) HelpBtn.clicked.connect(self.on_help) self.ToolBar.addWidget(newBtn) self.ToolBar.addWidget(OpenBtn) self.ToolBar.addWidget(AboutBtn) self.ToolBar.addWidget(HelpBtn) self.ToolBar.setMovable(False) self.ToolBar.setVisible(True) def on_help(self): app.g_pwd = os.getcwd() if not (QtGui.QDesktopServices.openUrl( QUrl.fromLocalFile(app.g_pwd + os.sep + 'image' + os.sep + 'help.pdf'))): print app.g_pwd + os.sep + '/image/help.pdf' QMessageBox.critical(None, "Failure", "Cannot open help manual") def on_about(self): abt = AboutDlg() abt.exec_() def on_new(self): '''新建向导''' app.g_configurations = Configuration() # 用来渲染的配置数据 dlg = wizard.MyWizard() if dlg.exec_(): app.g_configurations.initialized = True app.g_projects.append(app.g_configurations) content = app.g_configurations.toJson() self.path = QFileDialog.getSaveFileName( self, "选择模板保存的路径", app.g_pwd + os.sep + "configurations" + os.sep + app.g_configurations.project_name.encode('utf-8') + ".json", "Config (*.json)") fileInfo = QFileInfo(self.path) if not self.path.isEmpty(): path = app.QString2str(self.path) with open(path, 'w+') as f: f.write(content) self.addConfig(fileInfo.baseName(), fileInfo.filePath(), content) #self.lw.addItem(app.g_configurations.project_name) def getProjectLocation(self): '''获取项目路径''' path = QFileDialog.getExistingDirectory() path = QDir.fromNativeSeparators(path) self.et_project_location.setText(path) def on_open(self): '''打开现有配置''' fileName = QFileDialog.getOpenFileName( self, "选择现有模板", app.g_pwd + os.sep + "configurations", "Config (*.json)") if fileName.isEmpty(): return self.path = fileName with open(app.QString2str(fileName), 'r') as f: content = f.read() fileInfo = QFileInfo(fileName) if not fileInfo.exists(): return config = Configuration() config.fromJson(content) config.allone_dir = os.getenv('ALLONEDIR', '../..').replace('\\', '/') self.addConfig(fileInfo.baseName(), fileInfo.filePath(), content) self.on_select() def on_del(self): self.tw_config.clear() self.bGroup.setEnabled(False) self.tGroup.setEnabled(False) index = self.lw.currentRow() self.lw.takeItem(index) def on_select(self): '''选取配置''' item = self.lw.currentItem() if item != None: content = item.data(QtCore.Qt.UserRole).toString() config = Configuration() config.fromJson(app.QString2str(content)) self.currentConfig = config self.showConfigInfo(self.currentConfig) self.bGroup.setEnabled(True) self.path = item.data(QtCore.Qt.UserRole + 1).toString() # index = self.lw.currentRow() # if index < len(app.g_projects): # self.currentConfig = app.g_projects[index] # self.showConfigInfo(self.currentConfig) # self.bGroup.setEnabled(True) def addConfig(self, fileName, filePath, config): item = QListWidgetItem(fileName) item.setData(QtCore.Qt.UserRole, config) item.setData(QtCore.Qt.UserRole + 1, filePath) self.lw.addItem(item) self.lw.setCurrentRow(0) def showConfigInfo(self, cf): '''显示配置信息''' self.tw_config.clear() self.et_project_name.setText(cf.project_name) self.et_project_location.setText(cf.project_location) sr = QStringList() sr.append('信息') root1 = QTreeWidgetItem(sr) sr = QStringList() sr.append('Qt库') root2 = QTreeWidgetItem(sr) sr = QStringList() sr.append('模块') root3a = QTreeWidgetItem(sr) sr = QStringList() sr.append('第三方库') root3b = QTreeWidgetItem(sr) sr = QStringList() sr.append('接口') root4 = QTreeWidgetItem(sr) self.tw_config.addTopLevelItem(root1) self.tw_config.addTopLevelItem(root2) self.tw_config.addTopLevelItem(root3a) self.tw_config.addTopLevelItem(root3b) self.tw_config.addTopLevelItem(root4) sr1c00 = QStringList() sr1c00.append("项目名称") sr1c00.append(cf.project_name) r1c00 = QTreeWidgetItem(sr1c00) root1.addChild(r1c00) # sr1c0 = QStringList() # sr1c0.append("项目位置") # sr1c0.append(cf.project_location) # r1c0 = QTreeWidgetItem(sr1c0) # root1.addChild(r1c0) sr1c1 = QStringList() sr1c1.append("组件类型") sr1c1.append(cf.component_type) r1c1 = QTreeWidgetItem(sr1c1) root1.addChild(r1c1) sr1c2 = QStringList() sr1c2.append("源模板") sr1c2.append(cf.template_source) r1c2 = QTreeWidgetItem(sr1c2) root1.addChild(r1c2) sr1c3 = QStringList() sr1c3.append("平台类型") tmp_pt = "" if cf.platform_type & configuration.PT_WIN32: tmp_pt += "win32;" if cf.platform_type & configuration.PT_LINUX: tmp_pt += "linux" sr1c3.append(tmp_pt) r1c3 = QTreeWidgetItem(sr1c3) root1.addChild(r1c3) sr1c4 = QStringList() sr1c4.append("平台级别") sr1c4.append(cf.platform_version) r1c4 = QTreeWidgetItem(sr1c4) root1.addChild(r1c4) sr1c5 = QStringList() sr1c5.append("资源文件") if cf.resourcesFile == "True": sr1c5.append("添加") else: sr1c5.append("未添加") r1c5 = QTreeWidgetItem(sr1c5) root1.addChild(r1c5) sr1c6 = QStringList() sr1c6.append("翻译文件") if cf.translateFile == "True": sr1c6.append("添加") else: sr1c6.append("未添加") r1c6 = QTreeWidgetItem(sr1c6) root1.addChild(r1c6) for qt in cf.qt_libs: sr2 = QStringList() sr2.append(qt['name']) sr2.append(qt['qt']) r2 = QTreeWidgetItem(sr2) root2.addChild(r2) for module in cf.modules: sr3a = QStringList() sr3a.append(module['name']) sr3a.append(module['description']) r3a = QTreeWidgetItem(sr3a) root3a.addChild(r3a) # sr3b = QStringList() # sr3b.append('ALLONE_DIR') # sr3b.append(os.getenv('ALLONEDIR','../..')) # 第二个参数是默认值 # r3b = QTreeWidgetItem(sr3b) # root3b.addChild(r3b) for info in cf.thirdpart_lib: sr3b = QStringList() sr3b.append(info['libname']) sr3b.append(info['libpath']) r3b = QTreeWidgetItem(sr3b) root3b.addChild(r3b) for key in cf.interfaces.keys(): sr4 = QStringList() sr4.append(key) if cf.interfaces[key]: sr4.append('实现') else: sr4.append('未实现') r4 = QTreeWidgetItem(sr4) root4.addChild(r4) self.tw_config.expandAll() self.tw_config.header().resizeSection(0, 300) self.tGroup.setEnabled(True) def on_modify(self): '''修改配置''' if self.currentConfig: app.g_configurations = copy.copy(self.currentConfig) dlg = wizard.MyWizard() if dlg.exec_(): item = self.lw.currentItem() if item != None: content = app.g_configurations.toJson() item.setData(QtCore.Qt.UserRole, content) path = item.data(QtCore.Qt.UserRole + 1).toString() if not path.isEmpty(): path = app.QString2str(path) with open(path, 'w+') as f: f.write(content) self.on_select() def on_gen(self): '''生成工程''' if not self.currentConfig: return #获取工程名及有效路径 project_name = self.et_project_name.text() project_location = self.et_project_location.text() qdir = QDir(project_location) if not qdir.exists(): if not qdir.mkpath(project_location): QMessageBox.warning(self, '警告', '路径无效!') return project_location = qdir.absolutePath() if not project_location.endsWith( '/') and not project_location.endsWith('\\'): project_location += os.sep project_location.replace('\\', '/') if project_name.isEmpty() or project_location.isEmpty(): QMessageBox.warning(self, '警告', '项目名称或路径不能为空!') return self.currentConfig.project_name = app.QString2str(project_name) self.currentConfig.project_location = app.QString2str(project_location) content = self.currentConfig.toJson() fileInfo = QFileInfo(self.path) if not self.path.isEmpty(): path = app.QString2str(self.path) with open(path, 'w+') as f: f.write(content) item = self.lw.currentItem() item.setData(QtCore.Qt.UserRole, content) template_name = self.currentConfig.template_source template_dir = app.g_pwd + os.sep + 'templates' + os.sep + template_name.encode( 'utf-8') with open(template_dir + os.sep + 'config.json', 'r') as f: self.currentConfig.config_content = f.read() ret_json = app.render(self.currentConfig.config_content, config=self.currentConfig) self.currentConfig.config = json.loads(ret_json) for file in self.currentConfig.config['files']: sourcepath = template_dir + os.sep + file['source'].encode('utf-8') targetdir = self.currentConfig.project_location + self.currentConfig.project_name targetpath = targetdir + os.sep + file['target'] fi = QFileInfo(targetpath) qdir = fi.absoluteDir() if not qdir.exists(): qdir.mkpath(fi.absolutePath()) with open(sourcepath, 'r') as f: content = f.read() content = app.render(content, config=self.currentConfig) #渲染文件 with open(targetpath, 'w+') as f: f.write(content.encode('utf-8')) QMessageBox.information(self, '提示', '生成成功!')
class NewChartPage0(QWizardPage): """WizardPage to select chart type and name""" def __init__(self, parent, sensorgroup): QWizardPage.__init__(self, parent) self.setTitle(QCoreApplication.translate('DataStorageBrowser', 'Select type/template of chart')) self.setFinalPage(True) self.sensorgroup = sensorgroup self.mainLayout = QVBoxLayout() self.setLayout(self.mainLayout) layout0 = QHBoxLayout() self.templateSelect = QListWidget(self) self.templateSelect.setSelectionMode(QAbstractItemView.SingleSelection) layout0.addWidget(self.templateSelect) self.templatePreview = QLabel(self) self.templatePreview.setScaledContents(True) self.templatePreview.setMinimumSize(200, 200) self.templatePreview.setMaximumSize(200, 200) self.templatePreview.setFrameStyle(QFrame.Panel|QFrame.Sunken) layout0.addWidget(self.templatePreview) self.mainLayout.addLayout(layout0) self.templateInfo = QTextEdit(self) self.templateInfo.setReadOnly(True) self.templateInfo.setMinimumSize(400, 80) self.mainLayout.addWidget(self.templateInfo) layout1 = QHBoxLayout() nameLabel = QLabel(self) nameLabel.setText(QCoreApplication.translate('DataStorageBrowser', 'Chart name:')) layout1.addWidget(nameLabel) self.nameInput = QLineEdit(self) layout1.addWidget(self.nameInput) self.mainLayout.addLayout(layout1) openChartButton = QCheckBox(self) openChartButton.setChecked(True) openChartButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Open chart window after creation')) self.mainLayout.addWidget(openChartButton) for t in chartTemplates: self.templateSelect.addItem(t.name) self.registerField('templateNumber', self.templateSelect, 'currentRow') self.registerField('chartName', self.nameInput, 'text') self.registerField('openChart', openChartButton, 'checked') self.ownPlugIn = SimuVis4.Globals.plugInManager['DataStorageBrowser'] self.connect(self.templateSelect, SIGNAL("currentRowChanged(int)"), self.templateChanged) self.templateSelect.setCurrentRow(0) def templateChanged(self, i): t = chartTemplates[i] self.templateInfo.setPlainText(t.description) n = t.chartName while n in self.sensorgroup.charts.keys(): n += '_X' self.nameInput.setText(n) if t.previewImage: xpm = QPixmap() path = os.path.join('previewImages', t.previewImage) data = self.ownPlugIn.getFile(path).read() xpm.loadFromData(data) self.templatePreview.setPixmap(xpm) def validatePage(self): i, x = self.field('templateNumber').toInt() n = str(self.field('chartName').toString()) if n in self.sensorgroup.charts.keys(): QMessageBox.warning(self, QCoreApplication.translate('DataStorageBrowser', 'Chart name already exists!'), QCoreApplication.translate('DataStorageBrowser', 'Chart names must be unique. Choose another name or delete existing chart first!')) return False chartTemplates[i].chartName = n return True
class Dialogo(QDialog): def __init__(self, archivos, principal): super(Dialogo, self).__init__(principal) self.setWindowTitle(self.tr("Archivos sin guardar!")) self.principal = principal self.evento_ignorado = False vLayout = QVBoxLayout(self) label = QLabel(self.tr("Algunos archivos no se han guardado, " "selecciona los que \ndeseas guardar:")) vLayout.addWidget(label) hLayout = QHBoxLayout() self.lista = QListWidget() [self.lista.addItem(item) for item in archivos] self.lista.setSelectionMode(QAbstractItemView.ExtendedSelection) hLayout.addWidget(self.lista) layoutBotones = QVBoxLayout() botonTodo = QPushButton(self.tr("Todo")) botonNinguno = QPushButton(self.tr("Ninguno")) botonGuardar = QPushButton(self.tr("Guardar")) botonCancelar = QPushButton(self.tr("Cancelar")) botonNoGuardar = QPushButton(self.tr("No guardar")) layoutBotones.addWidget(botonTodo) layoutBotones.addWidget(botonNinguno) layoutBotones.addWidget(botonGuardar) layoutBotones.addWidget(botonNoGuardar) layoutBotones.addWidget(botonCancelar) hLayout.addLayout(layoutBotones) vLayout.addLayout(hLayout) self.tecla_escape = QShortcut(QKeySequence(Qt.Key_Escape), self) self.connect(self.tecla_escape, SIGNAL("activated()"), self.ignorar) self.connect(botonTodo, SIGNAL("clicked()"), self.seleccionar_todo) self.connect(botonNinguno, SIGNAL("clicked()"), self.deseleccionar) self.connect(botonGuardar, SIGNAL("clicked()"), self.guardar) self.connect(botonNoGuardar, SIGNAL("clicked()"), self.close) self.connect(botonCancelar, SIGNAL("clicked()"), self.ignorar) def ignorar(self): self.evento_ignorado = True self.hide() def ignorado(self): return self.evento_ignorado def seleccionar_todo(self): for item in range(self.lista.count()): self.lista.item(item).setSelected(True) def deseleccionar(self): for item in range(self.lista.count()): self.lista.item(item).setSelected(False) def guardar(self): archivos_seleccionados = self.lista.selectedItems() for archivo in archivos_seleccionados: nombre = archivo.text() self.principal.guardar_seleccionado(nombre) self.close()