class MenuWindow(QMainWindow): def __init__(self): super().__init__() self.href = '/top/' self.file_name = FILE_NAME + '.json' self.window2 = None self.create_main_window() def create_main_window(self): lbl1 = QLabel("Choose needed section", self) lbl1.setGeometry(40, 0, 200, 35) self.sections_combo = QComboBox(self) for ref in _SECTIONS_REF: self.sections_combo.addItem(ref) self.sections_combo.setGeometry(40, 35, 200, 35) lbl2 = QLabel("Choose needed format", self) lbl2.setGeometry(40, 70, 200, 35) self.format_combo = QComboBox(self) for form in _FORMAT: self.format_combo.addItem(form) self.format_combo.setGeometry(40, 105, 200, 35) self.sections_combo.activated[str].connect(self.sections_combo_Activated) self.sections_combo.setCurrentIndex(int(self.sections_combo.findText('За сутки'))) self.format_combo.activated[str].connect(self.format_combo_Activated) self.format_combo.setCurrentIndex(int(self.format_combo.findText('JSON'))) btn1 = QPushButton("GO", self) btn1.setGeometry(40, 140, 200, 35) btn1.clicked.connect(self.buttonClicked) self.setGeometry(300, 300, 300, 200) self.setWindowTitle('Main') self.show() def buttonClicked(self): pars = Parser() if self.window2 is None: self.window2 = OutputWindow(str(pars.parse_site(self.href, self.file_name))) self.window2.show() self.close() def sections_combo_Activated(self, text): self.href = _SECTIONS_REF.get(text) def format_combo_Activated(self, text): self.file_name = FILE_NAME + _FORMAT.get(text)
def initUI(self): self.setAutoFillBackground(True) palette = self.palette() palette.setColor(self.backgroundRole(), QColor('white')) self.setPalette(palette) self.setFrameShape(_frameShape) self.setFrameShadow(_frameShadow) self.setLineWidth(_lineWidth) self.setMidLineWidth(_midLineWidth) return combo = QComboBox(self) self.flist = self.load_list() self.lbl = QLabel('', self) self.descr = QLabel('', self) self.descr.setWordWrap(True) self.onActivated(0) for x in self.flist: combo.addItem(x['name']) combo.move(50, 50) self.lbl.move(50, 150) self.descr.move(150, 50) combo.activated[int].connect(self.onActivated)
class FormComboWidget(QWidget): def __init__(self, datalist, comment="", parent=None): QWidget.__init__(self, parent) layout = QVBoxLayout() self.setLayout(layout) self.combobox = QComboBox() layout.addWidget(self.combobox) self.stackwidget = QStackedWidget(self) layout.addWidget(self.stackwidget) self.combobox.currentIndexChanged[int].connect(self.stackwidget,setCurrentIndex) self.widgetlist = [] for data, title, comment in datalist: self.combobox.addItem(title) widget = FormWidget(data, comment=comment, parent=self) self.stackwidget.addWidget(widget) self.widgetlist.append(widget) def setup(self): for widget in self.widgetlist: widget.setup() def get(self): return [ widget.get() for widget in self.widgetlist]
class FindInFilesActions(QWidget): searchRequested = pyqtSignal('QString', bool, bool, bool) def __init__(self, parent=None): super().__init__(parent) self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored) self._scope = QComboBox() self._scope.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.ninjaide = IDE.get_service('ide') self.ninjaide.filesAndProjectsLoaded.connect( self._update_combo_projects) main_layout = QVBoxLayout(self) hbox = QHBoxLayout() hbox.addWidget(QLabel(translations.TR_SEARCH_SCOPE)) hbox.addWidget(self._scope) main_layout.addLayout(hbox) widgets_layout = QGridLayout() widgets_layout.setContentsMargins(0, 0, 0, 0) self._line_search = QLineEdit() self._line_search.setPlaceholderText(translations.TR_SEARCH_FOR) main_layout.addWidget(self._line_search) # TODO: replace self._check_cs = QCheckBox(translations.TR_SEARCH_CASE_SENSITIVE) self._check_cs.setChecked(True) widgets_layout.addWidget(self._check_cs, 2, 0) self._check_wo = QCheckBox(translations.TR_SEARCH_WHOLE_WORDS) widgets_layout.addWidget(self._check_wo, 2, 1) self._check_re = QCheckBox(translations.TR_SEARCH_REGEX) widgets_layout.addWidget(self._check_re, 3, 0) self._check_recursive = QCheckBox('Recursive') widgets_layout.addWidget(self._check_recursive, 3, 1) main_layout.addLayout(widgets_layout) main_layout.addStretch(1) # Connections self._line_search.returnPressed.connect(self.search_requested) def _update_combo_projects(self): projects = self.ninjaide.get_projects() for nproject in projects.values(): self._scope.addItem(nproject.name, nproject.path) @property def current_project_path(self): """Returns NProject.path of current project""" return self._scope.itemData(self._scope.currentIndex()) def search_requested(self): text = self._line_search.text() if not text.strip(): return has_search = self._line_search.text() cs = self._check_cs.isChecked() regex = self._check_re.isChecked() wo = self._check_wo.isChecked() self.searchRequested.emit(has_search, cs, regex, wo)
def createPaceSelector(self, pace_id=None): selector = QComboBox() # create a combo box for i in range(self.paceSelect.count()): selector.addItem(self.paceSelect.itemText(i)) if pace_id == None: selector.setCurrentIndex(self.paceSelect.currentIndex()) else: selector.setCurrentIndex(pace_id-1) # subtract 1 because comboboxes are indexed starting at 0 selector.currentIndexChanged.connect(self.segmentPaceChanged) # connect to the function that deals with adding the change to the database return selector
class DistanceUSV2(COMCUPluginBase): def __init__(self, *args): super().__init__(BrickletDistanceUSV2, *args) self.dist = self.device self.cbe_distance = CallbackEmulator(self.dist.get_distance, None, self.cb_distance, self.increase_error_count) self.current_distance = CurveValueWrapper() plots = [('Distance', Qt.red, self.current_distance, '{:.1f} cm'.format)] self.plot_widget = PlotWidget('Distance [cm]', plots, y_resolution=1.0) self.update_rate_label = QLabel('Update Rate:') self.update_rate_combo = QComboBox() self.update_rate_combo.addItem(" 2 Hz") self.update_rate_combo.addItem("10 Hz") self.update_rate_combo.currentIndexChanged.connect(self.new_update_rate) hlayout = QHBoxLayout() hlayout.addWidget(self.update_rate_label) hlayout.addWidget(self.update_rate_combo) hlayout.addStretch() layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addLayout(hlayout) def new_update_rate(self): update_rate = self.update_rate_combo.currentIndex() self.dist.set_update_rate(update_rate) def get_update_rate_async(self, update_rate): self.update_rate_combo.setCurrentIndex(update_rate) def start(self): async_call(self.dist.get_update_rate, None, self.get_update_rate_async, self.increase_error_count) self.cbe_distance.set_period(100) self.plot_widget.stop = False def stop(self): self.cbe_distance.set_period(0) self.plot_widget.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletDistanceUSV2.DEVICE_IDENTIFIER def cb_distance(self, distance): self.current_distance.value = distance / 10.0
def createEditor(self, parent, option, index): if index.column() == 1: combo = QComboBox(parent) combo.addItem('') combo.addItems(self._action_list) return combo return super().createEditor(parent, option, index)
class FileChooser(QWidget): fileOpened = pyqtSignal(str) def __init__(self, parent=None): super().__init__(parent) self.folderBox = QComboBox(self) self.explorerTree = FileTreeView(self) self.explorerTree.doubleClickCallback = self._fileOpened self.explorerModel = QFileSystemModel(self) self.explorerModel.setFilter( QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot) self.explorerModel.setNameFilters(["*.py"]) self.explorerModel.setNameFilterDisables(False) self.explorerTree.setModel(self.explorerModel) for index in range(1, self.explorerModel.columnCount()): self.explorerTree.hideColumn(index) self.setCurrentFolder() self.folderBox.currentIndexChanged[int].connect( self.updateCurrentFolder) layout = QVBoxLayout(self) layout.addWidget(self.folderBox) layout.addWidget(self.explorerTree) layout.setContentsMargins(5, 5, 0, 0) def _fileOpened(self, modelIndex): path = self.explorerModel.filePath(modelIndex) if os.path.isfile(path): self.fileOpened.emit(path) def currentFolder(self): return self.explorerModel.rootPath() def setCurrentFolder(self, path=None): if path is None: app = QApplication.instance() path = app.getScriptsDirectory() else: assert os.path.isdir(path) self.explorerModel.setRootPath(path) self.explorerTree.setRootIndex(self.explorerModel.index(path)) self.folderBox.blockSignals(True) self.folderBox.clear() style = self.style() dirIcon = style.standardIcon(style.SP_DirIcon) self.folderBox.addItem(dirIcon, os.path.basename(path)) self.folderBox.insertSeparator(1) self.folderBox.addItem(self.tr("Browse…")) self.folderBox.setCurrentIndex(0) self.folderBox.blockSignals(False) def updateCurrentFolder(self, index): if index < self.folderBox.count() - 1: return path = QFileDialog.getExistingDirectory( self, self.tr("Choose Directory"), self.currentFolder(), QFileDialog.ShowDirsOnly) if path: QSettings().setValue("scripting/path", path) self.setCurrentFolder(path)
def initUI(self): # lineedit self.lbl = QLabel(self) qle = QLineEdit(self) qle.move(20, 30) self.lbl.move(20, 10) qle.textChanged[str].connect(self.onChanged) # combobox self.lbl1 = QLabel('ubuntu', self) combo = QComboBox(self) combo.addItem('ubuntu') combo.addItem('mandriva') combo.addItem('fedora') combo.addItem('arch') combo.addItem('gentoo') combo.move(20, 70) self.lbl1.move(20, 100) combo.activated[str].connect(self.onActivated) self.setGeometry(300, 300, 300, 250) self.setWindowTitle('widget 1') self.show()
class Window(QWidget): """ This part might be removed or included for main window application """ def __init__(self, algorithms): super(Window, self).__init__() self.stackedWidget = QStackedWidget() self.orientationCombo = QComboBox() for category in categories: pass for algorithm in algorithms: self.orientationCombo.addItem(algorithm.get_name()) self.stackedWidget.addWidget(GroupOfSliders(algorithm)) layout = QBoxLayout(QBoxLayout.TopToBottom) settings_layout = QBoxLayout(QBoxLayout.TopToBottom) settings_layout.addWidget(self.stackedWidget) select_layout = QBoxLayout(QBoxLayout.TopToBottom) select_layout.addWidget(self.orientationCombo) layout.addItem(settings_layout) layout.addItem(select_layout) self.setLayout(layout) self.setWindowTitle(algorithm.get_name() + " Settings")
def initUI(self): self.setWindowTitle("QTableWidget 例子") self.resize(430,300); conLayout = QHBoxLayout() tableWidget = QTableWidget() tableWidget.setRowCount(4) tableWidget.setColumnCount(3) conLayout.addWidget(tableWidget ) tableWidget.setHorizontalHeaderLabels(['姓名','性别','体重(kg)']) newItem = QTableWidgetItem("张三") tableWidget.setItem(0, 0, newItem) comBox = QComboBox() comBox.addItem("男") comBox.addItem("女") comBox.setStyleSheet("QComboBox{margin:3px};") tableWidget.setCellWidget(0,1,comBox) searchBtn = QPushButton("修改") searchBtn.setDown( True ) searchBtn.setStyleSheet("QPushButton{margin:3px};") tableWidget.setCellWidget(0, 2, searchBtn) self.setLayout(conLayout)
class IconDropDown(QWidget): entrySelected = pyqtSignal(int) def __init__(self, parentWidget, iconName): QWidget.__init__(self, parentWidget) icon = QLabel(self) icon.setPixmap(QPixmap(iconName)) self.dropdown = QComboBox(self) self.dropdown.activated.connect(self.entrySelected) hLayout = QVBoxLayout(self) hLayout.setContentsMargins(5, 5, 5, 5) self.setLayout(hLayout) hLayout.addWidget(icon, 0, Qt.AlignHCenter) hLayout.addWidget(self.dropdown) def addItem(self, title, tag): self.dropdown.addItem(title, tag) self.dropdown.setCurrentIndex(-1) # TODO - can not set index to -1 before items have been added def setCurrentIndex(self, idx): self.dropdown.setCurrentIndex(idx)
def _add_to_internal_dict(self, element, parent, num_row): QueueModel._add_to_internal_dict(self, element, parent, num_row) if element.tag == "item": # each row gets one combobox for the extension and one for the quality options format_combobox = QComboBox() # see ComboBoxDelegate.createEditor() quality_combobox = QComboBox() # see ComboBoxDelegate.createEditor() self.combo_boxes_format[element] = format_combobox self.combo_boxes_quality[element] = quality_combobox selected_extension = self.getSelectedExtension(element) selected_quality = self.getSelectedQuality(element, selected_extension) for format in element.findall("format"): format_combobox.addItem(format.get("extension")) for option in element.findall("format[@extension='%s']/option" % selected_extension): quality_combobox.addItem(option.get("quality")) format_combobox.setCurrentIndex(format_combobox.findText(selected_extension)) quality_combobox.setCurrentIndex(quality_combobox.findText(selected_quality)) # setup defaults for path and filename if "path" not in element.attrib: path = self.settings.value("DefaultDownloadFolder") element.attrib["path"] = path if "filename" not in element.attrib: filename = self.settings.value("DefaultFileName") # some of the template-filling will happen when an Item is moved to DownloadModel, as # quality and extension will most probably change until then mapping = dict(title=element.get("title"), url=element.get("url"), host=element.get("host")) element.attrib["filename"] = fill_filename_template(filename, mapping)
class GestionEleve(QWidget): def __init__(self,parent=None): super(GestionEleve,self).__init__(parent) #charge la classe en cour self.initClass() palette = QPalette() palette.setColor(QPalette.Text,QColor(128,128,128)) self.leNom = QLineEdit(self) self.leNom.setText("NOM..") self.leNom.setPalette(palette) self.lePrenom = QLineEdit(self) self.lePrenom.setText("PRENOM..") self.lePrenom.setPalette(palette) self.comboSex = QComboBox(self) self.comboSex.addItem("sexe..") self.comboSex.addItem("M") self.comboSex.addItem("F") self.comboClasse = self.initComboClasse(["CE1","CE2"]) self.buttonSave = QPushButton("Save") self.buttonSave.clicked.connect(self.saveEleve) layout = QHBoxLayout() layout.addStretch() layout.addWidget(self.leNom) layout.addWidget(self.lePrenom) layout.addWidget(self.comboSex) layout.addWidget(self.comboClasse) layout.addWidget(self.buttonSave) layout.addStretch() self.setLayout(layout) def initComboClasse(self,list): res = QComboBox() res.addItem("classe..") for elt in list: res.addItem(elt) return res def saveEleve(self): if (self.leNom.text == "NOM.." or self.lePrenom.text == "PRENOM.." or str(self.comboSex.currentText()) == "sexe.." or str(self.comboClasse.currentText()) == "classe.." ): pass #on enregistre pas else : pass #on enregistre def initClass(self): pass
def initUI(self, parent): combo = QComboBox(self) self.title = QLabel(u'Выбор каталога:', self) self.lbl = QLabel('', self) self.descr = QLabel('', self) self.descr.setWordWrap(True) self.descr.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.onActivated(parent, parent.code_int) for x in parent.flist: combo.addItem(x['name']) combo.move(50, 50) self.title.move(5, 25) self.lbl.move(50, 100) self.descr.move(150, 50) def onact(ind): return self.onActivated(parent, ind) combo.activated[int].connect(onact) self.setAutoFillBackground(True) palette = self.palette() palette.setColor(self.backgroundRole(), QColor('white')) self.setPalette(palette) self.setFrameShape(_frameShape) self.setFrameShadow(_frameShadow) self.setLineWidth(_lineWidth) self.setMidLineWidth(_midLineWidth)
def initUI(self): self.setFixedSize(400, 260) self.setWindowTitle('Fomoire!') fomoire = QPixmap(os.path.join('./Pictures/', "fomoire.png")) logo = QLabel(self) logo.setPixmap(fomoire) logo.setFixedSize(fomoire.size()) logo.move(400 / 2 - fomoire.width() / 2, 15) towerDefence = QLabel('A Tower Defence Game', self) towerDefence.move(130, 66) selectMap = QLabel('Select map:', self) selectMap.move(50, 105) mapList = QComboBox(self) mapList.addItem('No map selected') for mapFile in os.listdir('./Maps/'): mapList.addItem(mapFile) mapList.move(135, 102) mapList.activated[str].connect(self.selectMap) setSpeed = QLabel('Set game speed:', self) setSpeed.move(50, 140) slow = QLabel('Slow', self) slow.move(170, 140) slider = QSlider(Qt.Horizontal, self) slider.setFocusPolicy(Qt.NoFocus) slider.setSliderPosition(100 - self.gameSpeed) slider.setGeometry(210, 140, 100, 20) slider.valueChanged[int].connect(self.changeGameSpeed) fast = QLabel('Fast', self) fast.move(325, 140) start = QPushButton('Start game!', self) start.move(145, 175) start.clicked[bool].connect(self.startGame) quitButton = QPushButton('Quit', self) quitButton.move(168, 210) quitButton.clicked[bool].connect(qApp.quit) barbarian = QLabel(self) brbr = QPixmap(os.path.join('./Pictures/', "barbarian.png")) barbarian.setPixmap(brbr) barbarian.move(70, 185) berserker = QLabel(self) berber = QPixmap(os.path.join('./Pictures/', "berserker_left.png")) berserker.setPixmap(berber) berserker.move(290, 185) self.show()
def __init__(self, parent=None): super(ConfigurationPage, self).__init__(parent) configGroup = QGroupBox("Server configuration") serverLabel = QLabel("Server:") serverCombo = QComboBox() serverCombo.addItem("Trolltech (Australia)") serverCombo.addItem("Trolltech (Germany)") serverCombo.addItem("Trolltech (Norway)") serverCombo.addItem("Trolltech (People's Republic of China)") serverCombo.addItem("Trolltech (USA)") serverLayout = QHBoxLayout() serverLayout.addWidget(serverLabel) serverLayout.addWidget(serverCombo) configLayout = QVBoxLayout() configLayout.addLayout(serverLayout) configGroup.setLayout(configLayout) mainLayout = QVBoxLayout() mainLayout.addWidget(configGroup) mainLayout.addStretch(1) self.setLayout(mainLayout)
class AddItemDialog(QDialog): def __init__(self): super(AddItemDialog, self).__init__() self.setupUi(self) def setupUi(self, AddItemDialog): self.item_type_picker = QComboBox() self.item_properties_switch = QStackedWidget() for form in FORMS: self.item_type_picker.addItem(form.__name__.split('_')[0], FORMS.index(form)) self.item_properties_switch.addWidget(form()) self.item_type_picker.currentIndexChanged.connect( self.item_properties_switch.setCurrentIndex) self.add_button = QPushButton("Add") mainLayout = QVBoxLayout(self) mainLayout.addWidget(self.item_type_picker) mainLayout.addWidget(self.item_properties_switch, 1) mainLayout.addWidget(self.add_button) self.add_button.clicked.connect(self.add_item) self.setWindowIcon(QIcon(QPixmap('hotel_icon.jpg'))) self.layout().setSizeConstraint(QLayout.SetFixedSize) self.setWindowTitle("Add Items") def add_item(self): self.item_properties_switch.currentWidget().add_button_click()
def __init__(self, parent, configuration): QTableWidget.__init__(self, 5, 1, parent) self._configuration = configuration self._manual_change = True self.setVerticalHeaderLabels( ["Duration (cycles)", "Duration (ms)", "Cycles / ms", 'RAM access time', 'Execution Time Model']) self.horizontalHeader().setStretchLastSection(True) self.horizontalHeader().hide() self.setItem(0, 0, QTableWidgetItem(str(configuration.duration))) self.setItem(1, 0, QTableWidgetItem(str( float(configuration.duration) / configuration.cycles_per_ms))) self.setItem(2, 0, QTableWidgetItem(str(configuration.cycles_per_ms))) self.setItem( 3, 0, QTableWidgetItem(str(configuration.memory_access_time))) item = QComboBox(self) selected = 0 for i, (etm_name, etm_code) in \ enumerate(execution_time_model_names.items()): item.addItem(etm_name) if etm_code == configuration.etm: selected = i item.setCurrentIndex(selected) self.setCellWidget(4, 0, item) def activation_handler(x): configuration.etm = execution_time_model_names[str(x)] configuration.conf_changed() item.activated['QString'].connect(activation_handler) # self._update_observe_window() self.cellChanged.connect(self._cell_changed)
def createDesktopOption(self, layout): hlayout = QHBoxLayout() layout.addLayout(hlayout) vlayout1 = QVBoxLayout() vlayout2 = QVBoxLayout() hlayout.addLayout(vlayout1) hlayout.addLayout(vlayout2) label1 = QLabel() label1.setText(self.tr("Desktop Type")) vlayout1.addWidget(label1) label2 = QLabel() label2.setText(self.tr("Number of Desktops")) vlayout2.addWidget(label2) comboBox = QComboBox() comboBox.addItem(self.tr("Desktop View")) comboBox.addItem(self.tr("Folder View")) comboBox.currentIndexChanged.connect(self.desktopTypeCreate) vlayout1.addWidget(comboBox) spinBox = QSpinBox() spinBox.setMinimum(1) spinBox.setMaximum(20) spinBox.valueChanged.connect(self.desktopCreate) vlayout2.addWidget(spinBox)
class ModeSelectionToolbar(QToolBar): switch_mode = pyqtSignal(str) def __init__(self, network_handler): super().__init__("Mode selection") self._nh = network_handler mode_text = QLabel() mode_text.setText("Select mode:") self._mode_selection = QComboBox() self._mode_selection.setMinimumWidth(100) self._mode_selection.setMaximumWidth(140) self._mode_selection.addItem("RC") self._mode_selection.addItem("GPS") self.addWidget(mode_text) self.addWidget(self._mode_selection) self.addAction("Select", self._send_mode) @QtCore.pyqtSlot() def _send_mode(self): mode = self._mode_selection.currentText() self.switch_mode.emit(mode) if mode == "RC": command = "START_PROG_RC" elif mode == "GPS": command = "START_PROG_GPS" else: command = "START_PROG_RC" self._nh.send_command(command)
def initoptionspanel(self): label = QLabel('Filter') filtertype = QComboBox() filtertype.addItem('None') filtertype.addItem('Lowpass') filtertype.addItem('Highpass') filtertype.addItem('Bandreject') filtertype.addItem('Bandpass') filtertype.currentIndexChanged.connect(self.filtertypelistener) self.filterfunction = QComboBox() self.filterfunction.addItem('Ideal') self.filterfunction.addItem('Butterworth') self.filterfunction.addItem('Gaussian') self.filterfunction.currentIndexChanged.connect(self.filterfunctionlistener) self.filterfunction.setEnabled(False) self.filtercutoff = QDoubleSpinBox() self.filtercutoff.setValue(0.0) self.filtercutoff.setRange(0.0, 10000.0) self.filtercutoff.valueChanged.connect(self.filtercutofflistener) self.filtercutoff.setEnabled(False) self.filterbandwidth = QDoubleSpinBox() self.filterbandwidth.setValue(1.0) self.filterbandwidth.setRange(0.0, 10000.0) self.filterbandwidth.valueChanged.connect(self.filterbandwidthlistener) self.filterbandwidth.setEnabled(False) self.filterorder = QDoubleSpinBox() self.filterorder.setValue(1.0) self.filterorder.setRange(0.0, 10000.0) self.filterorder.valueChanged.connect(self.filterorderlistener) self.filterorder.setEnabled(False) loader = QMovie('loader.gif') loader.start() self.loadercontainer = QLabel() self.loadercontainer.setMovie(loader) self.loadercontainer.setVisible(False) formlayout = QFormLayout() formlayout.addRow('Type', filtertype) formlayout.addRow('Function', self.filterfunction) formlayout.addRow('Cut off', self.filtercutoff) formlayout.addRow('Bandwidth', self.filterbandwidth) formlayout.addRow('Order', self.filterorder) formlayout.addRow('', self.loadercontainer) filterbox = QGroupBox('Filter') filterbox.setLayout(formlayout) options = QDockWidget('Options') options.setFeatures(QDockWidget.DockWidgetFloatable) options.setFeatures(QDockWidget.DockWidgetMovable) options.setWidget(filterbox) self.addDockWidget(Qt.RightDockWidgetArea, options)
def __init__(self, title, numVar, numCons, typeVar, objCrit, parent=None): super(InputTableModel, self).__init__(parent) self.problem = None self.problemTitle = title self.numVariables = numVar self.numConstraints = numCons self.objCriterion = objCrit self.typeVariable = typeVar self.tableModel = QTableWidget(self.numConstraints+1, self.numVariables+2) self.tableModel.setItemDelegate(Delegate(self)) listVariables = [] for m in range(self.numVariables): listVariables.append("X"+str(m)) listVariables.extend(["Direction","R.H.S"]) #Generar Filas listConstraints = ["Objetive"] for m in range(self.numConstraints): listConstraints.append("C"+str(m)) combo = QComboBox() combo.addItem('<') combo.addItem('<=') combo.addItem('=') combo.addItem('>=') combo.addItem('>') self.tableModel.setCellWidget(m+1, self.numVariables, combo) #listConstraints.extend(["LowerBound","UpperBound", "VariableType"]) self.tableModel.setCellWidget(0, self.numVariables, QLabel("")) self.tableModel.setHorizontalHeaderLabels(listVariables) self.tableModel.setVerticalHeaderLabels(listConstraints) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.verify) buttonBox.rejected.connect(self.reject) f = "Problem Title: " if self.objCriterion == True: f = f + self.problemTitle + " - Objetive: Maximitation" else: f = f + self.problemTitle + " - Objetive: Minimization" t = QLabel(f) mainLayout = QVBoxLayout() mainLayout.addWidget(t) mainLayout.addWidget(self.tableModel) mainLayout.addWidget(buttonBox) width = self.tableModel.columnWidth(1)*(self.tableModel.columnCount()+1) height = self.tableModel.rowHeight(0)*(self.tableModel.rowCount()+4) self.resize(QSize(width, height)) self.setWindowTitle("Input Problem Model") self.setLayout(mainLayout)
class SubFileDialog(QFileDialog): def __init__(self, parent = None, caption = "", directory = "", filter = ""): super().__init__(parent, caption, directory, filter) self.setOption(QFileDialog.DontUseNativeDialog) def _initAllSubFormats(self, formatList): self._formats = {} for f in formatList: self._formats[f.NAME] = f def _addEncodingsBox(self, row, addAuto): mainLayout = self.layout() encodingLabel = QLabel(_("File encoding:"), self) self._encodingBox = QComboBox(self) if addAuto is True: self._encodingBox.addItem(AUTO_ENCODING_STR) self._encodingBox.addItems(ALL_ENCODINGS) self._encodingBox.setToolTip(_("Change file encoding")) self._encodingBox.setEditable(True) mainLayout.addWidget(encodingLabel, row, 0) mainLayout.addWidget(self._encodingBox, row, 1) def _addFormatBox(self, row, formatList): self._initAllSubFormats(formatList) displayedFormats = list(self._formats.keys()) displayedFormats.sort() mainLayout = self.layout() formatLabel = QLabel(_("Subtitle format:"), self) self._formatBox = QComboBox(self) self._formatBox.addItems(displayedFormats) mainLayout.addWidget(formatLabel, row, 0) mainLayout.addWidget(self._formatBox, row, 1) def getEncoding(self): encoding = self._encodingBox.currentText() if encoding == AUTO_ENCODING_STR: encoding = None return encoding def setEncoding(self, encoding): index = self._encodingBox.findText(encoding) self._encodingBox.setCurrentIndex(index) def getSubFormat(self): return self._formats.get(self._formatBox.currentText()) def setSubFormat(self, subFormat): for key, val in self._formats.items(): if val == subFormat: index = self._formatBox.findText(key) self._formatBox.setCurrentIndex(index) return
def __init__(self, *args): COMCUPluginBase.__init__(self, BrickletIndustrialQuadRelayV2, *args) self.setupUi(self) self.iqr = self.device self.open_pixmap = load_masked_pixmap('plugin_system/plugins/industrial_quad_relay/relay_open.bmp') self.close_pixmap = load_masked_pixmap('plugin_system/plugins/industrial_quad_relay/relay_close.bmp') self.relay_buttons = [self.b0, self.b1, self.b2, self.b3] self.relay_button_icons = [self.b0_icon, self.b1_icon, self.b2_icon, self.b3_icon] self.relay_button_labels = [self.b0_label, self.b1_label, self.b2_label, self.b3_label] for icon in self.relay_button_icons: icon.setPixmap(self.open_pixmap) icon.show() for i in range(len(self.relay_buttons)): self.relay_buttons[i].clicked.connect(functools.partial(self.relay_button_clicked, i)) self.monoflop_values = [] self.monoflop_times = [] for i in range(4): self.monoflop_channel.setItemData(i, i) monoflop_value = QComboBox() monoflop_value.addItem('On', True) monoflop_value.addItem('Off', False) self.monoflop_values.append(monoflop_value) self.monoflop_value_stack.addWidget(monoflop_value) monoflop_time = QSpinBox() monoflop_time.setRange(1, (1 << 31) - 1) monoflop_time.setValue(1000) self.monoflop_times.append(monoflop_time) self.monoflop_time_stack.addWidget(monoflop_time) self.monoflop = Monoflop(self.iqr, [0, 1, 2, 3], self.monoflop_values, self.cb_value_change_by_monoflop, self.monoflop_times, None, self) self.monoflop_channel.currentIndexChanged.connect(self.monoflop_channel_changed) self.monoflop_go.clicked.connect(self.monoflop_go_clicked) self.cbox_cs0_cfg.currentIndexChanged.connect(self.cbox_cs0_cfg_changed) self.cbox_cs1_cfg.currentIndexChanged.connect(self.cbox_cs1_cfg_changed) self.cbox_cs2_cfg.currentIndexChanged.connect(self.cbox_cs2_cfg_changed) self.cbox_cs3_cfg.currentIndexChanged.connect(self.cbox_cs3_cfg_changed)
def createLegendBox(self): legendComboBox = QComboBox() legendComboBox.addItem("No Legend ", 0) legendComboBox.addItem("Legend Top", Qt.AlignTop) legendComboBox.addItem("Legend Bottom", Qt.AlignBottom) legendComboBox.addItem("Legend Left", Qt.AlignLeft) legendComboBox.addItem("Legend Right", Qt.AlignRight) return legendComboBox
def _createOptions(self, param, tooltip=""): combo = QComboBox() combo.addItem("Select option") combo.addItems(param.options) combo.setCurrentIndex(0) append = param.isVectorType() combo.currentTextChanged.connect(lambda text: self._optionSelected(param.name, append, text)) row = self.findRow(param.name) if tooltip: combo.setToolTip(tooltip) self.setCellWidget(row, 2, combo)
class AddPlayerWidget(QWidget): def __init__(self): super(AddPlayerWidget, self).__init__() self.users = {} # self.setWindowTitle('Add Player') self.setStyleSheet(style.style_loader.stylesheet) self.label = QLabel('Enter Name:', self) self.label_widget = QWidget(self) label_layout = QBoxLayout(QBoxLayout.LeftToRight) label_layout.addWidget(self.label) self.label_widget.setLayout(label_layout) self.user_box = QComboBox(self) self.user_box.setFixedWidth(210) self.user_box.setFixedHeight(50) self.user_box_widget = QWidget(self) user_box_layout = QBoxLayout(QBoxLayout.LeftToRight) user_box_layout.addWidget(self.user_box) self.user_box_widget.setLayout(user_box_layout) self.submit_btn = QPushButton('Add Player', self) self.submit_btn.clicked.connect(self.submit) self.submit_btn_widget = QWidget(self) submit_btn_layout = QBoxLayout(QBoxLayout.LeftToRight) submit_btn_layout.addWidget(self.submit_btn) self.submit_btn_widget.setLayout(submit_btn_layout) layout = QFormLayout() layout.addRow(self.label_widget) layout.addRow(self.user_box_widget) layout.addRow(self.submit_btn_widget) self.setLayout(layout) self.show() self.setFixedHeight(self.height()) self.setFixedWidth(self.width()) self.close() def update(self): self.user_box.clear() self.users = um.users() for user in self.users: self.user_box.addItem(user.name + ' (' + str(user.id) + ')') def submit(self): user = self.users[self.user_box.currentIndex()] view.notifier.player_added(user.name, user) self.close()
class DeleteForm(QDialog): def __init__(self): super(DeleteForm, self).__init__() self.initUI(self) def initUI(self, DeleteForm): layout = QGridLayout(self) self.delete_label = QLabel("Delete by:") self.delete_combo_box = QComboBox() self.delete_combo_box.addItem("ISBN") self.delete_combo_box.addItem("Title") self.delete_line_edit = QLineEdit() self.delete_button = QPushButton("Delete") layout.addWidget(self.delete_label, 0, 0) layout.addWidget(self.delete_combo_box, 0, 1) layout.addWidget(self.delete_line_edit, 0, 2) layout.addWidget(self.delete_button, 0, 3, 1, 2) self.setLayout(layout) self.delete_button.clicked.connect(self.delete_button_click) self.layout().setSizeConstraint(QLayout.SetFixedSize) self.setWindowTitle("Delete Book") self.setWindowIcon(QIcon(QPixmap('../images/delete.png'))) def delete_button_click(self): search = self.delete_combo_box.currentText() text = self.delete_line_edit.text() if search == 'ISBN': if not(Validations.is_valid_isbn(text)): QMessageBox(QMessageBox.Critical, "Error", "Invalid ISBN. Please correct it!").exec_() books = select_by_isbn(text) if books != []: delete_by_isbn(text) QMessageBox(QMessageBox.Information, "Information", "You successfully deleted this book!").exec_() return else: QMessageBox(QMessageBox.Information, "No results", "There is NO such book in the library!").exec_() return elif search == 'Title': books = select_by_title(string.capwords(text)) if books != []: delete_by_title(string.capwords(text)) QMessageBox(QMessageBox.Information, "Information", "You successfully deleted this book!").exec_() return else: QMessageBox(QMessageBox.Information, "No results", "There is NO such book in the library!").exec_() return
class PreviewForm(QDialog): def __init__(self, parent): super(PreviewForm, self).__init__(parent) self.encodingComboBox = QComboBox() encodingLabel = QLabel("&Encoding:") encodingLabel.setBuddy(self.encodingComboBox) self.textEdit = QTextEdit() self.textEdit.setLineWrapMode(QTextEdit.NoWrap) self.textEdit.setReadOnly(True) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.encodingComboBox.activated.connect(self.updateTextEdit) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) mainLayout = QGridLayout() mainLayout.addWidget(encodingLabel, 0, 0) mainLayout.addWidget(self.encodingComboBox, 0, 1) mainLayout.addWidget(self.textEdit, 1, 0, 1, 2) mainLayout.addWidget(buttonBox, 2, 0, 1, 2) self.setLayout(mainLayout) self.setWindowTitle("Choose Encoding") self.resize(400, 300) def setCodecList(self, codecs): self.encodingComboBox.clear() for codec in codecs: self.encodingComboBox.addItem(codec_name(codec), codec.mibEnum()) def setEncodedData(self, data): self.encodedData = data self.updateTextEdit() def decodedString(self): return self.decodedStr def updateTextEdit(self): mib = self.encodingComboBox.itemData(self.encodingComboBox.currentIndex()) codec = QTextCodec.codecForMib(mib) data = QTextStream(self.encodedData) data.setAutoDetectUnicode(False) data.setCodec(codec) self.decodedStr = data.readAll() self.textEdit.setPlainText(self.decodedStr)
def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.setMinimumHeight(300) self.setMinimumWidth(300) # MENU BAR menu_bar = self.menuBar() _ = menu_bar.addMenu('&File') edit = menu_bar.addMenu('&Edit') copy = edit.addAction('©') copy.triggered.connect(self.text_edit.copy) paste = edit.addAction('&paste') paste.triggered.connect(self.text_edit.paste) select_all = edit.addAction('&select all') select_all.triggered.connect(self.text_edit.selectAll) undo = edit.addAction('&undo') undo.triggered.connect(self.text_edit.undo) redo = edit.addAction('&redo') redo.triggered.connect(self.text_edit.redo) window_layout = QVBoxLayout() window_layout.addWidget(menu_bar, 0) # TOOL BAR tool_bar = QToolBar() button = QAction(QIcon("icons/new-file.png"), "a", self) button.triggered.connect(self.new_file) tool_bar.addAction(button) button = QAction(QIcon("icons/open-archive.png"), "a", self) button.triggered.connect(self.getfile) tool_bar.addAction(button) button = QAction(QIcon("icons/save.png"), "a", self) button.triggered.connect(self.save_file) tool_bar.addAction(button) button = QAction(QIcon("icons/saveas.png"), "a", self) button.triggered.connect(self.save_as) tool_bar.addAction(button) tool_bar.addSeparator() button = QAction(QIcon("icons/undo.png"), "a", self) button.triggered.connect(self.text_edit.undo) tool_bar.addAction(button) button = QAction(QIcon("icons/redo.png"), "a", self) button.triggered.connect(self.text_edit.redo) tool_bar.addAction(button) tool_bar.addSeparator() button = QAction(QIcon("icons/copy.png"), "a", self) button.triggered.connect(self.text_edit.copy) tool_bar.addAction(button) button = QAction(QIcon("icons/paste.png"), "a", self) button.triggered.connect(self.text_edit.paste) tool_bar.addAction(button) button = QAction(QIcon("icons/selection.png"), "a", self) button.triggered.connect(self.text_edit.selectAll) tool_bar.addAction(button) window_layout.addWidget(tool_bar, 1) # SPLIT PANE window_layout.addWidget(self.split_pane, 2) # LEFT PANE w = QWidget() w.setLayout(self.left_v_box) w.setFixedWidth(250) self.split_pane.addWidget(w) # RIGHT PANE self.split_pane.addWidget(self.text_edit) # LEFT PANE FONT SIZE combo_box = QComboBox(self) combo_box.addItem("10") combo_box.addItem("12") combo_box.addItem("14") combo_box.addItem("16") combo_box.addItem("18") combo_box.activated[str].connect(self.change_font_size) self.left_v_box.addWidget(combo_box) # # LEFT PANE FONT STYLE # options = ['Times Nes Roman', 'Arial', 'Courier New'] # cbg = QButtonGroup(self) # cbg.setExclusive(True) # for id, ch in enumerate(options): # rb = QRadioButton(ch) # cbg.addButton(rb) # cbg.setId(rb, id) # self.left_v_box.addWidget(rb) # LEFT PANE FONT STYLE options = ['Times Nes Roman', 'Arial', 'Courier New'] rb = QRadioButton(options[0]) rb.clicked.connect(self.set_font1) self.left_v_box.addWidget(rb) rb = QRadioButton(options[1]) rb.pressed.connect(self.set_font2) self.left_v_box.addWidget(rb) rb = QRadioButton(options[2]) rb.pressed.connect(self.set_font3) self.left_v_box.addWidget(rb) # LEFT PANE COLOR PALETTE pal_widget = QWidget() pal_widget.setFixedHeight(120) pal_widget.setFixedWidth(120) palette = QGridLayout() pal_widget.setLayout(palette) self.left_v_box.addWidget(pal_widget) colors = [ '#000000', '#141923', '#414168', '#3a7fa7', '#35e3e3', '#8fd970', '#5ebb49', '#458352', '#dcd37b', '#fffee5', '#ffd035', '#cc9245', '#a15c3e', '#a42f3b', '#f45b7a', '#ffffff' ] row, col = 0, 0 num_of_columns = 4 for c in colors: b = _PaletteButton(c) b.clicked.connect( self.ColorChanger(c, self.pal, self.text_edit, self.statusBar())) palette.addWidget(b, row, col) col += 1 if col == num_of_columns: col = 0 row += 1 # ALIGN LEFT PANE TO TOP self.left_v_box.addStretch(1) # SET MAIN WINDOW self.main_widget.setLayout(window_layout) self.setCentralWidget(self.main_widget) # STATUS BAR self.statusBar().showMessage("Status bar") self.show()
class Flasher(QDialog): def __init__(self): super().__init__() self.setWindowTitle("ESP32 Flasher 1.0") self.setMinimumWidth(480) self.mode = 0 # BIN file self.bin_file = os.getcwd() + "\\firmware.bin" self.release_data = b"" self.createUI() self.refreshPorts() self.jsonStart = False self.jsonBuffer = "" def createUI(self): vl = VLayout() self.setLayout(vl) # Port groupbox gbPort = GroupBoxH("Select port", 3) self.cbxPort = QComboBox() pbRefreshPorts = QPushButton("Refresh") gbPort.addWidget(self.cbxPort) gbPort.addWidget(pbRefreshPorts) gbPort.layout().setStretch(0, 4) gbPort.layout().setStretch(1, 1) # Firmware groupbox gbFW = GroupBoxV("Select image", 3) self.wFile = QWidget() hl_file = HLayout(0) self.file = QLineEdit() self.file.setReadOnly(True) self.file.setText(self.bin_file) pbFile = QPushButton("Open") hl_file.addWidgets([self.file, pbFile]) self.wFile.setLayout(hl_file) gbFW.addWidgets([self.wFile]) # Buttons self.pbFlash = QPushButton("Flash!") self.pbFlash.setFixedHeight(50) self.pbFlash.setStyleSheet("background-color: #223579;") self.pbConfig = QPushButton("Setup WIFI") self.pbConfig.setStyleSheet("background-color: #571054;") self.pbConfig.setFixedHeight(50) self.pbQuit = QPushButton("Quit") self.pbQuit.setStyleSheet("background-color: #c91017;") self.pbQuit.setFixedSize(QSize(50, 50)) hl_btns = HLayout([50, 3, 50, 3]) hl_btns.addWidgets([self.pbFlash, self.pbConfig, self.pbQuit]) vl.addWidgets([gbPort, gbFW]) vl.addLayout(hl_btns) pbRefreshPorts.clicked.connect(self.refreshPorts) pbFile.clicked.connect(self.openBinFile) self.pbFlash.clicked.connect(self.start_process) self.pbConfig.clicked.connect(self.send_config) self.pbQuit.clicked.connect(self.reject) def refreshPorts(self): self.cbxPort.clear() ports = reversed( sorted(port.portName() for port in QSerialPortInfo.availablePorts())) for p in ports: port = QSerialPortInfo(p) self.cbxPort.addItem(port.portName(), port.systemLocation()) def setBinMode(self, radio): self.mode = radio self.wFile.setVisible(self.mode == 0) def appendReleaseInfo(self): self.release_data += self.release_reply.readAll() def openBinFile(self): file, ok = QFileDialog.getOpenFileName(self, "Select Firmware image", self.bin_file, filter="BIN files (*.bin)") if ok: self.file.setText(file) def send_config(self): dlg = SendConfigDialog() if dlg.exec_() == QDialog.Accepted: if dlg.commands: try: self.serial = QSerialPort(self.cbxPort.currentData()) self.serial.setBaudRate(115200) self.serial.open(QIODevice.ReadWrite) self.serial.readyRead.connect(self.on_serial_read) bytes_sent = self.serial.write(bytes(dlg.commands, 'utf8')) except Exception as e: QMessageBox.critical(self, "COM Port error", e) else: QMessageBox.information(self, "Done", "Nothing to send") def on_serial_read(self): self.process_bytes(bytes(self.serial.readAll())) def process_bytes(self, bs): text = bs.decode('ascii') # print("!Received: " + text) try: for b in text: if b == '{': # start json self.jsonStart = True # print("start JSON") if self.jsonStart == True: self.jsonBuffer += b if b == '}': # end json self.jsonStart = False # print("found JSON") print(self.jsonBuffer) obj = json.loads(self.jsonBuffer) url = "http://" + obj["IP"] print("Device IP: {0} ".format(url)) txt = "******* Use admin/{0} to enter configuration page *******".format( obj["ApPassword"]) print(txt) webbrowser.get().open(url) self.serial.close() except Exception as e: print("JSON error", e) def start_process(self): ok = True if self.mode == 0: if len(self.file.text()) > 0: self.bin_file = self.file.text() else: ok = False QMessageBox.information( self, "Nothing to do...", "Select a local BIN file or select which one to download.") if ok: dlg = FlashingDialog(self) if dlg.exec_() == QDialog.Accepted: QMessageBox.information( self, "Done", "Flashing successful! Press the reset button.") else: if dlg.error_msg: QMessageBox.critical(self, "Error", dlg.error_msg) else: QMessageBox.critical( self, "Flashing aborted", "Flashing process has been aborted by the user.") def mousePressEvent(self, e): self.old_pos = e.globalPos() def mouseMoveEvent(self, e): delta = e.globalPos() - self.old_pos self.move(self.x() + delta.x(), self.y() + delta.y()) self.old_pos = e.globalPos()
class Settings(QWidget): """settings window""" def __init__(self, lang, main, settings): """ :param lang: dict, current locale :param main: core.gui.gui.Main object :param settings: dict, current settings """ super().__init__() self.lang = lang['SETTINGS'] self.orig_lang = lang self.main = main self.settings = settings self._loc_items = {} self._changed = False self.del_widgets_win = None # setup window self.setWindowTitle(self.lang['title']) self.setWindowIcon(QIcon(SETTINGS)) self.resize(290, 200) self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint) # setup 'Languages' lebel self.label_loc = QLabel(self.lang['label_loc'], self) self.label_loc.setAlignment(Qt.AlignCenter) # setup languages list self.language = QComboBox(self) self.language.setToolTip(self.lang['language_tt']) self.language.activated.connect(self._change_settings) self._langs_box_fill() # setup log level label self.label_log = QLabel(self.lang['label_log']) self.label_log.setAlignment(Qt.AlignCenter) # setup levels list self.log_levels = QComboBox(self) self.log_levels.setToolTip(self.lang['levels_tt']) self.log_levels.activated.connect(self._change_settings) self._logs_box_fill() # setup 'Load placed' checkbox self.load_placed = QCheckBox(self.lang['load_placed'], self) self.load_placed.setToolTip(self.lang['load_placed_tt']) if strtobool(settings['MAIN']['load_placed']): self.load_placed.setChecked(True) self.load_placed.stateChanged.connect(self._change_settings) # setup widgets delete button self.del_button = QPushButton(self.lang['del_button'], self) self.del_button.setToolTip(self.lang['del_button_tt']) self.del_button.clicked.connect(self._show_del_widgets) # setup 'Save' button self.save_button = QPushButton(self.lang['save_button'], self) self.save_button.setToolTip(self.lang['save_button_tt']) self.save_button.clicked.connect(self._save) # setup 'Cancel' button self.cancel_button = QPushButton(self.lang['cancel_button'], self) self.cancel_button.setToolTip(self.lang['cancel_button_tt']) self.cancel_button.clicked.connect(self._cancel) # setup h box layout self.h_box = QHBoxLayout() self.h_box.addWidget(self.save_button) self.h_box.addWidget(self.cancel_button) # setup grid layout self.grid = QGridLayout(self) self.grid.addWidget(self.label_loc, 0, 0) self.grid.addWidget(self.language, 0, 1) self.grid.addWidget(self.label_log, 1, 0) self.grid.addWidget(self.log_levels, 1, 1) self.grid.addWidget(self.load_placed, 2, 0, 1, 2) self.grid.addWidget(self.del_button, 3, 0, 1, 2) self.grid.addLayout(self.h_box, 4, 0, 1, 2) self.setLayout(self.grid) # show self.show() def _change_settings(self): self._changed = True def _langs_box_fill(self): for name in get_locales(): try: conf = get_locale(name) item = conf['LANG']['name'] + ' (' item += conf['LANG']['description'] + ')' self.language.addItem(item) if name == self.settings['MAIN']['locale']: self.language.setCurrentText(item) self._loc_items[item] = name except: print_stack_trace()() @try_except() def _logs_box_fill(self): for key in LogLevel.get_keys(): try: self.log_levels.addItem(key) except: print_stack_trace()() self.log_levels.setCurrentText( LogLevel.from_int(int(self.settings['LOGS']['log_level']))) @try_except() def _save(self, checked): self.settings['MAIN']['locale'] = \ self._loc_items[self.language.currentText()] self.settings['MAIN']['load_placed'] = \ str(self.load_placed.isChecked()) self.settings['LOGS']['log_level'] = \ str(LogLevel.from_string(self.log_levels.currentText())) properties.write_settings(self.settings) if self._changed: self._show_warn() self.main._list_fill() self.close() @try_except() def _cancel(self, checked): self.main._list_fill() self.close() def _show_warn(self): mbox = QMessageBox(QMessageBox.Warning, self.lang['warn_title'], self.lang['warn_text'], QMessageBox.Ok, self) mbox.setWindowIcon(QIcon(SUCCESS)) ok = mbox.button(QMessageBox.Ok) ok.setText(self.lang['warn_ok_button']) ok.setToolTip(self.lang['warn_ok_button_tt']) mbox.exec() @try_except() def _show_del_widgets(self, checked): self.del_widgets_win = Delete(self.orig_lang, sys.modules['core.gui.gui'].manager)
class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) centralWidget = QWidget() self.mainLayout = QVBoxLayout() buttonLayout = QHBoxLayout() foldersLayout = QHBoxLayout() backupFolderLayout = QHBoxLayout() self.usbDevicesChooser = QComboBox() usb_util = Utils() self.usbDevices = usb_util.get_storage_device() for device in self.usbDevices: self.usbDevicesChooser.addItem(device.__str__()) self.pathToFolders = QLineEdit() self.pathToFolders.setPlaceholderText("Path to folders you want to backup") self.pathToBackupFolder = QLineEdit() self.pathToBackupFolder.setPlaceholderText("Path to backup destination folder") self.browseFoldersButton = QPushButton("Browse...") self.browseFoldersButton.clicked.connect(self.on_browseFolders_clicked) self.browseBackupFolderButton = QPushButton("Browse...") self.browseBackupFolderButton.clicked.connect(self.on_browseBackupFolder_clicked) foldersLayout.addWidget(self.pathToFolders) foldersLayout.addWidget(self.browseFoldersButton) foldersLayout.setSpacing(5) backupFolderLayout.addWidget(self.pathToBackupFolder) backupFolderLayout.addWidget(self.browseBackupFolderButton) backupFolderLayout.setSpacing(5) self.startBackupButton = QPushButton("Start Backup") self.startBackupButton.clicked.connect(self.on_startBackup_clicked) self.exitButton = QPushButton("Exit") self.exitButton.clicked.connect(self.on_exit_clicked) buttonLayout.addWidget(self.startBackupButton) buttonLayout.addWidget(self.exitButton) buttonLayout.setSpacing(10) self.mainLayout.addWidget(self.usbDevicesChooser) self.mainLayout.addLayout(backupFolderLayout) self.mainLayout.addLayout(foldersLayout) self.mainLayout.addLayout(buttonLayout) centralWidget.setLayout(self.mainLayout) self.setCentralWidget(centralWidget) self.setWindowTitle("Nice Backup") self.setMinimumSize(600, 200) def on_exit_clicked(self, widget): sys.exit() def on_browseFolders_clicked(self, widget): index = self.usbDevicesChooser.currentIndex() file_dialog = QFileDialog() file_dialog.setFileMode(QFileDialog.DirectoryOnly) file_dialog.setOption(QFileDialog.DontUseNativeDialog, True) file_view = file_dialog.findChild(QListView, 'listView') if file_view: file_view.setSelectionMode(QAbstractItemView.MultiSelection) ftree_view = file_dialog.findChild(QTreeView) if ftree_view: ftree_view.setSelectionMode(QAbstractItemView.MultiSelection) file_dialog.setDirectory(self.usbDevices[index].getPath()) if file_dialog.exec(): paths = file_dialog.selectedFiles() self.pathToFolders.setText(";".join(paths)) def on_browseBackupFolder_clicked(self, widget): fname = QFileDialog.getExistingDirectory(self.window(), 'Open file', '/home/{}'.format(getpass.getuser())) self.pathToBackupFolder.setText(fname) def on_startBackup_clicked(self, widget): print("Starting backup") backuper = Backuper.Backuper() sources = self.pathToFolders.text().split(";") destination = self.pathToBackupFolder.text() progress = QProgressBar() progress.setMinimum(0) progress.setMaximum(len(sources)) self.mainLayout.addWidget(progress) for source in sources: backuper.make_backup(source, destination) progress.setValue(sources.index(source)) QApplication.processEvents() doneDialog = QMessageBox() doneDialog.setIcon(QMessageBox.Information) doneDialog.setText("Copying data is completed") doneDialog.setWindowTitle("Copy event") doneDialog.setStandardButtons(QMessageBox.Ok) index = self.mainLayout.indexOf(progress) self.mainLayout.itemAt(index).widget().setParent(None) doneDialog.exec()
class MainTab(QWidget): WELCOMEGROUP = 1 FORMGROUP = 2 FIRSTSTANDARD = 3 def __init__(self, tabs, *args) -> None: super().__init__(*args) self.tabs = tabs self.opt = None self.main_layout = QHBoxLayout() self.createBar() self.createFormGroupBox() self.createWelcome() self.main_layout.addWidget(self.barGroup) self.main_layout.addWidget(self.welcomeGroup) self.setLayout(self.main_layout) def createWelcome(self): self.welcomeGroup = QGroupBox("Welcome") self.qb = QVBoxLayout() lb1 = QLabel("Welcome") self.qb.addWidget(lb1) self.welcomeGroup.setLayout(self.qb) def createBar(self): self.barGroup = QGroupBox('Menu') self.btn1 = CustomBtn('Welcome') self.btn2 = CustomBtn("Selecting Files") self.btn3 = CustomBtn("First Standard") self.btn2.clicked.connect( lambda: self.handelFormBtn(MainTab.FORMGROUP)) self.btn1.clicked.connect( lambda: self.handelFormBtn(MainTab.WELCOMEGROUP)) self.btn3.clicked.connect(lambda x: self.handelStandards(x, 1)) self.hb = QVBoxLayout() self.hb.addWidget(self.btn1) self.hb.addWidget(self.btn2) self.hb.addWidget(self.btn3) self.hb.addStretch(1) self.hb.setAlignment(Qt.AlignTop) self.barGroup.setMaximumWidth(150) self.barGroup.setLayout(self.hb) def handelFormBtn(self, clearOpt): self.clearLayoutAndSetNewOne(clearOpt) def handelStandards(self, _, number): self.exels_files = [] self.exels_files.append( str( os.path.join(os.path.dirname(__file__), 'data', f'standard_{number}.xlsx'))) print(self.exels_files) for path in self.exels_files: if not os.path.exists(path): MainWindow.errorHandler(f"directory_{path} not exits") return self.createTabs(None) def clearLayoutAndSetNewOne(self, clearOpt): if self.opt != clearOpt: item = None if self.layout() is not None: for i in range(1, self.layout().count()): item = self.layout().itemAt(i).widget() item.setParent(None) item.close() if clearOpt == MainTab.FORMGROUP: self.createFormGroupBox() self.main_layout.addWidget(self.formGroupBox) self.opt = MainTab.FORMGROUP elif clearOpt == MainTab.WELCOMEGROUP: self.createWelcome() self.main_layout.addWidget(self.welcomeGroup) self.opt = MainTab.WELCOMEGROUP def setComobox(self): self.options = {} for i in range(1, 11): self.options[f'{i} file'] = { 'value': i, 'label': f'Insert Address of file {i}' } def createFormGroupBox(self): self.formGroupBox = QGroupBox("Form layout") self.formLayout = QFormLayout() self.combo = QComboBox(self) self.combo.setStyleSheet("""background: #275efe; border-radius: 10px; width:100%;""") self.combo.addItem('select') self.setComobox() for val in self.options: self.combo.addItem(val, userData=QtCore.QVariant( str(self.options[val]['value']))) self.filebtn = QPushButton('Select File', self) self.filebtn.setStyleSheet("""background: #275efe; border-radius: 10px; width: 100%; padding: 2px""") self.filebtn.clicked.connect(self.fileBtnHandler) self.tabCreatorBtn = QPushButton('create Tabs', self) self.tabCreatorBtn.setStyleSheet("""background: #275efe; border-radius: 10px; width:100%; padding: 2px;""") self.formLayout.addRow( QLabel('Enter The Folder Which Contains The Execl Files.'), self.filebtn) self.formLayout.addRow( QLabel( "Enter the number of files you want to load from directory"), self.combo) self.formLayout.addRow(QLabel('Create Tabs For Execl files.'), self.tabCreatorBtn) self.tabCreatorBtn.clicked.connect(self.createTabs) self.combo.currentIndexChanged.connect(self.comboHandler) self.formGroupBox.setLayout(self.formLayout) def fileBtnHandler(self, x): """ Handling directory which selected by user if directory was not selected the send error msg in QMessage window if everything was good it sets file_path for directories; parameter: x: clicked or not returns: void """ self.file_path = str( QFileDialog.getExistingDirectory(self, 'select Directory')) if self.file_path == None or self.file_path == " " or len( self.file_path) == 0: self.file_path = " " MainWindow.errorHandler( "Directory Not Selected!\n\nplease select directory.") return self.exels_files = [] files = os.listdir(self.file_path) for file in files: if os.path.splitext(file)[1] == ".xlsx": self.exels_files.append(path.join(self.file_path, file)) if len(self.exels_files) == 0: MainWindow.errorHandler("Directory Contains No .xlsx files.", "Directory Execl file") return foundedFiles = "[" lbl = QLabel() for file in self.exels_files: foundedFiles += str(file).split('/')[-1] + ', ' lbl.setText(foundedFiles + ']') self.formLayout.addRow(QLabel("Founded Files"), lbl) def comboHandler(self, value): self.combo_value = value if getattr(self, 'exels_files', None) == None or len( self.exels_files) == 0: MainWindow.errorHandler("please select Directory First.") return if value >= len(self.exels_files): self.combo_value = len(self.exels_files) itemValue = self.combo.itemData(value) itemText = self.combo.itemText(value) print(itemValue, "====", itemText, "====", value) def keyPressEvent(self, a0: QtGui.QKeyEvent) -> None: if a0.key() == QKeySequence("Ctrl+Q"): sys.exit(1) if a0.key() == QKeySequence('Command+Q'): sys.exit(1) def createTabs(self, _=None): if getattr(self, 'exels_files', None) == None or len( self.exels_files) == 0: MainWindow.errorHandler("please Select Directory First.") return if getattr(self, 'combo_value', None) == None: self.combo_value = len(self.exels_files) for file in self.exels_files[:self.combo_value]: tab = ExeclTab(file) tab.setMaximumWidth(self.width()) self.tabs.addTab(tab, str(file).split('/')[-1]) self.tabs.setCurrentWidget(tab) self.exels_files = None del self.exels_files
class TeqGraphGenerationWidget(QWidget): def __init__(self): super(QWidget, self).__init__() self._setup_widget() def _setup_widget(self): self.query = QTextEdit(self) self.addtoreport = QPushButton("Add Graph to Report") self.addtoreport.clicked.connect(self.add_graph) self.submit1 = QPushButton("Execute Query") self.submit1.clicked.connect(self.run_query) self.export1 = QPushButton("Export Graphs") self.export1.clicked.connect(self.export_data) self.clear1 = QPushButton("Clear Graphs") self.clear1.clicked.connect(self.clear_graphs) self._setup_graph_export_combobox() self._setup_report_queue_table() self.table1 = QTableWidget() # set layouts self.layout = QGridLayout(self) self.layout.setColumnStretch(0, 3) self.layout.addWidget(QLabel("Query:"), 0, 0) # add query textbox self.layout.addWidget(self.query, 1, 0) self.layout.addWidget(self.submit1, 1, 1) self.layout.addWidget(QLabel("In Current Report:"), 2, 0) # add file option combobox self.layout.addWidget(self.export_combobox, 2, 1) # add query output result table self.layout.addWidget(self.report_table, 3, 0) self.layout.addWidget(self.addtoreport, 3, 1) self.layout.addWidget(QLabel("Query Output:"), 4, 0) self.layout.addWidget(self.clear1, 4, 1) self.layout.addWidget(self.table1, 5, 0) self.layout.addWidget(self.export1, 5, 1) self.setLayout(self.layout) def _setup_graph_export_combobox(self): self.export_graph_options = { "bar": graph.bar_chart, "line": graph.line_chart, "pie": graph.pie_chart } self.export_combobox = QComboBox() for key in self.export_graph_options: self.export_combobox.addItem(key) def _setup_report_queue_table(self): self.report_table = QTableWidget() self.report_table.setColumnCount(2) header = self.report_table.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.ResizeToContents) header.setSectionResizeMode(1, QHeaderView.ResizeToContents) self.report_table.setHorizontalHeaderItem(0, QTableWidgetItem("Graph Type")) self.report_table.setHorizontalHeaderItem(1, QTableWidgetItem("Query")) @pyqtSlot() def run_query(self): query = self.query.toPlainText() if (len(query) == 0): gui_helper.prompt_error("Please enter a query") return try: dict_values = database.execute_query_result(query) if (dict_values): self.populateTable(dict_values) gui_helper.prompt_information("query executed successfully") except Exception as e: gui_helper.prompt_error("Failed to run Query: " + repr(e)) def populateTable(self, column_values): self.table1.clearContents() self.table1.setColumnCount(len(column_values)) for key in column_values: self.table1.setRowCount(len(column_values[key])) break for i, key in enumerate(column_values): self.table1.setHorizontalHeaderItem(i, QTableWidgetItem(key)) col_vals = column_values[key] for j, val in enumerate(col_vals): self.table1.setItem(j, i, QTableWidgetItem(str(val))) @pyqtSlot() def add_graph(self): graph_type = self.export_combobox.currentText() query_text = self.query.toPlainText() if (len(query_text) == 0): gui_helper.prompt_error("Please enter a query") return row_count = self.report_table.rowCount() self.report_table.insertRow(row_count) self.report_table.setItem(row_count, 0, QTableWidgetItem(graph_type)) self.report_table.setItem(row_count, 1, QTableWidgetItem(query_text)) @pyqtSlot() def clear_graphs(self): self.report_table.setRowCount(0) @pyqtSlot() def export_data(self): query_text = self.query.toPlainText() if (len(query_text) == 0): gui_helper.prompt_error("Please enter a query") return file_path = gui_helper.prompt_file_save() if (not file_path): return with PdfPages(file_path) as pdf: conn = database.get_db_connection() for i in range(self.report_table.rowCount()): query_text = self.report_table.item(i, 1).text() graph_type = self.report_table.item(i, 0).text() dict_values = query.manual_sql_query(conn, query_text) try: plt = self.export_graph_options[graph_type](graph_type, dict_values) fig = plt.gcf() pdf.savefig() plt.close(fig) except Exception as e: gui_helper.prompt_error("Failed to export graph {}: ".format(i) + repr(e)) conn.close() gui_helper.prompt_information("Graphs has been successfully exported")
class ToolBar: def __init__(self, window): self.window = window self.tool_bar = self.window.addToolBar('Toolbar') self.tool_bar.setFixedHeight(50) self.tool_bar.layout().setSpacing(10) self.tool_bar.setMovable(False) self.view = None self.add_button = None self.del_button = None self.populate_tool_bar() def populate_tool_bar(self): self.view = QComboBox(self.window) self.view.addItem('CHURCH') self.view.addItem('EXAM') self.view.addItem('PRIZE') self.view.setFixedHeight(30) self.view.setFixedWidth(100) self.tool_bar.addWidget(self.view) self.add_button = ToolButton('Add', self.add, self.window, short_cut='', status_tip='Add Church') self.tool_bar.addAction(self.add_button.button) self.del_button = ToolButton('Delete', self.delete, self.window, short_cut='', status_tip='Delete all Church') self.tool_bar.addAction(self.del_button.button) self.add_spacer() self.add_spacer() self.add_spacer() self.add_spacer() self.add_spacer() self.add_spacer() self.add_spacer() search_label = QLabel() search_label.setText('Search') self.tool_bar.addWidget(search_label) self.add_search_bar() def add_spacer(self): spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.tool_bar.addWidget(spacer) def add_search_bar(self): line_edit = QLineEdit(self.window) str_list = ['test', 'complete'] completer = QCompleter(str_list, line_edit) line_edit.setCompleter(completer) line_edit.setFocusPolicy(Qt.ClickFocus) line_edit.editingFinished.connect(self.set_focus) line_edit.focusNextChild() self.window.focusWidget() self.tool_bar.addWidget(line_edit) def add(self): self.window.add_window() def delete(self): self.window.delete() def set_focus(self): self.window.setFocus() def set_text(self, text): self.view.setCurrentText(text)
def __init__(self, parent=None): super(Widget, self).__init__(parent) self.setWindowTitle("Keuze grafieken externe werken") self.setWindowIcon(QIcon('./images/logos/logo.jpg')) self.setFont(QFont('Arial', 10)) self.Keuze = QLabel() kEdit = QComboBox() kEdit.setFixedWidth(300) kEdit.setFont(QFont("Arial", 10)) kEdit.setStyleSheet("color: black; background-color: gainsboro") kEdit.addItem(' Keuze Grafieken') kEdit.addItem('1. Kosten totaal begroot-werkelijk') kEdit.addItem('2. Lonen begroot-werkelijk') kEdit.addItem('3. Materialen begroot-werkelijk') kEdit.addItem('4. Materiëel begroot-werkelijk') kEdit.addItem('5. Inhuur begroot-werkelijk') kEdit.addItem('6. Diensten begroot-werkelijk') kEdit.addItem('7. Projektkosten begroot-werkelijk') kEdit.addItem('8. Bruto winst - prognose / aktueel') kEdit.addItem('9. Onderhandenwerk - Betaald bedrag') kEdit.addItem('A. Opbrengsten - prognose / aktueel') kEdit.addItem('B. Bruto winst werkelijk\n Meerminderwerk') kEdit.activated[str].connect(self.kChanged) self.Zoekterm = QLabel() zktermEdit = QLineEdit() zktermEdit.setFixedWidth(65) zktermEdit.setFont(QFont("Arial", 10)) zktermEdit.textChanged.connect(self.zktermChanged) reg_ex = QRegExp("^[2]{1}[0-9]{3}[0-5]{1}[0-9]{1}$") input_validator = QRegExpValidator(reg_ex, zktermEdit) zktermEdit.setValidator(input_validator) grid = QGridLayout() grid.setSpacing(20) lbl = QLabel() pixmap = QPixmap('./images/logos/verbinding.jpg') lbl.setPixmap(pixmap) grid.addWidget(lbl, 0, 0, 1, 2) grid.addWidget(kEdit, 1, 0, 1, 2, Qt.AlignRight) lbl1 = QLabel('Jaarweek-uitdraai (jjjjww)') lbl1.setAlignment(Qt.AlignRight | Qt.AlignVCenter) grid.addWidget(lbl1, 2, 0, 1, 2, Qt.AlignCenter) grid.addWidget(zktermEdit, 2, 1, 1, 1, Qt.AlignRight) self.setLayout(grid) self.setGeometry(500, 200, 150, 150) grid.addWidget( QLabel('\u00A9 2017 all rights reserved [email protected]'), 4, 0, 1, 2, Qt.AlignRight) logo = QLabel() pixmap = QPixmap('./images/logos/logo.jpg') logo.setPixmap(pixmap) grid.addWidget(logo, 0, 1, 1, 1, Qt.AlignRight) applyBtn = QPushButton('Zoeken') applyBtn.clicked.connect(self.accept) sluitBtn = QPushButton('Sluiten') sluitBtn.clicked.connect(lambda: windowSluit(self, m_email)) grid.addWidget(applyBtn, 3, 1, 1, 1, Qt.AlignRight) applyBtn.setFont(QFont("Arial", 10)) applyBtn.setFixedWidth(100) applyBtn.setStyleSheet( "color: black; background-color: gainsboro") grid.addWidget(sluitBtn, 3, 0, 1, 2, Qt.AlignCenter) sluitBtn.setFont(QFont("Arial", 10)) sluitBtn.setFixedWidth(100) sluitBtn.setStyleSheet( "color: black; background-color: gainsboro")
class DAT_GUI(QtWidgets.QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.initUI() def initUI(self): screen = QApplication.desktop().screenNumber( QApplication.desktop().cursor().pos()) centerPoint = QApplication.desktop().screenGeometry(screen).center() # should fit in 1024x768 (old computer screens) window_width = 900 window_height = 700 self.setGeometry( QtCore.QRect( centerPoint.x() - int(window_width / 2), centerPoint.y() - int(window_height / 2), window_width, window_height)) # should I rather center on the screen # zoom parameters self.scale = 1.0 self.min_scaling_factor = 0.1 self.max_scaling_factor = 20 self.zoom_increment = 0.05 self.setWindowTitle(__NAME__ + ' v' + str(__VERSION__)) self.paint = Createpaintwidget() # initiate 2D image for 2D display self.img = None self.list = QListWidget( self) # a list that contains files to read or play with self.list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.list.selectionModel().selectionChanged.connect( self.selectionChanged) # connect it to sel change self.scrollArea = QScrollArea() self.scrollArea.setBackgroundRole(QPalette.Dark) self.scrollArea.setWidget(self.paint) self.paint.scrollArea = self.scrollArea self.table_widget = QWidget() table_widget_layout = QVBoxLayout() # Initialize tab screen self.tabs = QTabWidget(self) self.tab1 = QWidget() self.tab2 = QWidget() self.tab3 = QWidget() # Add tabs self.tabs.addTab(self.tab1, "Mask neuron") self.tabs.addTab(self.tab2, "Mask cell body") self.tabs.addTab(self.tab3, "Segment dendrites") # listen to tab changes self.tabs.currentChanged.connect(self._onTabChange) # Create first tab self.tab1.layout = QGridLayout() self.tab1.layout.setAlignment(Qt.AlignTop) self.tab1.layout.setHorizontalSpacing(3) self.tab1.layout.setVerticalSpacing(3) self.tab1.layout.setContentsMargins(0, 0, 0, 0) label1_tab1 = QLabel('Step 1:') self.tab1.layout.addWidget(label1_tab1, 0, 0) self.local_threshold = QPushButton("Local threshold") self.local_threshold.clicked.connect(self.run_threshold_neuron) self.tab1.layout.addWidget(self.local_threshold, 0, 1) self.global_threshold = QPushButton("Global threshold") self.global_threshold.clicked.connect(self.run_threshold_neuron) self.tab1.layout.addWidget(self.global_threshold, 0, 2) self.local_n_global_threshold = QPushButton( "Local AND Global threshold") self.local_n_global_threshold.clicked.connect( self.run_threshold_neuron) self.tab1.layout.addWidget(self.local_n_global_threshold, 0, 3) self.extra_value_for_threshold = QSpinBox() self.extra_value_for_threshold.setSingleStep(1) self.extra_value_for_threshold.setRange(0, 1_000_000) self.extra_value_for_threshold.setValue(6) self.tab1.layout.addWidget(self.extra_value_for_threshold, 0, 4) self.threshold_method = QComboBox() self.threshold_method.addItem('Mean') self.threshold_method.addItem('Median') self.tab1.layout.addWidget(self.threshold_method, 0, 5) label2_tab1 = QLabel('Step 2 (optional):') self.tab1.layout.addWidget(label2_tab1, 1, 0) self.remove_pixel_blobs_smaller_or_equal = QPushButton( "Remove pixel blobs smaller or equal to") self.remove_pixel_blobs_smaller_or_equal.clicked.connect( self.remove_blobs) self.tab1.layout.addWidget(self.remove_pixel_blobs_smaller_or_equal, 1, 1) self.remove_blobs_size = QSpinBox() self.remove_blobs_size.setSingleStep(1) self.remove_blobs_size.setRange(0, 1_000_000) self.remove_blobs_size.setValue(1) self.tab1.layout.addWidget(self.remove_blobs_size, 1, 2) label3_tab1 = QLabel('Step 3: Save') self.tab1.layout.addWidget(label3_tab1, 2, 0) self.tab1.setLayout(self.tab1.layout) self.tab2.layout = QGridLayout() self.tab2.layout.setAlignment(Qt.AlignTop) self.tab2.layout.setHorizontalSpacing(3) self.tab2.layout.setVerticalSpacing(3) self.tab2.layout.setContentsMargins(0, 0, 0, 0) label1_tab2 = QLabel('Step 1:') self.tab2.layout.addWidget(label1_tab2, 0, 0) self.detect_cell_body = QPushButton("Detect cell body") self.detect_cell_body.clicked.connect(self.detect_neuronal_cell_body) self.tab2.layout.addWidget(self.detect_cell_body, 0, 1) self.extraCutOff_cell_body = QSpinBox() self.extraCutOff_cell_body.setSingleStep(1) self.extraCutOff_cell_body.setRange(0, 1_000_000) self.extraCutOff_cell_body.setValue(5) self.tab2.layout.addWidget(self.extraCutOff_cell_body, 0, 2) erosion_label = QLabel('erosion rounds') self.tab2.layout.addWidget(erosion_label, 0, 3) self.nb_erosion_cellbody = QSpinBox() self.nb_erosion_cellbody.setSingleStep(1) self.nb_erosion_cellbody.setRange(0, 1_000_000) self.nb_erosion_cellbody.setValue(2) self.tab2.layout.addWidget(self.nb_erosion_cellbody, 0, 4) min_object_size_label = QLabel('minimum object size') self.tab2.layout.addWidget(min_object_size_label, 0, 5) self.min_obj_size_px = QSpinBox() self.min_obj_size_px.setSingleStep(1) self.min_obj_size_px.setRange(0, 1_000_000) self.min_obj_size_px.setValue(600) self.tab2.layout.addWidget(self.min_obj_size_px, 0, 6) fill_label = QLabel('fill up to') self.tab2.layout.addWidget(fill_label, 0, 7) self.fill_holes_up_to = QSpinBox() self.fill_holes_up_to.setSingleStep(1) self.fill_holes_up_to.setRange(0, 1_000_000) self.fill_holes_up_to.setValue(600) self.tab2.layout.addWidget(self.fill_holes_up_to, 0, 8) nb_dilation_cell_body_label = QLabel('nb dilation cell body') self.tab2.layout.addWidget(nb_dilation_cell_body_label, 0, 9) self.nb_dilation_cellbody = QSpinBox() self.nb_dilation_cellbody.setSingleStep(1) self.nb_dilation_cellbody.setRange(0, 1_000_000) self.nb_dilation_cellbody.setValue(2) self.tab2.layout.addWidget(self.nb_dilation_cellbody, 0, 10) label2_tab2 = QLabel('Step 2: Save') self.tab2.layout.addWidget(label2_tab2, 6, 0) self.tab2.setLayout(self.tab2.layout) self.tab3.layout = QGridLayout() self.tab3.layout.setAlignment(Qt.AlignTop) self.tab3.layout.setHorizontalSpacing(3) self.tab3.layout.setVerticalSpacing(3) self.tab3.layout.setContentsMargins(0, 0, 0, 0) label1_tab3 = QLabel('Step 1:') self.tab3.layout.addWidget(label1_tab3, 0, 0) self.wshed = QPushButton("Watershed") self.wshed.clicked.connect(self.watershed_segment_the_neuron) self.tab3.layout.addWidget(self.wshed, 0, 1) self.whsed_big_blur = QDoubleSpinBox() self.whsed_big_blur.setSingleStep(0.1) self.whsed_big_blur.setRange(0, 100) self.whsed_big_blur.setValue(2.1) self.tab3.layout.addWidget(self.whsed_big_blur, 0, 2) self.whsed_small_blur = QDoubleSpinBox() self.whsed_small_blur.setSingleStep(0.1) self.whsed_small_blur.setRange(0, 100) self.whsed_small_blur.setValue(1.4) self.tab3.layout.addWidget(self.whsed_small_blur, 0, 3) self.wshed_rm_small_cells = QSpinBox() self.wshed_rm_small_cells.setSingleStep(1) self.wshed_rm_small_cells.setRange(0, 1_000_000) self.wshed_rm_small_cells.setValue(10) self.tab3.layout.addWidget(self.wshed_rm_small_cells, 0, 4) self.jSpinner11 = QSpinBox() self.jSpinner11.setSingleStep(1) self.jSpinner11.setRange(0, 1_000_000) self.jSpinner11.setValue(10) self.tab3.layout.addWidget(self.jSpinner11, 0, 5) label1_bis_tab3 = QLabel('Alternative Step 1:') self.tab3.layout.addWidget(label1_bis_tab3, 1, 0) self.skel = QPushButton("Skeletonize") self.skel.clicked.connect(self.skeletonize_mask) self.tab3.layout.addWidget(self.skel, 1, 1) label2_tab3 = QLabel('Step 2:') self.tab3.layout.addWidget(label2_tab3, 2, 0) self.apply_cell_body = QPushButton("Apply cell body") self.apply_cell_body.clicked.connect( self.apply_cell_body_to_skeletonized_mask) self.tab3.layout.addWidget(self.apply_cell_body, 2, 1) label3_tab3 = QLabel('Step 3 (Optional):') self.tab3.layout.addWidget(label3_tab3, 3, 0) self.prune = QPushButton("Prune") self.prune.clicked.connect(self.prune_dendrites) self.tab3.layout.addWidget(self.prune, 3, 1) self.prune_length = QSpinBox() self.prune_length.setSingleStep(1) self.prune_length.setRange(0, 1_000_000) self.prune_length.setValue(3) self.tab3.layout.addWidget(self.prune_length, 3, 2) label4_tab3 = QLabel('Step 4 (Optional):') self.tab3.layout.addWidget(label4_tab3, 4, 0) self.find_neurons = QPushButton("Find neurons") self.find_neurons.clicked.connect(self.find_neurons_in_mask) self.tab3.layout.addWidget(self.find_neurons, 4, 1) self.find_neurons_min_size = QSpinBox() self.find_neurons_min_size.setSingleStep(1) self.find_neurons_min_size.setRange(0, 1_000_000) self.find_neurons_min_size.setValue(45) self.tab3.layout.addWidget(self.find_neurons_min_size, 4, 2) self.prune_unconnected_segments = QPushButton( "Prune unconnected segments (run 'Find neurons' first)") self.prune_unconnected_segments.clicked.connect( self.prune_neuron_unconnected_segments) self.tab3.layout.addWidget(self.prune_unconnected_segments, 4, 3) label6_tab3 = QLabel('Step 5: Save') self.tab3.layout.addWidget(label6_tab3, 5, 0) label5_tab3 = QLabel('Step 6:') self.tab3.layout.addWidget(label5_tab3, 6, 0) self.create_n_save_bonds = QPushButton("Segment dendrites") self.create_n_save_bonds.clicked.connect(self.save_segmented_bonds) self.tab3.layout.addWidget(self.create_n_save_bonds, 6, 1) self.tab3.setLayout(self.tab3.layout) # Add tabs to widget table_widget_layout.addWidget(self.tabs) self.table_widget.setLayout(table_widget_layout) self.Stack = QStackedWidget(self) self.Stack.addWidget(self.scrollArea) # create a grid that will contain all the GUI interface self.grid = QGridLayout() self.grid.addWidget(self.Stack, 0, 0) self.grid.addWidget(self.list, 0, 1) # The first parameter of the rowStretch method is the row number, the second is the stretch factor. So you need two calls to rowStretch, like this: --> below the first row is occupying 80% and the second 20% self.grid.setRowStretch(0, 75) self.grid.setRowStretch(2, 25) # first col 75% second col 25% of total width self.grid.setColumnStretch(0, 75) self.grid.setColumnStretch(1, 25) # void QGridLayout::addLayout(QLayout * layout, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment = 0) self.grid.addWidget(self.table_widget, 2, 0, 1, 2) # spans over one row and 2 columns # BEGIN TOOLBAR # pen spin box and connect self.penSize = QSpinBox() self.penSize.setSingleStep(1) self.penSize.setRange(1, 256) self.penSize.setValue(3) self.penSize.valueChanged.connect(self.penSizechange) self.channels = QComboBox() self.channels.addItem("merge") self.channels.currentIndexChanged.connect(self.channelChange) tb_drawing_pane = QToolBar() save_button = QToolButton() save_button.setText("Save") save_button.clicked.connect(self.save_current_mask) tb_drawing_pane.addWidget(save_button) tb_drawing_pane.addWidget(QLabel("Channels")) tb_drawing_pane.addWidget(self.channels) # tb.addAction("Save") # tb_drawing_pane.addWidget(QLabel("Pen size")) tb_drawing_pane.addWidget(self.penSize) self.grid.addWidget(tb_drawing_pane, 1, 0) # END toolbar # toolbar for the list tb_list = QToolBar() del_button = QToolButton() del_button.setText("Delete selection from list") del_button.clicked.connect(self.delete_from_list) tb_list.addWidget(del_button) self.grid.addWidget(tb_list, 1, 1) # self.setCentralWidget(self.scrollArea) self.setCentralWidget(QFrame()) self.centralWidget().setLayout(self.grid) # self.statusBar().showMessage('Ready') statusBar = self.statusBar( ) # sets an empty status bar --> then can add messages in it self.paint.statusBar = statusBar # add progress bar to status bar self.progress = QProgressBar(self) self.progress.setGeometry(200, 80, 250, 20) statusBar.addWidget(self.progress) # Set up menu bar self.mainMenu = self.menuBar() self.zoomInAct = QAction( "Zoom &In (25%)", self, # shortcut="Ctrl++", enabled=True, triggered=self.zoomIn) self.zoomOutAct = QAction( "Zoom &Out (25%)", self, # shortcut="Ctrl+-", enabled=True, triggered=self.zoomOut) self.normalSizeAct = QAction( "&Normal Size", self, # shortcut="Ctrl+S", enabled=True, triggered=self.defaultSize) self.viewMenu = QMenu("&View", self) self.viewMenu.addAction(self.zoomInAct) self.viewMenu.addAction(self.zoomOutAct) self.viewMenu.addAction(self.normalSizeAct) self.menuBar().addMenu(self.viewMenu) self.setMenuBar(self.mainMenu) # set drawing window fullscreen fullScreenShortcut = QtWidgets.QShortcut( QtGui.QKeySequence(QtCore.Qt.Key_F), self) fullScreenShortcut.activated.connect(self.fullScreen) fullScreenShortcut.setContext(QtCore.Qt.ApplicationShortcut) escapeShortcut = QtWidgets.QShortcut( QtGui.QKeySequence(QtCore.Qt.Key_Escape), self) escapeShortcut.activated.connect(self.escape) escapeShortcut.setContext(QtCore.Qt.ApplicationShortcut) # Show/Hide the mask escapeShortcut = QtWidgets.QShortcut( QtGui.QKeySequence(QtCore.Qt.Key_H), self) escapeShortcut.activated.connect(self.showHideMask) escapeShortcut.setContext(QtCore.Qt.ApplicationShortcut) zoomPlus = QtWidgets.QShortcut("Ctrl+Shift+=", self) zoomPlus.activated.connect(self.zoomIn) zoomPlus.setContext(QtCore.Qt.ApplicationShortcut) zoomPlus2 = QtWidgets.QShortcut("Ctrl++", self) zoomPlus2.activated.connect(self.zoomIn) zoomPlus2.setContext(QtCore.Qt.ApplicationShortcut) zoomMinus = QtWidgets.QShortcut("Ctrl+Shift+-", self) zoomMinus.activated.connect(self.zoomOut) zoomMinus.setContext(QtCore.Qt.ApplicationShortcut) zoomMinus2 = QtWidgets.QShortcut("Ctrl+-", self) zoomMinus2.activated.connect(self.zoomOut) zoomMinus2.setContext(QtCore.Qt.ApplicationShortcut) spaceShortcut = QtWidgets.QShortcut( QtGui.QKeySequence(QtCore.Qt.Key_Space), self) spaceShortcut.activated.connect(self.nextFrame) spaceShortcut.setContext(QtCore.Qt.ApplicationShortcut) backspaceShortcut = QtWidgets.QShortcut( QtGui.QKeySequence(QtCore.Qt.Key_Backspace), self) backspaceShortcut.activated.connect(self.prevFrame) backspaceShortcut.setContext(QtCore.Qt.ApplicationShortcut) # connect enter keys to edit dendrites enterShortcut = QtWidgets.QShortcut( QtGui.QKeySequence(QtCore.Qt.Key_Return), self) enterShortcut.activated.connect(self.runSkel) enterShortcut.setContext(QtCore.Qt.ApplicationShortcut) enter2Shortcut = QtWidgets.QShortcut( QtGui.QKeySequence(QtCore.Qt.Key_Enter), self) enter2Shortcut.activated.connect(self.runSkel) enter2Shortcut.setContext(QtCore.Qt.ApplicationShortcut) #Qt.Key_Enter is the Enter located on the keypad: #Qt::Key_Return 0x01000004 #Qt::Key_Enter 0x01000005 Typically located on the keypad. self.setAcceptDrops(True) # KEEP IMPORTANT def __get_mask_img_from_overlay(self): if self.paint.imageDraw: channels_count = 4 s = self.paint.imageDraw.bits().asstring( self.img.shape[0] * self.img.shape[1] * channels_count) arr = np.frombuffer(s, dtype=np.uint8).reshape( (self.img.shape[0], self.img.shape[1], channels_count)) return Img(arr[..., 2].copy(), dimensions='hw') else: return None def __get_output_folder(self): selected_items = self.list.selectedItems() if selected_items: filename = selected_items[0].toolTip() filename0_without_ext = os.path.splitext(filename)[0] return filename0_without_ext else: return None def delete_from_list(self): list_items = self.list.selectedItems() # empty list --> nothing to do if not list_items: return for item in list_items: self.list.takeItem(self.list.row(item)) def save_current_mask(self): output_folder = self.__get_output_folder() if output_folder is None: logger.error('No image is selected --> nothing to save') return mask = self.__get_mask_img_from_overlay() if mask is None: logger.error('No mask/overlay detected --> nothing to save') return if self.tabs.currentIndex() == 0: print('saving', os.path.join(output_folder, 'mask.tif')) mask.save(os.path.join(output_folder, 'mask.tif')) elif self.tabs.currentIndex() == 1: print('saving', os.path.join(output_folder, 'cellBodyMask.tif')) mask.save(os.path.join(output_folder, 'cellBodyMask.tif')) else: print('saving', os.path.join(output_folder, 'handCorrection.tif')) mask.save(os.path.join(output_folder, 'handCorrection.tif')) def detect_neuronal_cell_body(self): try: # get image and detect cell body mask = detect_cell_body( self.img, fillHoles=self.fill_holes_up_to.value(), denoise=self.min_obj_size_px.value(), nbOfErosions=self.nb_erosion_cellbody.value(), nbOfDilatations=self.nb_dilation_cellbody.value(), extraCutOff=self.extraCutOff_cell_body.value(), channel=self.channels.currentText()) if mask is not None: self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() else: logger.error('Cell body could not be detected') except: traceback.print_exc() def __get_neuronal_mask(self, warn=True): output_folder = self.__get_output_folder() if output_folder is None: if warn: logger.error('No image selected --> nothing to do') return None if os.path.exists(os.path.join(output_folder, 'mask.tif')): # NB should I check the nb of channels --> no I don't want to handle externally created files and want people to rely fully on my stuff that has return Img(os.path.join(output_folder, 'mask.tif')) else: if warn: logger.error( 'Neuronal mask not found --> Please create one in the "Mask neuron" tab first' ) return None def __get_corrected_mask(self, warn=True): output_folder = self.__get_output_folder() if output_folder is None: if warn: logger.error('No image selected --> nothing to do') return None if os.path.exists(os.path.join(output_folder, 'handCorrection.tif')): return Img(os.path.join(output_folder, 'handCorrection.tif')) elif os.path.exists(os.path.join(output_folder, 'mask.tif')) and not warn: return Img(os.path.join(output_folder, 'mask.tif')) return None def __get_cellbody_mask(self, warn=True): output_folder = self.__get_output_folder() if output_folder is None: if warn: logger.error('No image selected --> nothing to do') return None if os.path.exists(os.path.join(output_folder, 'cellBodyMask.tif')): # NB should I check the nb of channels --> no I don't want to handle externally created files and want people to rely fully on my stuff that has return Img(os.path.join(output_folder, 'cellBodyMask.tif')) else: if warn: logger.error( 'Cell body mask not found --> Please create one in the "Mask cell body" tab first' ) return None # seems ok for now def watershed_segment_the_neuron(self): try: # get raw image and segment it using the watershed algorithm # make it load the neuronal mask neuronal_mask = self.__get_neuronal_mask() if neuronal_mask is None: return # TODO should I add autoskel or not mask = watershed_segment_neuron( self.img, neuronal_mask, fillSize=self.jSpinner11.value(), autoSkel=True, first_blur=self.whsed_big_blur.value(), second_blur=self.whsed_small_blur.value(), min_size=self.wshed_rm_small_cells.value(), channel=self.channels.currentText()) if mask is not None: self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() else: logger.error( 'Something went wrong, the neuron could not be segmented, sorry...' ) except: traceback.print_exc() def save_segmented_bonds(self): output_folder = self.__get_output_folder() if output_folder is None: logger.error('No image is selected --> nothing to save') return # get mask the find neurons mask = self.__get_mask_img_from_overlay() if mask is None: logger.error('No mask/overlay detected --> nothing to do') return mask = detect_cell_bonds(mask) if mask is None: logger.error( 'Could not find dendrites, are you sure a mask is overlayed over the neuron' ) return # code for conversion of 24 bits numpy array to an RGB one --> keep and store in Img at some point cause useful # convert 24 bits array to RGB RGB_mask = np.zeros(shape=(*mask.shape, 3), dtype=np.uint8) RGB_mask[..., 2] = mask & 255 RGB_mask[..., 1] = (mask >> 8) & 255 RGB_mask[..., 0] = (mask >> 16) & 255 Img(RGB_mask, dimensions='hwc').save(os.path.join(output_folder, 'bonds.tif')) def prune_neuron_unconnected_segments(self): # get mask the find neurons mask = self.__get_mask_img_from_overlay() if mask is None: logger.error('No mask/overlay detected --> nothing to do') return mask = find_neurons( mask, neuron_minimum_size_threshold=self.find_neurons_min_size.value(), return_unconnected=True) if mask is None: logger.error( 'Could not find neurons, are you sure a mask is overlayed over the neuron' ) return self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() def apply_cell_body_to_skeletonized_mask(self): mask = self.__get_mask_img_from_overlay() if mask is None: logger.error('No mask/overlay detected --> nothing to do') return cell_body_mask = self.__get_cellbody_mask() if cell_body_mask is None: return cell_body_outline = get_cell_body_outline(cell_body_mask, mask) if cell_body_outline is None: logger.error( 'Error could not add cell body outline to the neuronal mask...' ) return self.paint.imageDraw = Img(self.createRGBA(cell_body_outline), dimensions='hwc').getQimage() self.paint.update() def find_neurons_in_mask(self): # get mask the find neurons mask = self.__get_mask_img_from_overlay() if mask is None: logger.error('No mask/overlay detected --> nothing to do') return mask_copy = mask.copy() mask = find_neurons( mask, neuron_minimum_size_threshold=self.find_neurons_min_size.value()) if mask is None: logger.error( 'Could not find neurons, are you sure a mask is overlayed over the neuron' ) return # we set the red channel, the blue one, the alpha transparency (channel 4) and finally we only allow alpha channel in the two masks regions to keep the rest of the stuff final_overlay = np.zeros(shape=(*mask_copy.shape, 4), dtype=np.uint8) final_overlay[..., 0] = np.logical_xor(mask, mask_copy).astype( np.uint8) * 255 # blue channel final_overlay[mask == 0, 0] = 0 final_overlay[..., 1] = final_overlay[ ..., 0] # green channel # copy the channel to make the stuff appear cyan final_overlay[..., 2] = mask_copy # red channel final_overlay[np.logical_or(mask, mask_copy) != 0, 3] = 255 # --> need set alpha transparency of the image self.paint.imageDraw = Img(final_overlay, dimensions='hwc').getQimage() self.paint.update() def prune_dendrites(self): prune_lgth = self.prune_length.value() if prune_lgth <= 0: logger.info('prune length is 0 --> nothing to do') return # get the mask from displayed image mask = self.__get_mask_img_from_overlay() if mask is None: logger.error('No mask/overlay detected --> nothing to do') return # see how to get the stuff ???? mask = prune_dendrites(mask, prune_below=prune_lgth) if mask is None: logger.error( 'Could not prune dendrites, are you sure there is a mask ovrlayed on the neuron' ) return self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() def skeletonize_mask(self): # get mask then skeletonize it then return it --> see exactly try: # get raw image and segment it using the skeletonize algorithm # make it load the neuronal mask neuronal_mask = self.__get_neuronal_mask() if neuronal_mask is None: return mask = skel_segment_neuronal_mask(neuronal_mask) if mask is not None: self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() else: logger.error( 'Something went wrong, the neuron could not be sekeletonized, sorry...' ) except: traceback.print_exc() def _onTabChange(self): # if tab is changed --> do stuff # load files or warn... if self.tabs.currentIndex() == 0: mask = self.__get_neuronal_mask(warn=False) if mask is not None: self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() elif self.tabs.currentIndex() == 1: mask = self.__get_cellbody_mask(warn=False) if mask is not None: self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() elif self.tabs.currentIndex() == 2: mask = self.__get_corrected_mask(warn=False) if mask is not None: self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() def run_threshold_neuron(self): try: local_or_global = 'global' if self.sender() == self.local_threshold: local_or_global = 'local' elif self.sender() == self.local_n_global_threshold: local_or_global = 'local+global' mask = threshold_neuron( self.img, mode=local_or_global, blur_method=self.threshold_method.currentText(), spin_value=self.extra_value_for_threshold.value(), channel=self.channels.currentText()) if mask is not None: self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() except: traceback.print_exc() def channelChange(self, i): if self.Stack.currentIndex() == 0: if i == 0: self.paint.setImage(self.img) else: channel_img = self.img.imCopy(c=i - 1) self.paint.setImage(channel_img) self.paint.update() def penSizechange(self): self.paint.brushSize = self.penSize.value() def selectionChanged(self): self.paint.maskVisible = True selected_items = self.list.selectedItems() if selected_items: start = timer() if self.img is not None: # make sure we don't load the image twice if selected_items[0].toolTip() != self.img.metadata['path']: self.img = Img(selected_items[0].toolTip()) logger.debug("took " + str(timer() - start) + " secs to load image") else: logger.debug("image already loaded --> ignoring") else: self.img = Img(selected_items[0].toolTip()) logger.debug("took " + str(timer() - start) + " secs to load image") if self.img is not None: selection = self.channels.currentIndex() self.channels.disconnect() self.channels.clear() comboData = ['merge'] if self.img.has_c(): for i in range(self.img.get_dimension('c')): comboData.append(str(i)) logger.debug('channels found ' + str(comboData)) self.channels.addItems(comboData) if selection != -1 and selection < self.channels.count(): self.channels.setCurrentIndex(selection) else: self.channels.setCurrentIndex(0) self.channels.currentIndexChanged.connect(self.channelChange) if selected_items: self.statusBar().showMessage('Loading ' + selected_items[0].toolTip()) selection = self.channels.currentIndex() if selection == 0: self.paint.setImage(self.img) else: self.paint.setImage(self.img.imCopy(c=selection - 1)) self.scaleImage(0) self.update() self.paint.update() if self.list.currentItem() and self.list.currentItem().icon( ).isNull(): logger.debug('Updating icon') icon = QIcon(QPixmap.fromImage(self.paint.image)) pixmap = icon.pixmap(24, 24) icon = QIcon(pixmap) self.list.currentItem().setIcon(icon) else: logger.debug("Empty selection") self.paint.image = None self.scaleImage(0) self.update() self.paint.update() self.img = None # try update also the masks if they are available try: self._onTabChange() except: pass def clearlayout(self, layout): for i in reversed(range(layout.count())): layout.itemAt(i).widget().setParent(None) def showHideMask(self): self.paint.maskVisible = not self.paint.maskVisible self.paint.update() def escape(self): if self.Stack.isFullScreen(): self.fullScreen() def fullScreen(self): if not self.Stack.isFullScreen(): self.Stack.setWindowFlags( QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint | # QtCore.Qt.WindowTitleHint | # QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowStaysOnTopHint) self.Stack.showFullScreen() else: self.Stack.setWindowFlags(QtCore.Qt.Widget) self.grid.addWidget(self.Stack, 0, 0) # dirty hack to make it repaint properly --> obviously not all lines below are required but some are --> need test, the last line is key though self.grid.update() self.Stack.update() self.Stack.show() self.centralWidget().setLayout(self.grid) self.centralWidget().update() self.update() self.show() self.repaint() self.Stack.update() self.Stack.repaint() self.centralWidget().repaint() def nextFrame(self): idx = self.list.model().index(self.list.currentRow() + 1, 0) if idx.isValid(): self.list.selectionModel().setCurrentIndex( idx, QItemSelectionModel.ClearAndSelect) # SelectCurrent def remove_blobs(self): blob_size = self.remove_blobs_size.value() if blob_size <= 0: logger.info('blob size is 0 --> nothing to do') return # get the mask from displayed image mask = self.__get_mask_img_from_overlay() if mask is None: logger.error('No mask/overlay detected --> nothing to save') return mask = remove_small_objects(mask.astype(np.bool), min_size=blob_size, connectivity=2, in_place=False) # then place back pixels in the mask # now set the mask back # plt.imshow(mask) # plt.show() self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() def runSkel(self): # only allow that for tab 3 if self.tabs.currentIndex() == 2: mask = self.__get_mask_img_from_overlay() if mask is None: logger.error('No mask/overlay detected --> nothing to do') return # just skeletonize the image mask = skel_segment_neuronal_mask( mask, fill_holes=0) # should I put it to 0 or other things ??? if mask is None: logger.error('Could not skeletonize user edited mask...') return self.paint.imageDraw = Img(self.createRGBA(mask), dimensions='hwc').getQimage() self.paint.update() def createRGBA(self, handCorrection): # use pen color to display the mask # in fact I need to put the real color RGBA = np.zeros((handCorrection.shape[0], handCorrection.shape[1], 4), dtype=np.uint8) red = self.paint.drawColor.red() green = self.paint.drawColor.green() blue = self.paint.drawColor.blue() # bug somewhere --> fix it some day --> due to bgra instead of RGBA RGBA[handCorrection != 0, 0] = blue # b RGBA[handCorrection != 0, 1] = green # g RGBA[handCorrection != 0, 2] = red # r RGBA[..., 3] = 255 # alpha --> indeed alpha RGBA[handCorrection == 0, 3] = 0 # very complex fix some day return RGBA def prevFrame(self): idx = self.list.model().index(self.list.currentRow() - 1, 0) if idx.isValid(): self.list.selectionModel().setCurrentIndex( idx, QItemSelectionModel.ClearAndSelect) def zoomIn(self): self.statusBar().showMessage('Zooming in', msecs=200) if self.Stack.currentIndex() == 0: self.scaleImage(self.zoom_increment) def zoomOut(self): self.statusBar().showMessage('Zooming out', msecs=200) if self.Stack.currentIndex() == 0: self.scaleImage(-self.zoom_increment) def defaultSize(self): self.paint.adjustSize() self.scale = 1.0 self.scaleImage(0) def scaleImage(self, factor): self.scale += factor if self.paint.image is not None: self.paint.resize(self.scale * self.paint.image.size()) else: # no image set size to 0, 0 --> scroll pane will auto adjust self.paint.resize(QSize(0, 0)) self.scale -= factor # reset zoom self.paint.scale = self.scale # self.paint.vdp.scale = self.scale self.zoomInAct.setEnabled(self.scale < self.max_scaling_factor) self.zoomOutAct.setEnabled(self.scale > self.min_scaling_factor) # allow DND def dragEnterEvent(self, event): if event.mimeData().hasUrls: event.accept() else: event.ignore() def dragMoveEvent(self, event): if event.mimeData().hasUrls: event.setDropAction(QtCore.Qt.CopyAction) event.accept() else: event.ignore() # handle DND on drop def dropEvent(self, event): if event.mimeData().hasUrls: event.setDropAction(QtCore.Qt.CopyAction) event.accept() urls = [] for url in event.mimeData().urls(): urls.append(url.toLocalFile()) for url in urls: import os item = QListWidgetItem(os.path.basename(url), self.list) item.setToolTip(url) self.list.addItem(item) else: event.ignore()
class SunPlotPy(Spatial, QMainWindow): """ The main frame of the application """ title = 'sunplot(py)' # Plotting options autoclim = True showedges = False bgcolor = 'k' textcolor = 'w' cmap = 'RdBu' particlesize = 1.8 particlecolor = 'm' # other flags collectiontype = 'cells' oldcollectiontype = 'cells' # tindex = 0 depthlevs = [0., 10., 100., 200., 300., 400., 500.,\ 1000.,2000.,3000.,4000.,5000] _FillValue = 999999 def __init__(self, parent=None): #wx.Frame.__init__(self, None, -1, self.title) QMainWindow.__init__(self, parent) #super(SunPlotPy, self).__init__(parent) self.create_menu() #self.create_status_bar() self.create_main_panel() #self.draw_figure() def create_menu(self): self.file_menu = self.menuBar().addMenu("&File") ### # File Menu ### # Load a hydro output file load_file_action = self.create_action("&Open file",\ shortcut="ctrl-o", slot=self.on_open_file, tip="open netcdf file") load_grid_action = self.create_action("&Open grid",\ shortcut="ctrl-g", slot=self.on_load_grid, tip="open suntans grid") save_anim_action = self.create_action("&Save animation",\ shortcut="ctrl-a", slot=self.on_save_anim, tip="animate current scene") quit_action = self.create_action("&Exit",\ shortcut="ctrl-x", slot=self.close, tip="Close the application") self.add_actions(self.file_menu, (load_file_action, load_grid_action,\ save_anim_action, None, quit_action)) # self.Bind(wx.EVT_MENU, self.on_open_file, m_expt) ### # Tools menu ### self.tools_menu = self.menuBar().addMenu("&Tools") ### # File Menu ### # Load a hydro output file load_stat_action = self.create_action("&Plot grid size statistics",\ slot=self.on_plot_gridstat, tip="grid stats") self.add_actions(self.tools_menu, (load_stat_action, )) # # Load a grid file # m_grid = menu_file.Append(-1, "&Load grid\tCtrl-G", "Load SUNTANS grid from folder") # self.Bind(wx.EVT_MENU, self.on_load_grid, m_grid) # # Load a particle file # m_part = menu_file.Append(-1, "&Load PTM file\tCtrl-Shift-P", "Load a PTM file") # self.Bind(wx.EVT_MENU, self.on_load_ptm, m_part) # # Save current scene as an animation # m_anim = menu_file.Append(-1,"&Save animation of current scene\tCtrl-S","Save animation") # self.Bind(wx.EVT_MENU, self.on_save_anim, m_anim) # # Save the current figure # m_prin = menu_file.Append(-1,"&Print current scene\tCtrl-P","Save figure") # self.Bind(wx.EVT_MENU, self.on_save_fig, m_prin) # menu_file.AppendSeparator() # # Exit # m_exit = menu_file.Append(-1, "E&xit\tCtrl-X", "Exit") # self.Bind(wx.EVT_MENU, self.on_exit, m_exit) # ### # # Tools menu # ### # menu_tools = wx.Menu() # m_gridstat = menu_tools.Append(-1, "&Plot grid size statistics", "SUNTANS grid size") # self.Bind(wx.EVT_MENU, self.on_plot_gridstat, m_gridstat) # m_countcells = menu_tools.Append(-1, "&Count # grid cells", "Grid cell count") # self.Bind(wx.EVT_MENU, self.on_count_cells, m_countcells) # m_overlaybathy = menu_tools.Append(-1, "&Overlay depth contours", "Depth overlay") # self.Bind(wx.EVT_MENU, self.on_overlay_bathy, m_overlaybathy) # # ### # # Help Menu # ### # menu_help = wx.Menu() # m_about = menu_help.Append(-1, "&About\tF1", "About the demo") # self.Bind(wx.EVT_MENU, self.on_about, m_about) # # # # Add all of the menu bars # self.menubar.Append(menu_file, "&File") # self.menubar.Append(menu_tools, "&Tools") # self.menubar.Append(menu_help, "&Help") # self.SetMenuBar(self.menubar) def add_actions(self, target, actions): for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def create_action( self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, ): #signal="triggered()"): action = QAction(text, self) if icon is not None: action.setIcon(QIcon(":/%s.png" % icon)) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: #self.connect(action, SIGNAL(signal), slot) # Qt5 style action.triggered.connect(slot) if checkable: action.setCheckable(True) return action def create_main_panel(self): """ Creates the main panel with all the controls on it: * mpl canvas * mpl navigation toolbar * Control panel for interaction """ self.panel = QWidget() # Create the mpl Figure and FigCanvas objects. # 5x4 inches, 100 dots-per-inch # self.dpi = 100 #self.fig = Figure((7.0, 6.0), dpi=self.dpi,facecolor=self.bgcolor) self.fig = Figure((7.0, 6.0), dpi=self.dpi) #self.canvas = FigCanvas(self.panel, -1, self.fig) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.panel) # Since we have only one plot, we can use add_axes # instead of add_subplot, but then the subplot # configuration tool in the navigation toolbar wouldn't # work. # self.axes = self.fig.add_subplot(111) #SetAxColor(self.axes,self.textcolor,self.bgcolor) # Bind the 'pick' event for clicking on one of the bars # #self.canvas.mpl_connect('pick_event', self.on_pick) ######### ## Create widgets ######### self.variable_list = QComboBox() self.variable_list.addItem("Select a variable...") self.variable_list.activated[str].connect(self.on_select_variable) self.time_list = QComboBox() self.time_list.addItem("Select a time...") self.time_list.activated[int].connect(self.on_select_time) self.depthlayer_list = QComboBox() self.depthlayer_list.addItem("Select a vertical layer...") self.depthlayer_list.activated[int].connect(self.on_select_depth) self.show_edge_check = QCheckBox('Show Edges', self) #self.show_edge_check.toggle() self.show_edge_check.stateChanged.connect(self.on_show_edges) cmaps = list(matplotlib.cm.datad.keys()) cmaps.sort() self.colormap_list = QComboBox() self.colormap_list.clear() self.colormap_list.addItems(cmaps) self.colormap_list.activated[str].connect(self.on_select_cmap) self.clim_check = QCheckBox('Manual color limits', self) #self.show_edge_check.toggle() self.clim_check.stateChanged.connect(self.on_clim_check) #self.clim_check = wx.CheckBox(self.panel, -1, # "Manual color limits ", # style=wx.ALIGN_RIGHT) #self.clim_check.Bind(wx.EVT_CHECKBOX, self.on_clim_check) self.climlow = QLineEdit() self.climlow.textChanged[str].connect(self.on_climlow) self.climhigh = QLineEdit() self.climhigh.textChanged[str].connect(self.on_climhigh) ## Labels #self.variable_label = wx.StaticText(self.panel, -1,"Variable:",size=(200,-1)) #self.time_label = wx.StaticText(self.panel, -1,"Time step:",size=(200,-1)) #self.depth_label = wx.StaticText(self.panel, -1,"Vertical level:",size=(200,-1)) # Create the navigation toolbar, tied to the canvas # self.toolbar = NavigationToolbar(self.canvas, self) #self.toolbar.toolitems[8][3]='my_save_fig' #def my_save_fig(self,*args): # print 'saving figure' ## return "break" ######### # Layout with box sizers ######### hbox = QHBoxLayout() for w in [self.variable_list, self.time_list, self.depthlayer_list]: hbox.addWidget(w) hbox.setAlignment(w, Qt.AlignVCenter) hbox1 = QHBoxLayout() for w in [ self.show_edge_check, self.colormap_list, self.clim_check, self.climlow, self.climhigh ]: hbox1.addWidget(w) hbox1.setAlignment(w, Qt.AlignVCenter) self.vbox = QVBoxLayout() self.vbox.addWidget(self.canvas) self.vbox.addWidget(self.toolbar) self.vbox.addLayout(hbox) self.vbox.addLayout(hbox1) self.panel.setLayout(self.vbox) self.setCentralWidget(self.panel) # ########### ## Event functions ########### def create_figure(self): """ Creates the figure """ # Find the colorbar limits if unspecified if self.autoclim: self.clim = [self.data.min(), self.data.max()] self.climlow.setText('%3.1f' % self.clim[0]) self.climhigh.setText('%3.1f' % self.clim[1]) if 'collection' in self.__dict__: #self.collection.remove() self.axes.collections.remove(self.collection) else: # First call - set the axes limits self.axes.set_aspect('equal') self.axes.set_xlim(self.xlims) self.axes.set_ylim(self.ylims) if self.collectiontype == 'cells': self.collection = PolyCollection(self.xy, cmap=self.cmap) self.collection.set_array(np.array(self.data[:])) if not self.showedges: self.collection.set_edgecolors( self.collection.to_rgba(np.array((self.data[:])))) elif self.collectiontype == 'edges': xylines = [self.xp[self.edges], self.yp[self.edges]] linesc = [ list(zip(xylines[0][ii, :], xylines[1][ii, :])) for ii in range(self.Ne) ] self.collection = LineCollection(linesc, array=np.array(self.data[:]), cmap=self.cmap) self.collection.set_clim(vmin=self.clim[0], vmax=self.clim[1]) self.axes.add_collection(self.collection) self.title = self.axes.set_title(self.genTitle(), color=self.textcolor) self.axes.set_xlabel('Easting [m]') self.axes.set_ylabel('Northing [m]') # create a colorbar if 'cbar' not in self.__dict__: self.cbar = self.fig.colorbar(self.collection) #SetAxColor(self.cbar.ax.axes,self.textcolor,self.bgcolor) else: #pass print('Updating colorbar...') #self.cbar.check_update(self.collection) self.cbar.on_mappable_changed(self.collection) self.canvas.draw() def update_figure(self): if self.autoclim: self.clim = [self.data.min(), self.data.max()] self.climlow.setText('%3.1f' % self.clim[0]) self.climhigh.setText('%3.1f' % self.clim[1]) else: self.clim = [float(self.climlow.text()),\ float(self.climhigh.text())] # check whether it is cell or edge type if self.hasDim(self.variable, self.griddims['Ne']): self.collectiontype = 'edges' elif self.hasDim(self.variable, self.griddims['Nc']): self.collectiontype = 'cells' # Create a new figure if the variable has gone from cell to edge of vice # versa if not self.collectiontype == self.oldcollectiontype: self.create_figure() self.oldcollectiontype = self.collectiontype self.collection.set_array(np.array(self.data[:])) self.collection.set_clim(vmin=self.clim[0], vmax=self.clim[1]) # Cells only if self.collectiontype == 'cells': if not self.showedges: self.collection.set_edgecolors( self.collection.to_rgba(np.array((self.data[:])))) else: self.collection.set_edgecolors('k') self.collection.set_linewidths(0.2) # Update the title self.title = self.axes.set_title(self.genTitle(), color=self.textcolor) #Update the colorbar self.cbar.update_normal(self.collection) # redraw the figure self.canvas.draw() #def on_pick(self, event): # # The event received here is of the type # # matplotlib.backend_bases.PickEvent # # # # It carries lots of information, of which we're using # # only a small amount here. # # # box_points = event.artist.get_bbox().get_points() # msg = "You've clicked on a bar with coords:\n %s" % box_points # # dlg = wx.MessageDialog( # self, # msg, # "Click!", # wx.OK | wx.ICON_INFORMATION) # dlg.ShowModal() # dlg.Destroy() # def on_select_variable(self, event): #vname = event.GetString() vname = event #self.flash_status_message("Selecting variable: %s"%vname) # update the spatial object and load the data self.variable = vname self.loadData(variable=self.variable) # Check if the variable has a depth coordinate depthstr = [''] # If so populate the vertical layer box if self.hasDim(self.variable, self.griddims['Nk']): depthstr = ['%3.1f' % self.z_r[k] for k in range(self.Nkmax)] depthstr += ['surface', 'seabed'] elif self.hasDim(self.variable, 'Nkw'): depthstr = ['%3.1f' % self.z_w[k] for k in range(self.Nkmax + 1)] self.depthlayer_list.clear() self.depthlayer_list.addItems(depthstr) # Update the plot self.update_figure() def on_select_time(self, event): self.tindex = event # # Update the object time index and reload the data #if self.plot_type=='hydro': if not self.tstep == self.tindex: self.tstep = self.tindex self.loadData() #self.flash_status_message("Selecting variable: %s..."%event.GetString()) # Update the plot self.update_figure() #elif self.plot_type=='particles': # self.PTM.plot(self.tindex,ax=self.axes,\ # xlims=self.axes.get_xlim(),ylims=self.axes.get_ylim()) # # self.canvas.draw() def on_select_depth(self, event): print(event) kindex = event if not self.klayer[0] == kindex: # Check if its the seabed or surface value if kindex >= self.Nkmax: kindex = event.GetString() self.klayer = [kindex] self.loadData() #self.flash_status_message("Selecting depth: %s..."%event.GetString()) # Update the plot self.update_figure() def on_open_file(self, event): file_choices = "SUNTANS NetCDF (*.nc);;All Files (*.*)" dlg = QFileDialog.getOpenFileNames(self, "Open SUNTANS file...", "", file_choices) path = dlg[0] if len(path) == 0: return self.statusBar().showMessage("Opening SUNTANS file: %s" % path) try: Spatial.__init__(self, path, _FillValue=self._FillValue) except: Spatial.__init__(self, path, _FillValue=-999999) startvar = 'dv' self.statusBar().clearMessage() # Populate the drop down menus vnames = self.listCoordVars() self.variable_list.clear() self.variable_list.addItems(vnames) # Update the time drop down list if 'time' in self.__dict__: self.timestr = [ datetime.strftime(tt, '%d-%b-%Y %H:%M:%S') for tt in self.time ] else: # Assume that it is a harmonic-type file self.timestr = self.nc.Constituent_Names.split() self.time_list.clear() self.time_list.addItems(self.timestr) # Draw the depth if startvar in vnames: self.variable = startvar self.loadData() self.create_figure() def on_load_grid(self, event): dir_ = QFileDialog.getExistingDirectory(None, 'Select a SUNTANS grid folder:',\ '~/', QFileDialog.ShowDirsOnly) print(dir_) if dir_ is not None: path = dir_ # Initialise the class #self.flash_status_message("Opening SUNTANS grid from folder: %s" % path) Grid.__init__(self, path) # Plot the Grid if 'collection' in self.__dict__: self.axes.collections.remove(self.collection) self.axes, self.collection = self.plotmesh(ax=self.axes, edgecolors='y') # redraw the figure self.canvas.draw() #def on_load_ptm(self, event): # file_choices = "PTM NetCDF (*.nc)|*.nc|PTM Binary (*_bin.out)|*_bin.out|All Files (*.*)|*.*" # # dlg = wx.FileDialog( # self, # message="Open PTM file...", # defaultDir=os.getcwd(), # defaultFile="", # wildcard=file_choices, # style= wx.FD_MULTIPLE) # # if dlg.ShowModal() == wx.ID_OK: # self.plot_type = 'particles' # path = dlg.GetPath() # # Initialise the class # if dlg.GetFilterIndex() == 0: #SUNTANS # self.flash_status_message("Opening PTM netcdf file: %s" % path) # self.PTM = PtmNC(path) # elif dlg.GetFilterIndex() == 1: #PTM # self.flash_status_message("Opening PTM binary file: %s" % path) # self.PTM = PtmBin(path) # self.Nt = self.PTM.nt # # # Update the time drop down list # self.timestr = [datetime.strftime(tt,'%d-%b-%Y %H:%M:%S') for tt in self.PTM.time] # self.time_list.SetItems(self.timestr) # # Plot the first time step # if self.__dict__.has_key('xlims'): # self.PTM.plot(self.PTM.nt-1,ax=self.axes,xlims=self.xlims,\ # ylims=self.ylims,color=self.particlecolor,\ # fontcolor='w',markersize=self.particlesize) # else: # self.PTM.plot(self.PTM.nt-1,ax=self.axes,fontcolor='w',\ # color=self.particlecolor,markersize=self.particlesize) # # redraw the figure # self.canvas.draw() # def on_show_edges(self, event): if event > 0: self.showedges = True else: self.showedges = False # Update the figure self.update_figure() def on_clim_check(self, event): if event > 0: self.autoclim = False self.update_figure() else: self.autoclim = True def on_climlow(self, event): try: self.clim[0] = float(event) except: return # do nothing # self.clim[0] = event.GetString() # #self.update_figure() def on_climhigh(self, event): try: self.clim[1] = float(event) except: return # do nothing # print event # self.clim[1] = event.GetString() # #self.update_figure() def on_select_cmap(self, event): self.cmap = event self.collection.set_cmap(self.cmap) # Update the figure self.update_figure() #def on_save_fig(self,event): # """ # Save a figure of the current scene to a file # """ # file_choices = " (*.png)|*.png| (*.pdf)|*.pdf |(*.jpg)|*.jpg |(*.eps)|*eps " # filters=['.png','.pdf','.png','.png'] # # dlg = wx.FileDialog( # self, # message="Save figure to file...", # defaultDir=os.getcwd(), # defaultFile="", # wildcard=file_choices, # style= wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) # if dlg.ShowModal() == wx.ID_OK: # path = dlg.GetPath() # ext = filters[dlg.GetFilterIndex()] # if ext in path: # outfile=path # else: # outfile = path+ext # self.fig.savefig(outfile) # def on_save_anim(self, event): """ Save an animation of the current scene to a file """ #file_choices = "Quicktime (*.mov)|*.mov| (*.gif)|*.gif| (*.avi)|*.avi |(*.mp4)|*.mp4 " #filters=['.mov','.gif','.avi','.mp4'] filters = "Movie formats (*.mp4 *.avi *.gif);;All files (*.*)" dir_ = QFileDialog.getSaveFileName(None, 'Save animation to file:',\ '~/', filters) print(dir_) #dlg = wx.FileDialog( # self, # message="Output animation file...", # defaultDir=os.getcwd(), # defaultFile="", # wildcard=file_choices, # style= wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) if dir_ is not None: outfile = dir_[0] ext = outfile[-4::] # Create the animation #self.tstep = range(self.Nt) # Use all time steps for animation #self.animate(cbar=self.cbar,cmap=self.cmap,\ # xlims=self.axes.get_xlim(),ylims=self.axes.get_ylim()) def initanim(): return (self.title, self.collection) #if not self.plot_type=='particles': # return (self.title, self.collection) #else: # return (self.PTM.title,self.PTM.p_handle) def updateScalar(i): self.tstep = [i] self.loadData() self.update_figure() return (self.title, self.collection) #if not self.plot_type=='particles': # self.tstep=[i] # self.loadData() # self.update_figure() # return (self.title,self.collection) #elif self.plot_type=='particles': # self.PTM.plot(i,ax=self.axes,\ # xlims=self.axes.get_xlim(),ylims=self.axes.get_ylim()) # return (self.PTM.title,self.PTM.p_handle) self.anim = animation.FuncAnimation(self.fig, \ updateScalar, init_func = initanim, frames=self.Nt, interval=50, blit=True) if ext == '.gif': self.anim.save(outfile, writer='imagemagick', fps=6) elif ext == '.mp4': print('Saving html5 video...') # Ensures html5 compatibility self.anim.save(outfile,fps=6,\ writer='ffmpeg',\ bitrate=3600,extra_args=['-vcodec','libx264']) #writer='mencoder', #bitrate=3600,extra_args=['-ovc','x264']) # mencoder options else: self.anim.save(outfile, writer='mencoder', fps=6, bitrate=3600) # Return the figure back to its status del self.anim self.tstep = self.tindex self.loadData() self.update_figure() print('Finished saving animation to %s' % outfile) print(72 * '#') #if not self.plot_type=='particles': # self.loadData() # self.update_figure() # Bring up a dialog box #dlg2= wx.MessageDialog(self, 'Animation complete.', "Done", wx.OK) #dlg2.ShowModal() #dlg2.Destroy() #def on_exit(self, event): # self.Destroy() # #def on_about(self, event): # msg = """ SUNTANS NetCDF visualization tool # # *Author: Matt Rayson # *Institution: Stanford University # *Created: October 2013 # """ # dlg = wx.MessageDialog(self, msg, "About", wx.OK) # dlg.ShowModal() # dlg.Destroy() #def on_count_cells(self,eveny): # msg = "Total 3-D grid cells = %d"%(self.count_cells()) # dlg = wx.MessageDialog(self, msg, "No. cells", wx.OK) # dlg.ShowModal() # dlg.Destroy() #def on_overlay_bathy(self,event): # # Plot depth contours # print 'Plotting contours...' # self.contourf(z=self.dv, clevs=self.depthlevs,\ # ax=self.axes,\ # filled=False, colors='0.5', linewidths=0.5, zorder=1e6) # print 'Done' def on_plot_gridstat(self, event): """ Plot the grid size histogram in a new figure """ matplotlib.pyplot.figure() self.plothist() matplotlib.pyplot.show()
class LCD20x4(PluginBase): MAX_LINE = 4 MAX_POSITION = 20 qtcb_pressed = pyqtSignal(int) qtcb_released = pyqtSignal(int) def __init__(self, *args): super().__init__(BrickletLCD20x4, *args) self.lcd = self.device # the firmware version of a EEPROM Bricklet can (under common circumstances) # not change during the lifetime of an EEPROM Bricklet plugin. therefore, # it's okay to make final decisions based on it here self.has_custom_character = self.firmware_version >= (2, 0, 1) self.qtcb_pressed.connect(self.cb_pressed) self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_PRESSED, self.qtcb_pressed.emit) self.qtcb_released.connect(self.cb_released) self.lcd.register_callback(self.lcd.CALLBACK_BUTTON_RELEASED, self.qtcb_released.emit) self.line_label = QLabel('Line:') self.line_combo = QComboBox() for i in range(LCD20x4.MAX_LINE): self.line_combo.addItem(str(i)) self.pos_label = QLabel('Position:') self.pos_combo = QComboBox() for i in range(LCD20x4.MAX_POSITION): self.pos_combo.addItem(str(i)) self.line_pos_layout = QHBoxLayout() self.line_pos_layout.addWidget(self.line_label) self.line_pos_layout.addWidget(self.line_combo) self.line_pos_layout.addWidget(self.pos_label) self.line_pos_layout.addWidget(self.pos_combo) self.line_pos_layout.addStretch() self.text_label = QLabel('Text:') self.text_edit = QLineEdit() self.text_edit.setMaxLength(LCD20x4.MAX_POSITION) self.text_button = QPushButton('Send Text') self.text_layout = QHBoxLayout() self.text_layout.addWidget(self.text_label) self.text_layout.addWidget(self.text_edit) self.text_layout.addWidget(self.text_button) self.clear_button = QPushButton("Clear Display") self.bl_button = QPushButton("Querying backlight status...") self.cursor_button = QPushButton("Querying cursor status...") self.blink_button = QPushButton("Querying blink status...") self.onofflayout = QHBoxLayout() self.onofflayout.addWidget(self.bl_button) self.onofflayout.addWidget(self.cursor_button) self.onofflayout.addWidget(self.blink_button) self.b0_label = QLabel('Button 0: Released,') self.b1_label = QLabel('Button 1: Released,') self.b2_label = QLabel('Button 2: Released,') self.b3_label = QLabel('Button 3: Released') self.buttonlayout = QHBoxLayout() self.buttonlayout.addWidget(self.b0_label) self.buttonlayout.addWidget(self.b1_label) self.buttonlayout.addWidget(self.b2_label) self.buttonlayout.addWidget(self.b3_label) self.cursor_button.clicked.connect(self.cursor_clicked) self.blink_button.clicked.connect(self.blink_clicked) self.clear_button.clicked.connect(self.clear_clicked) self.bl_button.clicked.connect(self.bl_clicked) self.text_button.clicked.connect(self.text_clicked) if self.has_custom_character: line = QFrame() line.setObjectName("line") line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.scribble_widget = ScribbleWidget(5, 8, 25, QColor(Qt.white), QColor(Qt.blue)) self.char_index_label = QLabel('Index:') self.char_index_combo = QComboBox() self.char_index_combo.currentIndexChanged.connect(self.char_index_changed) for i in range(8): self.char_index_combo.addItem(str(i)) self.char_index_layout = QHBoxLayout() self.char_index_layout.addStretch() self.char_index_layout.addWidget(self.char_index_label) self.char_index_layout.addWidget(self.char_index_combo) self.char_index_layout.addStretch() self.char_index_save = QPushButton('Save Character') self.char_index_save.clicked.connect(self.char_index_save_clicked) self.char_show = QPushButton('Show all Custom Characters on LCD') self.char_show.clicked.connect(self.show_clicked) self.char_save_layout = QVBoxLayout() self.char_save_layout.addStretch() self.char_save_layout.addLayout(self.char_index_layout) self.char_save_layout.addWidget(self.char_index_save) self.char_save_layout.addWidget(self.char_show) help_label = QLabel('Use "\\0, \\1, ..., \\7" in text field to show custom characters.') help_label.setWordWrap(True) self.char_save_layout.addWidget(help_label) self.char_save_layout.addStretch() grid_stretch_layout = QHBoxLayout() grid_stretch_layout.addWidget(QLabel('Custom Character:')) grid_stretch_layout.addWidget(self.scribble_widget) grid_stretch_layout.addLayout(self.char_save_layout) grid_stretch_layout.addStretch() self.char_main_layout = QHBoxLayout() self.char_main_layout.addStretch() self.char_main_layout.addLayout(grid_stretch_layout) self.char_main_layout.addStretch() layout = QVBoxLayout(self) layout.addLayout(self.line_pos_layout) layout.addLayout(self.text_layout) layout.addWidget(self.clear_button) layout.addLayout(self.onofflayout) layout.addLayout(self.buttonlayout) if self.hardware_version <= (1, 1, 0): self.b3_label.hide() if self.has_custom_character: layout.addWidget(line) layout.addLayout(self.char_main_layout) layout.addStretch(1) def is_backlight_on_async(self, on): if on: self.bl_button.setText('Backlight Off') else: self.bl_button.setText('Backlight On') def get_config_async(self, config): cursor, blink = config if cursor: self.cursor_button.setText('Cursor Off') else: self.cursor_button.setText('Cursor On') if blink: self.blink_button.setText('Blink Off') else: self.blink_button.setText('Blink On') def start(self): async_call(self.lcd.is_backlight_on, None, self.is_backlight_on_async, self.increase_error_count) async_call(self.lcd.get_config, None, self.get_config_async, self.increase_error_count) def stop(self): pass def destroy(self): pass def get_url_part(self): # override normal get_url_part() function, because the URL part here # depends on the hardware version return 'lcd_20x4_v{0}{1}'.format(self.hardware_version[0], self.hardware_version[1]) def is_hardware_version_relevant(self): return True @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletLCD20x4.DEVICE_IDENTIFIER def cb_pressed(self, button): if button == 0: self.b0_label.setText('Button 0: Pressed,') elif button == 1: self.b1_label.setText('Button 1: Pressed,') elif button == 2: self.b2_label.setText('Button 2: Pressed,') elif button == 3: self.b3_label.setText('Button 3: Pressed') def cb_released(self, button): if button == 0: self.b0_label.setText('Button 0: Released,') elif button == 1: self.b1_label.setText('Button 1: Released,') elif button == 2: self.b2_label.setText('Button 2: Released,') elif button == 3: self.b3_label.setText('Button 3: Released') def bl_clicked(self): if self.bl_button.text().replace('&', '') == 'Backlight On': async_call(self.lcd.backlight_on, None, None, self.increase_error_count) self.bl_button.setText('Backlight Off') else: async_call(self.lcd.backlight_off, None, None, self.increase_error_count) self.bl_button.setText('Backlight On') def get_config(self): cursor = self.cursor_button.text().replace('&', '') == 'Cursor Off' blink = self.blink_button.text().replace('&', '') == 'Blink Off' return (cursor, blink) def cursor_clicked(self): cursor, blink = self.get_config() async_call(self.lcd.set_config, (not cursor, blink), None, self.increase_error_count) if cursor: self.cursor_button.setText('Cursor On') else: self.cursor_button.setText('Cursor Off') def blink_clicked(self): cursor, blink = self.get_config() async_call(self.lcd.set_config, (cursor, not blink), None, self.increase_error_count) if blink: self.blink_button.setText('Blink On') else: self.blink_button.setText('Blink Off') def clear_clicked(self): async_call(self.lcd.clear_display, None, None, self.increase_error_count) def text_clicked(self): line = int(self.line_combo.currentText()) position = int(self.pos_combo.currentText()) text = self.text_edit.text() if self.has_custom_character: for i in range(8): text = text.replace('\\' + str(i), chr(i + 8)) async_call(self.lcd.write_line, (line, position, unicode_to_ks0066u(text)), None, self.increase_error_count) def char_index_save_clicked(self): char = [0]*8 img = self.scribble_widget.image() for j in range(img.height()): for i in range(img.width() - 1, -1, -1): if img.pixel(i, j) == self.scribble_widget.foreground_color().rgb(): char[j] |= 1 << (4 - i) index = int(self.char_index_combo.currentText()) async_call(self.lcd.set_custom_character, (index, char), None, self.increase_error_count) def show_clicked(self): async_call(self.lcd.clear_display, None, None, self.increase_error_count) line1 = '0:{0} 1:{1} 2:{2} 3:{3}'.format(chr(8), chr(9), chr(10), chr(11)) line2 = '4:{0} 5:{1} 6:{2} 7:{3}'.format(chr(12), chr(13), chr(14), chr(15)) async_call(self.lcd.write_line, (0, 0, line1), None, self.increase_error_count) async_call(self.lcd.write_line, (1, 0, line2), None, self.increase_error_count) def custom_character_async(self, characters): r = [] g = [] b = [] for j in range(self.scribble_widget.image().height()): for i in range(self.scribble_widget.image().width() - 1, -1, -1): if characters[j] & (1 << i): r.append(255) g.append(255) b.append(255) else: r.append(0) g.append(0) b.append(255) self.scribble_widget.array_draw(r, g, b) def char_index_changed(self, index): async_call(self.lcd.get_custom_character, index, self.custom_character_async, self.increase_error_count)
def create_filters(self, parent, code, lang=False, area=False, sal=True): if sal: label_sal = QLabel(parent) label_sal.setText('Зарплата от') label_sal.resize(100, 15) label_sal.move(5, 125) label_sal_val = QLabel(parent) label_sal_val.move(FRAME_WIDTH - 50, 125) label_sal_val.resize(45, 15) label_sal_val.setAlignment(Qt.AlignRight) label_sal_val.setText(str(self.start_sal)) sld_sal = QSlider(Qt.Horizontal, parent) sld_sal.setMinimum(int(self.start_sal / 5000)) sld_sal.setMaximum(40) sld_sal.setPageStep(1) sld_sal.move(5, 145) sld_sal.resize(FRAME_WIDTH - 10, 20) sld_sal.valueChanged[int].connect( lambda val, tab=code: self.sld_action(val, tab)) else: label_sal_val = None sld_sal = None if lang: combo_lang = QComboBox(parent) combo_lang.setMaxVisibleItems(20) combo_lang.addItem("Все языки") combo_lang.resize(FRAME_WIDTH - 10, 20) combo_lang.move(5, 10) combo_lang.addItems(LANGUAGES) combo_lang.activated.connect( lambda val, tab=code: self.refresh_plot(tab)) else: combo_lang = None if area: combo_area = QComboBox(parent) combo_area.setMaxVisibleItems(20) combo_area.addItem("Все города") combo_area.resize(FRAME_WIDTH - 10, 20) combo_area.move(5, 10) combo_area.addItems( [work_with_data.decode_param(val) for val in AREA]) combo_area.activated.connect( lambda val, tab=code: self.refresh_plot(tab)) else: combo_area = None combo_sizecomp = QComboBox(parent) combo_sizecomp.setMaxVisibleItems(5) combo_sizecomp.addItem("Все компании") combo_sizecomp.resize(FRAME_WIDTH - 10, 20) combo_sizecomp.move(5, 40) combo_sizecomp.addItems([ work_with_data.decode_param(size_comp) for size_comp in SIZE_COMPANY ]) combo_sizecomp.activated.connect( lambda val, tab=code: self.refresh_plot(tab)) combo_exp = QComboBox(parent) combo_exp.setMaxVisibleItems(10) combo_exp.addItem("Любой опыт") combo_exp.resize(FRAME_WIDTH - 10, 20) combo_exp.move(5, 70) combo_exp.addItems([ work_with_data.decode_param(experience) for experience in EXPERIENCE ]) combo_exp.activated.connect( lambda val, tab=code: self.refresh_plot(tab)) combo_empl = QComboBox(parent) combo_empl.setMaxVisibleItems(10) combo_empl.addItem("Любой график") combo_empl.resize(FRAME_WIDTH - 10, 20) combo_empl.move(5, 100) combo_empl.addItems([ work_with_data.decode_param(employment) for employment in EMPLOYMENT ]) combo_empl.activated.connect( lambda val, tab=code: self.refresh_plot(tab)) items = { 'Lang': combo_lang, 'Area': combo_area, 'MinSal': sld_sal, 'SizeComp': combo_sizecomp, 'Employment': combo_empl, 'Experience': combo_exp, 'lbl_min': label_sal_val } return items
class WidgetGallery(QDialog): def __init__(self, parent=None): super(WidgetGallery, self).__init__(parent) self.AREA_LIST = [1261, 1, 1308, 1051, 1530] self.URL = r'https://api.hh.ru/vacancies/' self.messages = Message.MessageWindow() self.request_vacancy = Request.RequestVacancy(self.URL) self.save_vacancy = Save.SaveVacancy() self.clear_vacancy = Clear.ClearVacancy() self.create_top_left_group_box() self.create_top_right_group_box() self.create_bottom_left_tab_widget() self.create_bottom_right_group_box() main_layout = QGridLayout() main_layout.addWidget(self.top_left_group_box, 2, 0) main_layout.addWidget(self.top_right_group_box, 3, 0) main_layout.addWidget(self.bottom_left_tab_widget, 1, 1, 3, 3) main_layout.addWidget(self.bottom_right_group_box, 1, 0) main_layout.setRowStretch(1, 1) main_layout.setRowStretch(2, 1) main_layout.setColumnStretch(0, 1) main_layout.setColumnStretch(1, 1) self.setLayout(main_layout) self.setWindowTitle("HH API") self.setMinimumSize(800, 600) self.setWindowIcon(QIcon(r'Images\Иконка.png')) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowMaximizeButtonHint) def create_top_left_group_box(self): self.top_left_group_box = QGroupBox("Сохранение") name_str = QLabel() name_str.setText("Имя файла:") self.save_name_input = QLineEdit() self.save_name_input.setPlaceholderText("Имя") name_str_form = QLabel() name_str_form.setText("Формат:") self.format_branch_input = QComboBox() self.format_branch_input.addItem("CSV") self.format_branch_input.addItem("JSON") self.format_branch_input.addItem("XLSX") button_save = QPushButton("Сохранить") button_save.clicked.connect(self.add_save) layout = QVBoxLayout() layout.addWidget(name_str) layout.addWidget(self.save_name_input) layout.addWidget(name_str_form) layout.addWidget(self.format_branch_input) layout.addWidget(button_save) layout.addStretch(1) self.top_left_group_box.setLayout(layout) def create_top_right_group_box(self): self.top_right_group_box = QGroupBox() default_push_button = QPushButton("Помощь") default_push_button.clicked.connect(self.about) layout = QVBoxLayout() layout.addWidget(default_push_button) layout.addStretch(1) self.top_right_group_box.setLayout(layout) def create_bottom_left_tab_widget(self): self.connect_ = sqlite3.connect(r'Result.db') self.cursor = self.connect_.cursor() self.cursor.execute( "CREATE TABLE IF NOT EXISTS Result(id TEXT, name TEXT,area TEXT,employer TEXT,keySkills TEXT)" ) self.cursor.close() self.bottom_left_tab_widget = QGroupBox() self.bottom_left_tab_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored) self.table_widget = QTableWidget() self.table_widget.setAlternatingRowColors(True) self.table_widget.setColumnCount(5) self.table_widget.horizontalHeader().setCascadingSectionResizes(True) self.table_widget.horizontalHeader().setSortIndicatorShown(False) self.table_widget.horizontalHeader().setStretchLastSection(True) self.table_widget.verticalHeader().Stretch self.table_widget.verticalHeader().ResizeToContents self.table_widget.verticalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.table_widget.verticalHeader().setVisible(True) self.table_widget.verticalHeader().setCascadingSectionResizes(True) self.table_widget.verticalHeader().setStretchLastSection(False) self.table_widget.setHorizontalHeaderLabels( ("ID", "Название", "Город", "Компания", "Ключевые навыки")) self.load_data() table_h_box = QHBoxLayout() table_h_box.addWidget(self.table_widget) self.bottom_left_tab_widget.setLayout(table_h_box) def create_bottom_right_group_box(self): self.bottom_right_group_box = QGroupBox("Добавить вакансии") self.vacancy_name_input = QLineEdit() self.vacancy_name_input.setPlaceholderText("Название") self.region_branch_input = QComboBox() self.region_branch_input.addItem("Свердловкая область") self.region_branch_input.addItem("Москва") self.region_branch_input.addItem("Ростовская область") self.region_branch_input.addItem("Курская область") self.region_branch_input.addItem("Новгородская область") button_add_work = QPushButton("Добавить") button_add_work.clicked.connect(self.add_work) push_button = QPushButton("Удалить все") push_button.clicked.connect(self.delete_all_works) layout = QGridLayout() layout.addWidget(self.vacancy_name_input, 0, 0, 1, 2) layout.addWidget(self.region_branch_input, 1, 0, 1, 2) layout.addWidget(button_add_work, 2, 0, 1, 2) layout.addWidget(push_button, 3, 0, 1, 2) layout.setRowStretch(5, 1) self.bottom_right_group_box.setLayout(layout) def delete_all_works(self): if self.clear_vacancy.clear(): self.load_data() def add_work(self): self.request_vacancy.request( self.vacancy_name_input.text(), self.AREA_LIST[self.region_branch_input.currentIndex()]) self.load_data() def add_save(self): _name = self.save_name_input.text() _branch = self.format_branch_input.itemText( self.format_branch_input.currentIndex()) self.save_vacancy.save( self.save_name_input.text(), self.format_branch_input.itemText( self.format_branch_input.currentIndex())) def about(self): dialog = Help.AboutDialog() dialog.exec() def load_data(self): self.connect_ = sqlite3.connect(r'Result.db') _result = self.connect_.execute("SELECT * FROM Result") self.table_widget.setRowCount(0) for row_number, row_data in enumerate(_result): self.table_widget.insertRow(row_number) for column_number, data in enumerate(row_data): self.table_widget.setItem(row_number, column_number, QTableWidgetItem(str(data))) self.connect_.close()
class MainWindow(QWidget): __exit = False futures = None def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.title = "CryptoAlerts" self.left = 50 self.top = 50 self.width = 600 self.height = 400 self.ticker = "btcusdt" self.dlg = PriceAlertDialog() self.dlg.setWindowModality(Qt.WindowModality.WindowModal) self.InitUI() self.create_config() self.check_alerts = threading.Thread(target=self.check_prices) if self.futures: self.check_alerts.start() def create_config(self): """ Create new folder and config.json file in local appdata directory to store the api keys """ config_dir = os.path.join(os.getenv("LOCALAPPDATA"), "CryptoAlerts") if not os.path.exists(config_dir) or not os.path.exists( os.path.join(config_dir, "config.json")): try: os.mkdir(config_dir) except: print(f"Couldn't create a directory in {config_dir}") input_d = APIInputDialog(config_dir) acc = input_d.exec() if acc == QDialog.Accepted: self.futures = Futures(True) else: self.futures = Futures(True) def InitUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.ticker_textbox = QLineEdit() self.ticker_textbox.returnPressed.connect(self.change_ticker) # Alert textbox self.alert_pricebox = QLineEdit() # Alert button alert_b = QPushButton("Set Alert") alert_b.clicked.connect(self.add_to_list) # Remove alert alert_rem_b = QPushButton("Remove Alert") alert_rem_b.clicked.connect(self.remove_from_list) # Alert dropdown self.alert_dropdown = QComboBox() self.alert_dropdown.addItem("Below") self.alert_dropdown.addItem("Above") # Alert layout alert_layout = QBoxLayout(QBoxLayout.Direction.LeftToRight) alert_layout.addWidget(self.alert_dropdown) alert_layout.addWidget(self.alert_pricebox) alert_layout.addWidget(alert_b) alert_layout.addWidget(alert_rem_b) self.ticker_price = QLabel("") self.ticker_l = QLabel(self.ticker.upper()) # List of alerts self.alert_list = QTableWidget() self.alert_list.setColumnCount(4) self.alert_list.setHorizontalHeaderLabels( ["Ticker", "Alert Price", "Type", "Triggered"]) # Main layout tickerlayout = QFormLayout() tickerlayout.addRow("Ticker", self.ticker_textbox) tickerlayout.addRow(self.ticker_l, self.ticker_price) tickerlayout.addRow("Alert when price is", alert_layout) tickerlayout.addRow(self.alert_list) grid = QGridLayout() self.setLayout(tickerlayout) def remove_from_list(self): """Removes a symbol from the list (which disables the alert) """ for row in self.alert_list.selectedItems(): self.alert_list.removeRow(row.row()) def check_prices(self): """Constantly goes through a list of symbols and checks if price has reached a given number (runs in a thread) """ while True: if self.__exit: break self.set_ticker_price() for row in range(self.alert_list.rowCount()): if self.alert_list.item(row, 3).text() == "False": symbol = self.alert_list.item(row, 0).text().lower() alert_price = self.alert_list.item(row, 1).text() alert_type = self.alert_list.item(row, 2).text() price = self.futures.get_price(symbol) if alert_type == "Below" and price < float(alert_price): self.alert_list.item(row, 3).setText("True") self.dlg.set_ticker(symbol, alert_price, alert_type) self.dlg.play_sound() self.dlg.exec() elif alert_type == "Above" and price > float(alert_price): self.alert_list.item(row, 3).setText("True") self.dlg.set_ticker(symbol, alert_price, alert_type) self.dlg.play_sound() self.dlg.exec() time.sleep(0.5) def add_to_list(self): """Adds an item to the list """ self.alert_list.insertRow(self.alert_list.rowCount()) tck = QTableWidgetItem() tck.setText(self.ticker.upper()) price = QTableWidgetItem() price.setText(self.alert_pricebox.text()) typ = QTableWidgetItem() alert_type = self.alert_dropdown.itemText( self.alert_dropdown.currentIndex()) typ.setText(alert_type) triggered = QTableWidgetItem() triggered.setText("False") self.alert_list.setItem(self.alert_list.rowCount() - 1, 0, tck) self.alert_list.setItem(self.alert_list.rowCount() - 1, 1, price) self.alert_list.setItem(self.alert_list.rowCount() - 1, 2, typ) self.alert_list.setItem(self.alert_list.rowCount() - 1, 3, triggered) def change_ticker(self): self.ticker = self.ticker_textbox.text() self.ticker_l.setText(self.ticker.upper()) def set_ticker_price(self): self.ticker_price.setText(str(self.futures.get_price(self.ticker))) def closeEvent(self, event): # Breaks the while loop to end the thread self.__exit = True
def __init__(self, layer): super().__init__() self.layer = layer self.unselectedStyleSheet = "QFrame#layer {border: 3px solid lightGray; background-color:lightGray; border-radius: 3px;}" self.selectedStyleSheet = "QFrame#layer {border: 3px solid rgb(0, 153, 255); background-color:lightGray; border-radius: 3px;}" self.setObjectName('layer') self.grid_layout = QGridLayout() cb = QCheckBox(self) cb.setStyleSheet("QCheckBox::indicator {width: 18px; height: 18px;}" "QCheckBox::indicator:checked {image: url(" + path_on + ");}") cb.setToolTip('Layer visibility') cb.setChecked(self.layer.visible) cb.stateChanged.connect(lambda state=cb: self.changeVisible(state)) self.grid_layout.addWidget(cb, 0, 0) #self.grid_layout.insertSpacing(1, 5) textbox = QLineEdit(self) textbox.setStyleSheet('background-color:lightGray; border:none') textbox.setText(layer.name) textbox.setToolTip('Layer name') textbox.setFixedWidth(80) textbox.setAcceptDrops(False) textbox.editingFinished.connect( lambda text=textbox: self.changeText(text)) self.grid_layout.addWidget(textbox, 0, 1) self.grid_layout.addWidget(QLabel('opacity:'), 1, 0) sld = QSlider(Qt.Horizontal, self) sld.setFocusPolicy(Qt.NoFocus) #sld.setInvertedAppearance(True) sld.setFixedWidth(75) sld.setMinimum(0) sld.setMaximum(100) sld.setSingleStep(1) sld.setValue(self.layer.opacity * 100) sld.valueChanged[int].connect( lambda value=sld: self.changeOpacity(value)) self.grid_layout.addWidget(sld, 1, 1) blend_comboBox = QComboBox() for blend in self.layer._blending_modes: blend_comboBox.addItem(blend) index = blend_comboBox.findText(self.layer._blending, Qt.MatchFixedString) if index >= 0: blend_comboBox.setCurrentIndex(index) blend_comboBox.activated[str].connect( lambda text=blend_comboBox: self.changeBlending(text)) self.grid_layout.addWidget(QLabel('blending:'), 2, 0) self.grid_layout.addWidget(blend_comboBox, 2, 1) self.setLayout(self.grid_layout) self.setToolTip( 'Click to select\nDrag to rearrange\nDouble click to expand') self.setSelected(True) self.setExpanded(False) self.setFixedWidth(200) self.grid_layout.setColumnMinimumWidth(0, 100) self.grid_layout.setColumnMinimumWidth(1, 100)
class FileManager(QWidget, _HalWidgetBase): def __init__(self, parent=None): super(FileManager, self).__init__(parent) self.title = 'Qtvcp File System View' self.left = 10 self.top = 10 self.width = 640 self.height = 480 self._last = 0 if INFO.PROGRAM_PREFIX is not None: self.user_path = os.path.expanduser(INFO.PROGRAM_PREFIX) else: self.user_path = (os.path.join(os.path.expanduser('~'), 'linuxcnc/nc_files')) user = os.path.split(os.path.expanduser('~'))[-1] self.media_path = (os.path.join('/media', user)) temp = [('User', self.user_path), ('Media', self.media_path)] self._jumpList = OrderedDict(temp) self.currentPath = None self.currentFolder = None self.PREFS_ = None self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) pasteBox = QHBoxLayout() self.textLine = QLineEdit() self.textLine.setToolTip('Current Director/selected File') self.pasteButton = QToolButton() self.pasteButton.setEnabled(False) self.pasteButton.setText('Paste') self.pasteButton.setToolTip( 'Copy file from copy path to current directory/file') self.pasteButton.clicked.connect(self.paste) self.pasteButton.hide() pasteBox.addWidget(self.textLine) pasteBox.addWidget(self.pasteButton) self.copyBox = QFrame() hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) self.copyLine = QLineEdit() self.copyLine.setToolTip('File path to copy from, when pasting') self.copyButton = QToolButton() self.copyButton.setText('Copy') self.copyButton.setToolTip('Record current file as copy path') self.copyButton.clicked.connect(self.recordCopyPath) hbox.addWidget(self.copyButton) hbox.addWidget(self.copyLine) self.copyBox.setLayout(hbox) self.copyBox.hide() self.model = QFileSystemModel() self.model.setRootPath(QDir.currentPath()) self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files) self.model.setNameFilterDisables(False) self.model.rootPathChanged.connect(self.folderChanged) self.list = QListView() self.list.setModel(self.model) self.list.resize(640, 480) self.list.clicked[QModelIndex].connect(self.listClicked) self.list.activated.connect(self._getPathActivated) self.list.setAlternatingRowColors(True) self.list.hide() self.table = QTableView() self.table.setModel(self.model) self.table.resize(640, 480) self.table.clicked[QModelIndex].connect(self.listClicked) self.table.activated.connect(self._getPathActivated) self.table.setAlternatingRowColors(True) header = self.table.horizontalHeader() header.setSectionResizeMode(0, QHeaderView.Stretch) header.setSectionResizeMode(1, QHeaderView.ResizeToContents) header.setSectionResizeMode(3, QHeaderView.ResizeToContents) header.swapSections(1, 3) header.setSortIndicator(1, Qt.AscendingOrder) self.table.setSortingEnabled(True) self.table.setColumnHidden(2, True) # type self.table.verticalHeader().setVisible(False) # row count header self.cb = QComboBox() self.cb.currentIndexChanged.connect(self.filterChanged) self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS) self.cb.setMinimumSize(200, 30) self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button2 = QToolButton() self.button2.setText('User') self.button2.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button2.setMinimumSize(60, 30) self.button2.setToolTip( 'Jump to User directory.\nLong press for Options.') self.button2.clicked.connect(self.onJumpClicked) self.button3 = QToolButton() self.button3.setText('Add Jump') self.button3.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.button3.setMinimumSize(60, 30) self.button3.setToolTip('Add current directory to jump button list') self.button3.clicked.connect(self.onActionClicked) self.settingMenu = QMenu(self) self.button2.setMenu(self.settingMenu) hbox = QHBoxLayout() hbox.addWidget(self.button2) hbox.addWidget(self.button3) hbox.insertStretch(2, stretch=0) hbox.addWidget(self.cb) windowLayout = QVBoxLayout() windowLayout.addLayout(pasteBox) windowLayout.addWidget(self.copyBox) windowLayout.addWidget(self.list) windowLayout.addWidget(self.table) windowLayout.addLayout(hbox) self.setLayout(windowLayout) self.show() def _hal_init(self): if self.PREFS_: last_path = self.PREFS_.getpref('last_loaded_directory', self.user_path, str, 'BOOK_KEEPING') LOG.debug("lAST FILE PATH: {}".format(last_path)) if not last_path == '' and os.path.exists(last_path): self.updateDirectoryView(last_path) else: self.updateDirectoryView(self.user_path) # get all the saved jumplist paths temp = self.PREFS_.getall('FILEMANAGER_JUMPLIST') self._jumpList.update(temp) else: LOG.debug("lAST FILE PATH: {}".format(self.user_path)) self.updateDirectoryView(self.user_path) # install jump paths into toolbutton menu for i in self._jumpList: self.addAction(i) # set recorded columns sort settings self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName())) sect = self.SETTINGS_.value('sortIndicatorSection', type=int) order = self.SETTINGS_.value('sortIndicatorOrder', type=int) self.SETTINGS_.endGroup() if not None in (sect, order): self.table.horizontalHeader().setSortIndicator(sect, order) # when qtvcp closes this gets called # record jump list paths def _hal_cleanup(self): if self.PREFS_: for i, key in enumerate(self._jumpList): if i in (0, 1): continue self.PREFS_.putpref(key, self._jumpList.get(key), str, 'FILEMANAGER_JUMPLIST') # record sorted columns h = self.table.horizontalHeader() self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName())) self.SETTINGS_.setValue('sortIndicatorSection', h.sortIndicatorSection()) self.SETTINGS_.setValue('sortIndicatorOrder', h.sortIndicatorOrder()) self.SETTINGS_.endGroup() ######################### # callbacks ######################### # add shown text and hidden filter data from the INI def fillCombobox(self, data): for i in data: self.cb.addItem(i[0], i[1]) def folderChanged(self, data): data = os.path.normpath(data) self.currentFolder = data self.textLine.setText(data) def updateDirectoryView(self, path, quiet=False): if os.path.exists(path): self.list.setRootIndex(self.model.setRootPath(path)) self.table.setRootIndex(self.model.setRootPath(path)) else: LOG.debug( "Set directory view error - no such path {}".format(path)) if not quiet: STATUS.emit( 'error', LOW_ERROR, "File Manager error - No such path: {}".format(path)) # retrieve selected filter (it's held as QT.userData) def filterChanged(self, index): userdata = self.cb.itemData(index) self.model.setNameFilters(userdata) def listClicked(self, index): # the signal passes the index of the clicked item dir_path = os.path.normpath(self.model.filePath(index)) if self.model.fileInfo(index).isFile(): self.currentPath = dir_path self.textLine.setText(self.currentPath) return root_index = self.model.setRootPath(dir_path) self.list.setRootIndex(root_index) self.table.setRootIndex(root_index) def onUserClicked(self): self.showUserDir() def onMediaClicked(self): self.showMediaDir() # jump directly to a saved path shown on the button def onJumpClicked(self): data = self.button2.text() if data.upper() == 'MEDIA': self.showMediaDir() elif data.upper() == 'USER': self.showUserDir() else: temp = self._jumpList.get(data) if temp is not None: self.updateDirectoryView(temp) else: STATUS.emit('error', linuxcnc.OPERATOR_ERROR, 'file jumopath: {} not valid'.format(data)) log.debug('file jumopath: {} not valid'.format(data)) # jump directly to a saved path from the menu def jumpTriggered(self, data): if data.upper() == 'MEDIA': self.button2.setText('{}'.format(data)) self.button2.setToolTip( 'Jump to Media directory.\nLong press for Options.') self.showMediaDir() elif data.upper() == 'USER': self.button2.setText('{}'.format(data)) self.button2.setToolTip( 'Jump to User directory.\nLong press for Options.') self.showUserDir() else: self.button2.setText('{}'.format(data)) self.button2.setToolTip('Jump to directory:\n{}'.format( self._jumpList.get(data))) self.updateDirectoryView(self._jumpList.get(data)) # add a jump list path def onActionClicked(self): i = self.currentFolder try: self._jumpList[i] = i except Exception as e: print(e) button = QAction(QIcon.fromTheme('user-home'), i, self) # weird lambda i=i to work around 'function closure' button.triggered.connect(lambda state, i=i: self.jumpTriggered(i)) self.settingMenu.addAction(button) # get current selection and update the path # then if the path is good load it into linuxcnc # record it in the preference file if available def _getPathActivated(self): if self.list.isVisible(): row = self.list.selectionModel().currentIndex() else: row = self.table.selectionModel().currentIndex() self.listClicked(row) fname = self.currentPath if fname is None: return if fname: self.load(fname) def recordCopyPath(self): data, isFile = self.getCurrentSelected() if isFile: self.copyLine.setText(os.path.normpath(data)) self.pasteButton.setEnabled(True) else: self.copyLine.setText('') self.pasteButton.setEnabled(False) STATUS.emit('error', OPERATOR_ERROR, 'Can only copy a file, not a folder') def paste(self): res = self.copyFile(self.copyLine.text(), self.textLine.text()) if res: self.copyLine.setText('') self.pasteButton.setEnabled(False) ######################## # helper functions ######################## def addAction(self, i): axisButton = QAction(QIcon.fromTheme('user-home'), i, self) # weird lambda i=i to work around 'function closure' axisButton.triggered.connect(lambda state, i=i: self.jumpTriggered(i)) self.settingMenu.addAction(axisButton) def showList(self, state=True): if state: self.table.hide() self.list.show() else: self.table.show() self.list.hide() def showTable(self, state=True): self.showList(not state) def showCopyControls(self, state): if state: self.copyBox.show() self.pasteButton.show() else: self.copyBox.hide() self.pasteButton.hide() def showMediaDir(self, quiet=False): self.updateDirectoryView(self.media_path, quiet) def showUserDir(self, quiet=False): self.updateDirectoryView(self.user_path, quiet) def copyFile(self, s, d): try: shutil.copy(s, d) return True except Exception as e: LOG.error("Copy file error: {}".format(e)) STATUS.emit('error', OPERATOR_ERROR, "Copy file error: {}".format(e)) return False @pyqtSlot(float) @pyqtSlot(int) def scroll(self, data): if data > self._last: self.up() elif data < self._last: self.down() self._last = data # moves the selection up # used with MPG scrolling def up(self): self.select_row('up') # moves the selection down # used with MPG scrolling def down(self): self.select_row('down') def select_row(self, style='down'): style = style.lower() if self.list.isVisible(): i = self.list.rootIndex() selectionModel = self.list.selectionModel() else: i = self.table.rootIndex() selectionModel = self.table.selectionModel() row = selectionModel.currentIndex().row() self.rows = self.model.rowCount(i) if style == 'last': row = self.rows elif style == 'up': if row > 0: row -= 1 else: row = 0 elif style == 'down': if row < self.rows - 1: row += 1 else: row = self.rows - 1 else: return top = self.model.index(row, 0, i) selectionModel.setCurrentIndex( top, QItemSelectionModel.Select | QItemSelectionModel.Rows) selection = QItemSelection(top, top) selectionModel.clearSelection() selectionModel.select(selection, QItemSelectionModel.Select) # returns the current highlighted (selected) path as well as # whether it's a file or not. def getCurrentSelected(self): if self.list.isVisible(): selectionModel = self.list.selectionModel() else: selectionModel = self.table.selectionModel() index = selectionModel.currentIndex() dir_path = os.path.normpath(self.model.filePath(index)) if self.model.fileInfo(index).isFile(): return (dir_path, True) else: return (dir_path, False) # This can be class patched to do something else def load(self, fname=None): try: if fname is None: self._getPathActivated() return self.recordBookKeeping() ACTION.OPEN_PROGRAM(fname) STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME') except Exception as e: LOG.error("Load file error: {}".format(e)) STATUS.emit('error', NML_ERROR, "Load file error: {}".format(e)) # This can be class patched to do something else def recordBookKeeping(self): fname = self.currentPath if fname is None: return if self.PREFS_: self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(), str, 'BOOK_KEEPING') self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')
class TeqCustomQueryWidget(QWidget): def __init__(self): super(QWidget, self).__init__() self._setup_widget() def _setup_widget(self): self.query = QTextEdit(self) self.submit1 = QPushButton("Execute Query") self.submit1.clicked.connect(self.run_query) self.export1 = QPushButton("Export Data") self.export1.clicked.connect(self.export_data) self._setup_export_combobox() self.table1 = QTableWidget() # set layouts self.layout = QGridLayout(self) self.layout.setColumnStretch(0, 3) # add "Query" label self.layout.addWidget(QLabel("Query:"), 0, 0) # add query textbox self.layout.addWidget(self.query, 1, 0) # add "Execute Query" button self.layout.addWidget(self.submit1, 1, 1) # add "Output" label self.layout.addWidget(QLabel("Query Output:"), 2, 0) # add file option combobox self.layout.addWidget(self.export_combobox, 2, 1) # add query output result table self.layout.addWidget(self.table1, 3, 0) self.layout.addWidget(self.export1, 3, 1) self.setLayout(self.layout) def _setup_export_combobox(self): self.export_options = { "csv": exportCSV.ExportCSV(), "pdf": exportPDF.ExportPDF() } self.export_combobox = QComboBox() for key in self.export_options: self.export_combobox.addItem(key) @pyqtSlot() def run_query(self): query = self.query.toPlainText() if (len(query) == 0): gui_helper.prompt_error("Please enter a query") return try: dict_values = database.execute_query_result(query) if (dict_values): self.populateTable(dict_values) gui_helper.prompt_information("query executed successfully") except Exception as e: gui_helper.prompt_error("Failed to run Query: " + repr(e)) def populateTable(self, column_values): self.table1.clearContents() self.table1.setColumnCount(len(column_values)) for key in column_values: self.table1.setRowCount(len(column_values[key])) break for i, key in enumerate(column_values): self.table1.setHorizontalHeaderItem(i, QTableWidgetItem(key)) col_vals = column_values[key] for j, val in enumerate(col_vals): self.table1.setItem(j, i, QTableWidgetItem(str(val))) @pyqtSlot() def export_data(self): query_text = self.query.toPlainText() if (len(query_text) == 0): gui_helper.prompt_error("Please enter a query") return export_option = self.export_options[self.export_combobox.currentText()] file_path = gui_helper.prompt_file_save() if (not file_path): return try: export_option.export(file_path, query_text) gui_helper.prompt_information("Data has been succesfully exported!") except Exception as e: gui_helper.prompt_error("Failed to export data: " + repr(e)) @pyqtSlot() def add_graph(self): graph_type = self.export_combobox.currentText() query_text = self.query.toPlainText() if (len(query_text) == 0): gui_helper.prompt_error("Please enter a query") return row_count = self.report_table.rowCount() self.report_table.insertRow(row_count) self.report_table.setItem(row_count, 0, QTableWidgetItem(graph_type)) self.report_table.setItem(row_count, 1, QTableWidgetItem(query_text))
class App(QMainWindow): def __init__(self): super().__init__() # QMainWindow.__init__(self) # self.setAttribute(QtCore.Qt.WA_DeleteOnClose) # self.left = 100 # self.top = 100 self.title = 'PyQt5 matplotlib example - pythonspot.com' # self.width = 800 # self.height = 600 self.initUI() def initUI(self): global df, df1, df2 #import data # def parse_dates(x): # return datetime.strptime(x, "%Y.%m.%d") dateparse = lambda x: datetime.strptime(x, '%Y.%m.%d') df = pd.read_csv('LianJia.csv', encoding='ANSI', index_col=0, parse_dates=['成交日期'], date_parser=dateparse) #注意编码格式和索引 df.set_index('成交日期', inplace=True) #利用 '时间' 为index # Select_XiaoQu = App.getcombo1Information #self.combo1.currentText() # print(Select_XiaoQu) # if Select_XiaoQu == None: # Select_XiaoQu='瀚盛家园' Select_XiaoQu = '瀚盛家园' df1 = df[df['小区'] == Select_XiaoQu] df2 = df[df['板块'] == '唐镇'].groupby(['小区']).count() # df2.groupby(['小区']).count().index # df2.groupby(['小区']).count()['单价'] self.setWindowTitle(self.title) # self.setGeometry(self.left, self.top, self.width, self.height) self.file_menu = QMenu('&File', self) self.file_menu.addAction('&Quit', self.fileQuit, QtCore.Qt.CTRL + QtCore.Qt.Key_Q) self.menuBar().addMenu(self.file_menu) self.help_menu = QMenu('&Help', self) self.menuBar().addSeparator() self.menuBar().addMenu(self.help_menu) self.help_menu.addAction('&About', self.about) self.main_widget = QWidget(self) l = QVBoxLayout(self.main_widget) self.m = PlotCanvas(self.main_widget, width=8, height=4, dpi=100) self.n = PlotCount(self.main_widget, width=8, height=4, dpi=100) #m.move(0,0) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) self.combo = QComboBox(self) self.combo1 = QComboBox(self) l.addWidget(self.combo) l.addWidget(self.combo1) l.addWidget(self.m) l.addWidget(self.n) self.combo1.addItem('瀚盛家园') #self.combo.move(500, 30) for ListItem in df['板块'].unique(): self.combo.addItem(ListItem) self.combo.currentTextChanged.connect(self.comboChanged) self.combo.activated.connect(self.BanKuaiChanged) self.combo1.activated.connect(self.XiaoQuChanged) #self.combo.activated.connect(self.comboChanged) #self.roomBox.activated.connect(self.m.plot) #self.combo1.move(600, 30) #self.combo1.activated.connect(m.plot()) #button = QPushButton('PyQt5 button', self) #button.setToolTip('This s an example button') #button.move(500,0) #button.resize(140,100) #combo.activated[str].connect(self.onActivated) #self.show() def comboChanged(self, text): #self.mediaBox.setEnabled(True) global df, df1 Select_XiaoQu = self.combo.currentText() #print(Select_XiaoQu) self.combo1.clear() df1 = df[df['板块'] == Select_XiaoQu] #print(df1['小区'].unique()) for ListItem in df1['小区'].unique(): self.combo1.addItem(ListItem) def XiaoQuChanged(self, text): global df, df1 #self.mediaBox.setEnabled(True) Select_XiaoQu = self.combo1.currentText() df1 = df[df['小区'] == Select_XiaoQu] self.m.update_figure() def BanKuaiChanged(self, text): global df, df2 #self.mediaBox.setEnabled(True) Select_XiaoQu = self.combo.currentText() df2 = df[df['板块'] == Select_XiaoQu].groupby(['小区']).count() self.n.update_figure() def getcombo1Information(self): textMedia = self.combo1.currentText() #print(textMedia) return textMedia def fileQuit(self): self.close() def closeEvent(self, ce): self.fileQuit() def about(self): QMessageBox.about( self, "About", """embedding_in_qt5.py example Copyright 2005 Fand qt5""")
class SettingsDialogGeneral(QWidget): def __init__(self, dialog): super().__init__() layout = QVBoxLayout() layout.setAlignment(Qt.AlignTop) self.__language_gb = QGroupBox() layout.addWidget(self.__language_gb) self.__language_selector = QComboBox() configured_language_id = Application().config.language current_language_id = Application().language.current_language for no, (lang_id, label) in enumerate(AVAILABLE_LANGUAGES): self.__language_selector.addItem(label) if lang_id == configured_language_id: self.__language_selector.setCurrentIndex(no) elif configured_language_id is None and lang_id != current_language_id: self.__language_selector.setCurrentIndex(no) self.__use_system = QRadioButton() self.__use_custom = QRadioButton() self.__use_custom.toggled.connect(self.__use_custom_changed) if configured_language_id is None: self.__use_system.setChecked(True) self.__language_selector.setEnabled(False) else: self.__use_custom.setChecked(True) language_layout = QFormLayout() language_layout.addRow(self.__use_system) language_layout.addRow(self.__use_custom, self.__language_selector) self.__language_gb.setLayout(language_layout) self.setLayout(layout) self.reload_texts() def __use_custom_changed(self, checked): self.__language_selector.setEnabled(checked) @staticmethod def get_name(): return _("General") def apply_settings(self): if self.__use_system.isChecked(): Application().language.change_language(None) else: selected_no = self.__language_selector.currentIndex() Application().language.change_language( AVAILABLE_LANGUAGES[selected_no][0]) def reload_texts(self): self.__use_system.setText(_("Use system language")) self.__use_custom.setText(_("Custom language")) self.__language_gb.setTitle(_("Application language"))
class ControllerWindow(QWidget): def __init__(self): super(ControllerWindow, self).__init__() self.setWindowTitle("Controller") self.setGeometry(1060, 100, 240, 540) self.initUI() self.show() def initUI(self): self.wHLayoutWidget = QWidget(self) self.wHLayoutWidget.setGeometry(0, 0, 240, 50) self.wHLayout = QHBoxLayout(self.wHLayoutWidget) self.wHLayout.setContentsMargins(5, 5, 5, 5) self.btnStepBackward = QToolButton(self.wHLayoutWidget) self.btnStepBackward.setIcon(QIcon("./assets/icons/step-backward.svg")) self.btnStepBackward.setToolTip("Quay lại bước trước") self.btnStepBackward.clicked.connect(controller.debugStepBackward) self.wHLayout.addWidget(self.btnStepBackward) self.iconPlay = QIcon("./assets/icons/play.svg") self.iconPause = QIcon("./assets/icons/pause.svg") self.btnToggleRun = QToolButton(self.wHLayoutWidget) self.btnToggleRun.setIcon(self.iconPlay) self.btnToggleRun.setToolTip("Bắt đầu/Dừng quá trình tìm kiếm") self.btnToggleRun.clicked.connect(self.toggleRun) self.wHLayout.addWidget(self.btnToggleRun) self.btnStepForward = QToolButton(self.wHLayoutWidget) self.btnStepForward.setIcon(QIcon("./assets/icons/step-forward.svg")) self.btnStepForward.setToolTip("Bước tới một bước") self.btnStepForward.clicked.connect(controller.debugStepForward) self.wHLayout.addWidget(self.btnStepForward) self.btnStop = QToolButton(self.wHLayoutWidget) self.btnStop.setIcon(QIcon("./assets/icons/times.svg")) self.btnStop.setToolTip("Dừng chương trình") self.btnStop.clicked.connect(QCoreApplication.instance().quit) self.wHLayout.addWidget(self.btnStop) self.controlSeperator = QFrame(self) self.controlSeperator.setGeometry(0, 45, 240, 5) self.controlSeperator.setFrameShape(QFrame.HLine) self.controlSeperator.setFrameShadow(QFrame.Sunken) self.wFormLayoutWidget = QWidget(self) self.wFormLayoutWidget.setGeometry(0, 50, 240, 165) self.wFormLayout = QFormLayout(self.wFormLayoutWidget) self.wFormLayout.setContentsMargins(5, 5, 5, 5) self.labelAlg = QLabel(self.wFormLayoutWidget) self.labelAlg.setText("Chọn thuật toán") self.wFormLayout.setWidget(0, QFormLayout.LabelRole, self.labelAlg) self.algorithmChoice = QComboBox(self.wFormLayoutWidget) for algo in controller.algorithms: self.algorithmChoice.addItem(algo['name']) self.algorithmChoice.currentIndexChanged.connect(self.changeAlgo) self.wFormLayout.setWidget(0, QFormLayout.FieldRole, self.algorithmChoice) self.labelWidth, self.inpWidth = self._createLineInput( 1, "Số ô ngang", QIntValidator(1, 9999999), self.wFormLayout, self.wFormLayoutWidget) self.labelHeight, self.inpHeight = self._createLineInput( 2, "Số ô dọc", QIntValidator(1, 9999999), self.wFormLayout, self.wFormLayoutWidget) self.labelDelayTime, self.delayTime = self._createLineInput( 3, "Thời gian đợi", QIntValidator(20, 9999999), self.wFormLayout, self.wFormLayoutWidget) self.labelInput = QLabel(self.wFormLayoutWidget) self.labelInput.setText("Input") self.wFormLayout.setWidget(4, QFormLayout.LabelRole, self.labelInput) self.chooseInputFile = QPushButton(self.wFormLayoutWidget) self.chooseInputFile.setText("Chọn File") self.chooseInputFile.clicked.connect(self.pick_input) self.wFormLayout.setWidget(4, QFormLayout.FieldRole, self.chooseInputFile) self.btnApply = QPushButton(self) self.btnApply.setText("Áp dụng") self.btnApply.setGeometry(5, 220, 230, 25) self.btnApply.clicked.connect(self.applySettings) self.infoSeperator = QFrame(self) self.infoSeperator.setGeometry(0, 250, 240, 5) self.infoSeperator.setFrameShape(QFrame.HLine) self.infoSeperator.setFrameShadow(QFrame.Sunken) self.wInfoLayoutWidget = QWidget(self) self.wInfoLayoutWidget.setGeometry(0, 260, 240, 300) self.wInfoLayout = QFormLayout(self.wInfoLayoutWidget) self.wInfoLayout.setContentsMargins(5, 5, 5, 5) self.labelCost, self.valCost = self._createInfo( 0, "Cost", "_", self.wInfoLayout, self.wInfoLayoutWidget) self.labelTimeCost, self.valTimeCost = self._createInfo( 1, "Duration", "_", self.wInfoLayout, self.wInfoLayoutWidget) # self.btnToggle3D = QPushButton(self) # self.btnToggle3D.setText("Đổi sang chế độ 3D") # self.btnToggle3D.setGeometry(5, 510, 230, 25) # self.btnToggle3D.clicked.connect(self.toggle_3D) self.updateValuesFromState() def updateValuesFromState(self): self.inpWidth.setText(str(controller.map.width)) self.inpHeight.setText(str(controller.map.height)) self.delayTime.setText(str(controller.delayTime)) if controller.running: self.btnToggleRun.setIcon(self.iconPause) else: self.btnToggleRun.setIcon(self.iconPlay) def applySettings(self): controller.delayTime = int(self.delayTime.text()) controller.setMapWidth(int(self.inpWidth.text())) controller.setMapHeight(int(self.inpHeight.text())) controller.winRenderer.update() def changeAlgo(self, v): controller.currentAlgo = int(v) def toggleRun(self): newV = not controller.running if newV: self.btnToggleRun.setIcon(self.iconPause) else: self.btnToggleRun.setIcon(self.iconPlay) controller.running = newV if newV and controller.started: controller.update() if not controller.started and newV is True: controller.pfStart() def pick_input(self): filename, _ = QFileDialog.getOpenFileName( None, "Chọn file Input", "", "All Files (*);;Text Files (*.txt)") if filename: inp = open(filename, "r") controller.setNewInput(''.join([line for line in inp.readlines()])) self.updateValuesFromState() controller.winRenderer.update() def setPfResult(self, cost, time): self.valCost.setText(str(cost)) self.valTimeCost.setText(str(time)) def _createInfo(self, index, text, valText, parent, container): label = QLabel(container) label.setText(text) parent.setWidget(index, QFormLayout.LabelRole, label) val = QLabel(container) val.setText(valText) val.setAlignment(Qt.AlignRight) parent.setWidget(index, QFormLayout.FieldRole, val) return label, val def _createLineInput(self, index, text, validator, parent, container): label = QLabel(container) label.setText(text) parent.setWidget(index, QFormLayout.LabelRole, label) inp = QLineEdit(container) inp.setAlignment(Qt.AlignRight) inp.setValidator(validator) parent.setWidget(index, QFormLayout.FieldRole, inp) return label, inp
class Window(QWidget): NumRenderAreas = 9 def __init__(self): super(Window, self).__init__() rectPath = QPainterPath() rectPath.moveTo(20.0, 30.0) rectPath.lineTo(80.0, 30.0) rectPath.lineTo(80.0, 70.0) rectPath.lineTo(20.0, 70.0) rectPath.closeSubpath() roundRectPath = QPainterPath() roundRectPath.moveTo(80.0, 35.0) roundRectPath.arcTo(70.0, 30.0, 10.0, 10.0, 0.0, 90.0) roundRectPath.lineTo(25.0, 30.0) roundRectPath.arcTo(20.0, 30.0, 10.0, 10.0, 90.0, 90.0) roundRectPath.lineTo(20.0, 65.0) roundRectPath.arcTo(20.0, 60.0, 10.0, 10.0, 180.0, 90.0) roundRectPath.lineTo(75.0, 70.0) roundRectPath.arcTo(70.0, 60.0, 10.0, 10.0, 270.0, 90.0) roundRectPath.closeSubpath() ellipsePath = QPainterPath() ellipsePath.moveTo(80.0, 50.0) ellipsePath.arcTo(20.0, 30.0, 60.0, 40.0, 0.0, 360.0) piePath = QPainterPath() piePath.moveTo(50.0, 50.0) piePath.lineTo(65.0, 32.6795) piePath.arcTo(20.0, 30.0, 60.0, 40.0, 60.0, 240.0) piePath.closeSubpath() polygonPath = QPainterPath() polygonPath.moveTo(10.0, 80.0) polygonPath.lineTo(20.0, 10.0) polygonPath.lineTo(80.0, 30.0) polygonPath.lineTo(90.0, 70.0) polygonPath.closeSubpath() groupPath = QPainterPath() groupPath.moveTo(60.0, 40.0) groupPath.arcTo(20.0, 20.0, 40.0, 40.0, 0.0, 360.0) groupPath.moveTo(40.0, 40.0) groupPath.lineTo(40.0, 80.0) groupPath.lineTo(80.0, 80.0) groupPath.lineTo(80.0, 40.0) groupPath.closeSubpath() textPath = QPainterPath() timesFont = QFont("Times", 50) timesFont.setStyleStrategy(QFont.ForceOutline) textPath.addText(10, 70, timesFont, "Qt") bezierPath = QPainterPath() bezierPath.moveTo(20, 30) bezierPath.cubicTo(80, 0, 50, 50, 80, 80) starPath = QPainterPath() starPath.moveTo(90, 50) for i in range(1, 5): starPath.lineTo(50 + 40 * cos(0.8 * i * pi), 50 + 40 * sin(0.8 * i * pi)) starPath.closeSubpath() self.renderAreas = [ RenderArea(rectPath), RenderArea(roundRectPath), RenderArea(ellipsePath), RenderArea(piePath), RenderArea(polygonPath), RenderArea(groupPath), RenderArea(textPath), RenderArea(bezierPath), RenderArea(starPath), ] assert len(self.renderAreas) == 9 self.fillRuleComboBox = QComboBox() self.fillRuleComboBox.addItem("Odd Even", Qt.OddEvenFill) self.fillRuleComboBox.addItem("Winding", Qt.WindingFill) fillRuleLabel = QLabel("Fill &Rule:") fillRuleLabel.setBuddy(self.fillRuleComboBox) self.fillColor1ComboBox = QComboBox() self.populateWithColors(self.fillColor1ComboBox) self.fillColor1ComboBox.setCurrentIndex( self.fillColor1ComboBox.findText("mediumslateblue")) self.fillColor2ComboBox = QComboBox() self.populateWithColors(self.fillColor2ComboBox) self.fillColor2ComboBox.setCurrentIndex( self.fillColor2ComboBox.findText("cornsilk")) fillGradientLabel = QLabel("&Fill Gradient:") fillGradientLabel.setBuddy(self.fillColor1ComboBox) fillToLabel = QLabel("to") fillToLabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.penWidthSpinBox = QSpinBox() self.penWidthSpinBox.setRange(0, 20) penWidthLabel = QLabel("&Pen Width:") penWidthLabel.setBuddy(self.penWidthSpinBox) self.penColorComboBox = QComboBox() self.populateWithColors(self.penColorComboBox) self.penColorComboBox.setCurrentIndex( self.penColorComboBox.findText("darkslateblue")) penColorLabel = QLabel("Pen &Color:") penColorLabel.setBuddy(self.penColorComboBox) self.rotationAngleSpinBox = QSpinBox() self.rotationAngleSpinBox.setRange(0, 359) self.rotationAngleSpinBox.setWrapping(True) self.rotationAngleSpinBox.setSuffix(u"\N{DEGREE SIGN}") rotationAngleLabel = QLabel("&Rotation Angle:") rotationAngleLabel.setBuddy(self.rotationAngleSpinBox) self.fillRuleComboBox.activated.connect(self.fillRuleChanged) self.fillColor1ComboBox.activated.connect(self.fillGradientChanged) self.fillColor2ComboBox.activated.connect(self.fillGradientChanged) self.penColorComboBox.activated.connect(self.penColorChanged) for i in range(Window.NumRenderAreas): self.penWidthSpinBox.valueChanged.connect( self.renderAreas[i].setPenWidth) self.rotationAngleSpinBox.valueChanged.connect( self.renderAreas[i].setRotationAngle) topLayout = QGridLayout() for i in range(Window.NumRenderAreas): topLayout.addWidget(self.renderAreas[i], i / 3, i % 3) mainLayout = QGridLayout() mainLayout.addLayout(topLayout, 0, 0, 1, 4) mainLayout.addWidget(fillRuleLabel, 1, 0) mainLayout.addWidget(self.fillRuleComboBox, 1, 1, 1, 3) mainLayout.addWidget(fillGradientLabel, 2, 0) mainLayout.addWidget(self.fillColor1ComboBox, 2, 1) mainLayout.addWidget(fillToLabel, 2, 2) mainLayout.addWidget(self.fillColor2ComboBox, 2, 3) mainLayout.addWidget(penWidthLabel, 3, 0) mainLayout.addWidget(self.penWidthSpinBox, 3, 1, 1, 3) mainLayout.addWidget(penColorLabel, 4, 0) mainLayout.addWidget(self.penColorComboBox, 4, 1, 1, 3) mainLayout.addWidget(rotationAngleLabel, 5, 0) mainLayout.addWidget(self.rotationAngleSpinBox, 5, 1, 1, 3) self.setLayout(mainLayout) self.fillRuleChanged() self.fillGradientChanged() self.penColorChanged() self.penWidthSpinBox.setValue(2) self.setWindowTitle("Painter Paths") def fillRuleChanged(self): rule = Qt.FillRule(self.currentItemData(self.fillRuleComboBox)) for i in range(Window.NumRenderAreas): self.renderAreas[i].setFillRule(rule) def fillGradientChanged(self): color1 = QColor(self.currentItemData(self.fillColor1ComboBox)) color2 = QColor(self.currentItemData(self.fillColor2ComboBox)) for i in range(Window.NumRenderAreas): self.renderAreas[i].setFillGradient(color1, color2) def penColorChanged(self): color = QColor(self.currentItemData(self.penColorComboBox)) for i in range(Window.NumRenderAreas): self.renderAreas[i].setPenColor(color) def populateWithColors(self, comboBox): colorNames = QColor.colorNames() for name in colorNames: comboBox.addItem(name, name) def currentItemData(self, comboBox): return comboBox.itemData(comboBox.currentIndex())
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.gridGroupBox = QGroupBox("參數設定", self) layout = QGridLayout() self.manLabel = QLabel("測試人員", self) self.manLabel.resize(50, 250) self.combo001 = QComboBox(self) self.combo001.addItem('男性') self.combo001.addItem('女性') self.combo001.resize(50, 400) self.hightLabel = QLabel("身高(cm)", self) self.combo002 = QComboBox(self) self.combo002.addItem('150') self.combo002.addItem('160') self.combo002.addItem('170') self.combo002.addItem('180') self.combo002.addItem('190') self.strainLabel = QLabel("拉伸應變(%)", self) self.combo003 = QComboBox(self) self.combo003.addItem('5%') self.combo003.addItem('7.5%') self.combo003.addItem('10%') self.combo003.addItem('12.5%') self.combo003.addItem('15%') # self.combo003.activated[str].connect(self.onActivated) layout.setSpacing(20) layout.addWidget(self.manLabel, 1, 0) layout.addWidget(self.combo001, 1, 1) layout.addWidget(self.hightLabel, 2, 0) layout.addWidget(self.combo002, 2, 1) layout.addWidget(self.strainLabel, 3, 0) # layout.addWidget(self.emitLineEdit,2,1) layout.addWidget(self.combo003, 3, 1) self.noLabel1 = QLabel("案例編號", self) self.noLineEdit1 = QLineEdit("POC-", self) self.caseLabel1 = QLabel("案例名稱", self) self.caseLineEdit1 = QLineEdit(" ", self) self.dateLabel1 = QLabel("更新日期", self) self.dateLineEdit1 = QLineEdit("2021-01-", self) layout.setSpacing(20) layout.addWidget(self.noLabel1, 4, 0) layout.addWidget(self.noLineEdit1, 4, 1) layout.addWidget(self.caseLabel1, 5, 0) layout.addWidget(self.caseLineEdit1, 5, 1) layout.addWidget(self.dateLabel1, 6, 0) layout.addWidget(self.dateLineEdit1, 6, 1) self.pushButton_A01 = QPushButton() ### self.pushButton_A01.setGeometry(QtCore.QRect(10, 30, 45, 35)) self.pushButton_A01.setObjectName("pushButton_014") self.pushButton_A01.setStyleSheet( "background-color: #1F1F1F; color: white;font: 100 10pt \"Arial Narrow\"" ) self.pushButton_A01.setText("存檔") # self.pushButton_014.setFont(QFont('Arial', 5)) # self.pushButton_A01.scaled(20,15, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.pushButton_A01.setStyleSheet( "QPushButton{color:white}" "QPushButton:hover{color:yellow}" ## "QPushButton{border-image: url(/FHEUI/fig/max1.png)}" # "QPushButton{background-image: url(/FHEUI/fig/max1.png)}" "QPushButton{background-color:#1E1E1E}" # "QPushButton:hover{background-image:url(/FHEUI/fig/max2.png)}" "QPushButton{border:1px}" "QPushButton{border-radius:2px}" "QPushButton{font: 10pt} " "QPushButton{padding:2px 4px}") self.pushButton_A01.clicked.connect(self.saveas001) self.pushButton_A02 = QPushButton() ### self.pushButton_A01.setGeometry(QtCore.QRect(10, 30, 45, 35)) self.pushButton_A02.setObjectName("pushButton_014") self.pushButton_A02.setStyleSheet( "background-color: #1F1F1F; color: white;font: 100 10pt \"Arial Narrow\"" ) self.pushButton_A02.setText("修改") # self.pushButton_014.setFont(QFont('Arial', 5)) # self.pushButton_A01.scaled(20,15, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.pushButton_A02.setStyleSheet( "QPushButton{color:white}" "QPushButton:hover{color:yellow}" ## "QPushButton{border-image: url(/FHEUI/fig/max1.png)}" # "QPushButton{background-image: url(/FHEUI/fig/max1.png)}" "QPushButton{background-color:#1E1E1E}" # "QPushButton:hover{background-image:url(/FHEUI/fig/max2.png)}" "QPushButton{border:1px}" "QPushButton{border-radius:2px}" "QPushButton{font: 10pt} " "QPushButton{padding:2px 4px}") self.pushButton_A02.clicked.connect(self.modify001) layout.addWidget(self.pushButton_A01, 7, 0) layout.addWidget(self.pushButton_A02, 7, 1) layout.setColumnStretch(1, 1) self.gridGroupBox.setLayout(layout) self.gridGroupBox.resize(400, 450) self.setWindowTitle('智慧褲線路佈局') self.setWindowIcon(QIcon('fig\itrilogo.png')) self.setGeometry(475, 200, 400, 450) self.show() def modify001(self): self.noLineEdit1.clear() self.caseLineEdit1.setText(" ") self.dateLineEdit1.setText(" ") def saveas001(self, text): text001 = str(self.noLineEdit1.text()) text002 = str(self.caseLineEdit1.text()) text003 = str(self.dateLineEdit1.text()) text004 = "FHE ID_001" text005 = str(self.combo001.currentText()) text006 = str(self.combo002.currentText()) text007 = str(self.combo003.currentText()) # print(text001) filename, filetype = QFileDialog.getSaveFileName( self, "Save File", "*.txt") with open(filename, 'w', encoding='utf-8-sig') as f: print(filename) f.write(text001 + '\n') f.write(text002 + '\n') f.write(text003 + '\n') f.write(text004 + '\n') f.write(text005 + '\n') f.write(text006 + '\n') f.write(text007) f.close()
class LedgerAuthDialog(QDialog): def __init__(self, handler, data): '''Ask user for 2nd factor authentication. Support text, security card and paired mobile methods. Use last method from settings, but support new pairing and downgrade. ''' QDialog.__init__(self, handler.top_level_window()) self.handler = handler self.txdata = data self.idxs = self.txdata[ 'keycardData'] if self.txdata['confirmationType'] > 1 else '' self.setMinimumWidth(650) self.setWindowTitle(_("Ledger Wallet Authentication")) self.cfg = copy.deepcopy(self.handler.win.wallet.get_keystore().cfg) self.dongle = self.handler.win.wallet.get_keystore().get_client( ).dongle self.ws = None self.pin = '' self.devmode = self.getDevice2FAMode() if self.devmode == 0x11 or self.txdata['confirmationType'] == 1: self.cfg['mode'] = 0 vbox = QVBoxLayout() self.setLayout(vbox) def on_change_mode(idx): if idx < 2 and self.ws: self.ws.stop() self.ws = None self.cfg[ 'mode'] = 0 if self.devmode == 0x11 else idx if idx > 0 else 1 if self.cfg['mode'] > 1 and self.cfg['pair'] and not self.ws: self.req_validation() if self.cfg['mode'] > 0: self.handler.win.wallet.get_keystore().cfg = self.cfg self.handler.win.wallet.save_keystore() self.update_dlg() def add_pairing(): self.do_pairing() def return_pin(): self.pin = self.pintxt.text( ) if self.txdata['confirmationType'] == 1 else self.cardtxt.text() if self.cfg['mode'] == 1: self.pin = ''.join(chr(int(str(i), 16)) for i in self.pin) self.accept() self.modebox = QWidget() modelayout = QHBoxLayout() self.modebox.setLayout(modelayout) modelayout.addWidget(QLabel(_("Method:"))) self.modes = QComboBox() modelayout.addWidget(self.modes, 2) self.addPair = QPushButton(_("Pair")) self.addPair.setMaximumWidth(60) modelayout.addWidget(self.addPair) modelayout.addStretch(1) self.modebox.setMaximumHeight(50) vbox.addWidget(self.modebox) self.populate_modes() self.modes.currentIndexChanged.connect(on_change_mode) self.addPair.clicked.connect(add_pairing) self.helpmsg = QTextEdit() self.helpmsg.setStyleSheet( "QTextEdit { background-color: lightgray; }") self.helpmsg.setReadOnly(True) vbox.addWidget(self.helpmsg) self.pinbox = QWidget() pinlayout = QHBoxLayout() self.pinbox.setLayout(pinlayout) self.pintxt = QLineEdit() self.pintxt.setEchoMode(2) self.pintxt.setMaxLength(4) self.pintxt.returnPressed.connect(return_pin) pinlayout.addWidget(QLabel(_("Enter PIN:"))) pinlayout.addWidget(self.pintxt) pinlayout.addWidget(QLabel(_("NOT DEVICE PIN - see above"))) pinlayout.addStretch(1) self.pinbox.setVisible(self.cfg['mode'] == 0) vbox.addWidget(self.pinbox) self.cardbox = QWidget() card = QVBoxLayout() self.cardbox.setLayout(card) self.addrtext = QTextEdit() self.addrtext.setStyleSheet( "QTextEdit { color:blue; background-color:lightgray; padding:15px 10px; border:none; font-size:20pt; font-family:monospace; }" ) self.addrtext.setReadOnly(True) self.addrtext.setMaximumHeight(130) card.addWidget(self.addrtext) def pin_changed(s): if len(s) < len(self.idxs): i = self.idxs[len(s)] addr = self.txdata['address'] if not constants.net.TESTNET: text = addr[:i] + '<u><b>' + addr[ i:i + 1] + '</u></b>' + addr[i + 1:] else: # pin needs to be created from mainnet address addr_mainnet = bitcoin.script_to_address( bitcoin.address_to_script(addr), net=constants.BitcoinMainnet) addr_mainnet = addr_mainnet[:i] + '<u><b>' + addr_mainnet[ i:i + 1] + '</u></b>' + addr_mainnet[i + 1:] text = str(addr) + '\n' + str(addr_mainnet) self.addrtext.setHtml(str(text)) else: self.addrtext.setHtml(_("Press Enter")) pin_changed('') cardpin = QHBoxLayout() cardpin.addWidget(QLabel(_("Enter PIN:"))) self.cardtxt = QLineEdit() self.cardtxt.setEchoMode(2) self.cardtxt.setMaxLength(len(self.idxs)) self.cardtxt.textChanged.connect(pin_changed) self.cardtxt.returnPressed.connect(return_pin) cardpin.addWidget(self.cardtxt) cardpin.addWidget(QLabel(_("NOT DEVICE PIN - see above"))) cardpin.addStretch(1) card.addLayout(cardpin) self.cardbox.setVisible(self.cfg['mode'] == 1) vbox.addWidget(self.cardbox) self.pairbox = QWidget() pairlayout = QVBoxLayout() self.pairbox.setLayout(pairlayout) pairhelp = QTextEdit(helpTxt[5]) pairhelp.setStyleSheet("QTextEdit { background-color: lightgray; }") pairhelp.setReadOnly(True) pairlayout.addWidget(pairhelp, 1) self.pairqr = QRCodeWidget() pairlayout.addWidget(self.pairqr, 4) self.pairbox.setVisible(False) vbox.addWidget(self.pairbox) self.update_dlg() if self.cfg['mode'] > 1 and not self.ws: self.req_validation() def populate_modes(self): self.modes.blockSignals(True) self.modes.clear() self.modes.addItem( _("Summary Text PIN (requires dongle replugging)" ) if self.txdata['confirmationType'] == 1 else _("Summary Text PIN is Disabled")) if self.txdata['confirmationType'] > 1: self.modes.addItem(_("Security Card Challenge")) if not self.cfg['pair']: self.modes.addItem(_("Mobile - Not paired")) else: self.modes.addItem( _("Mobile - {}").format(self.cfg['pair'][1])) self.modes.blockSignals(False) def update_dlg(self): self.modes.setCurrentIndex(self.cfg['mode']) self.modebox.setVisible(True) self.addPair.setText( _("Pair") if not self.cfg['pair'] else _("Re-Pair")) self.addPair.setVisible(self.txdata['confirmationType'] > 2) self.helpmsg.setText( helpTxt[self.cfg['mode'] if self.cfg['mode'] < 2 else 2 if self. cfg['pair'] else 4]) self.helpmsg.setMinimumHeight(180 if self.txdata['confirmationType'] == 1 else 100) self.pairbox.setVisible(False) self.helpmsg.setVisible(True) self.pinbox.setVisible(self.cfg['mode'] == 0) self.cardbox.setVisible(self.cfg['mode'] == 1) self.pintxt.setFocus( True) if self.cfg['mode'] == 0 else self.cardtxt.setFocus(True) self.setMaximumHeight(400) def do_pairing(self): rng = os.urandom(16) pairID = (hexlify(rng) + hexlify(hashlib.sha256(rng).digest()[0:1])).decode('utf-8') self.pairqr.setData(pairID) self.modebox.setVisible(False) self.helpmsg.setVisible(False) self.pinbox.setVisible(False) self.cardbox.setVisible(False) self.pairbox.setVisible(True) self.pairqr.setMinimumSize(300, 300) if self.ws: self.ws.stop() self.ws = LedgerWebSocket(self, pairID) self.ws.pairing_done.connect(self.pairing_done) self.ws.start() def pairing_done(self, data): if data is not None: self.cfg['pair'] = [data['pairid'], data['name'], data['platform']] self.cfg['mode'] = 2 self.handler.win.wallet.get_keystore().cfg = self.cfg self.handler.win.wallet.save_keystore() self.pin = 'paired' self.accept() def req_validation(self): if self.cfg['pair'] and 'secureScreenData' in self.txdata: if self.ws: self.ws.stop() self.ws = LedgerWebSocket(self, self.cfg['pair'][0], self.txdata) self.ws.req_updated.connect(self.req_updated) self.ws.start() def req_updated(self, pin): if pin == 'accepted': self.helpmsg.setText(helpTxt[3]) else: self.pin = str(pin) self.accept() def getDevice2FAMode(self): apdu = [0xe0, 0x24, 0x01, 0x00, 0x00, 0x01] # get 2fa mode try: mode = self.dongle.exchange(bytearray(apdu)) return mode except BTChipException as e: debug_msg('Device getMode Failed') return 0x11 def closeEvent(self, evnt): debug_msg("CLOSE - Stop WS") if self.ws: self.ws.stop() if self.pairbox.isVisible(): evnt.ignore() self.update_dlg()
class ReTextWindow(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.resize(950, 700) screenRect = QDesktopWidget().screenGeometry() if globalSettings.windowGeometry: self.restoreGeometry(globalSettings.windowGeometry) else: self.move((screenRect.width()-self.width())/2, (screenRect.height()-self.height())/2) if not screenRect.contains(self.geometry()): self.showMaximized() if sys.platform.startswith('darwin'): # https://github.com/retext-project/retext/issues/198 searchPaths = QIcon.themeSearchPaths() searchPaths.append('/opt/local/share/icons') searchPaths.append('/usr/local/share/icons') QIcon.setThemeSearchPaths(searchPaths) if globalSettings.iconTheme: QIcon.setThemeName(globalSettings.iconTheme) if QIcon.themeName() in ('hicolor', ''): if not QFile.exists(getBundledIcon('document-new')): QIcon.setThemeName(get_icon_theme()) if QFile.exists(getBundledIcon('retext')): self.setWindowIcon(QIcon(getBundledIcon('retext'))) elif QFile.exists('/usr/share/pixmaps/retext.png'): self.setWindowIcon(QIcon('/usr/share/pixmaps/retext.png')) else: self.setWindowIcon(QIcon.fromTheme('retext', QIcon.fromTheme('accessories-text-editor'))) self.tabWidget = QTabWidget(self) self.initTabWidget() self.setCentralWidget(self.tabWidget) self.tabWidget.currentChanged.connect(self.changeIndex) self.tabWidget.tabCloseRequested.connect(self.closeTab) self.toolBar = QToolBar(self.tr('File toolbar'), self) self.addToolBar(Qt.TopToolBarArea, self.toolBar) self.editBar = QToolBar(self.tr('Edit toolbar'), self) self.addToolBar(Qt.TopToolBarArea, self.editBar) self.searchBar = QToolBar(self.tr('Search toolbar'), self) self.addToolBar(Qt.BottomToolBarArea, self.searchBar) self.toolBar.setVisible(not globalSettings.hideToolBar) self.editBar.setVisible(not globalSettings.hideToolBar) self.actionNew = self.act(self.tr('New'), 'document-new', self.createNew, shct=QKeySequence.New) self.actionNew.setPriority(QAction.LowPriority) self.actionOpen = self.act(self.tr('Open'), 'document-open', self.openFile, shct=QKeySequence.Open) self.actionOpen.setPriority(QAction.LowPriority) self.actionSetEncoding = self.act(self.tr('Set encoding'), trig=self.showEncodingDialog) self.actionSetEncoding.setEnabled(False) self.actionReload = self.act(self.tr('Reload'), 'view-refresh', lambda: self.currentTab.readTextFromFile()) self.actionReload.setEnabled(False) self.actionSave = self.act(self.tr('Save'), 'document-save', self.saveFile, shct=QKeySequence.Save) self.actionSave.setEnabled(False) self.actionSave.setPriority(QAction.LowPriority) self.actionSaveAs = self.act(self.tr('Save as'), 'document-save-as', self.saveFileAs, shct=QKeySequence.SaveAs) self.actionNextTab = self.act(self.tr('Next tab'), 'go-next', lambda: self.switchTab(1), shct=Qt.CTRL+Qt.Key_PageDown) self.actionPrevTab = self.act(self.tr('Previous tab'), 'go-previous', lambda: self.switchTab(-1), shct=Qt.CTRL+Qt.Key_PageUp) self.actionCloseCurrentTab = self.act(self.tr('Close tab'), 'window-close', lambda: self.closeTab(self.ind), shct=QKeySequence.Close) self.actionPrint = self.act(self.tr('Print'), 'document-print', self.printFile, shct=QKeySequence.Print) self.actionPrint.setPriority(QAction.LowPriority) self.actionPrintPreview = self.act(self.tr('Print preview'), 'document-print-preview', self.printPreview) self.actionViewHtml = self.act(self.tr('View HTML code'), 'text-html', self.viewHtml) self.actionChangeEditorFont = self.act(self.tr('Change editor font'), trig=self.changeEditorFont) self.actionChangePreviewFont = self.act(self.tr('Change preview font'), trig=self.changePreviewFont) self.actionSearch = self.act(self.tr('Find text'), 'edit-find', self.search, shct=QKeySequence.Find) self.actionGoToLine = self.act(self.tr('Go to line'), trig=self.goToLine, shct=Qt.CTRL+Qt.Key_G) self.searchBar.visibilityChanged.connect(self.searchBarVisibilityChanged) self.actionPreview = self.act(self.tr('Preview'), shct=Qt.CTRL+Qt.Key_E, trigbool=self.preview) if QIcon.hasThemeIcon('document-preview'): self.actionPreview.setIcon(QIcon.fromTheme('document-preview')) elif QIcon.hasThemeIcon('preview-file'): self.actionPreview.setIcon(QIcon.fromTheme('preview-file')) elif QIcon.hasThemeIcon('x-office-document'): self.actionPreview.setIcon(QIcon.fromTheme('x-office-document')) else: self.actionPreview.setIcon(QIcon(getBundledIcon('document-preview'))) self.actionLivePreview = self.act(self.tr('Live preview'), shct=Qt.CTRL+Qt.Key_L, trigbool=self.enableLivePreview) menuPreview = QMenu() menuPreview.addAction(self.actionLivePreview) self.actionPreview.setMenu(menuPreview) self.actionInsertTable = self.act(self.tr('Insert table'), trig=lambda: self.insertFormatting('table')) self.actionTableMode = self.act(self.tr('Table editing mode'), shct=Qt.CTRL+Qt.Key_T, trigbool=lambda x: self.currentTab.editBox.enableTableMode(x)) if ReTextFakeVimHandler: self.actionFakeVimMode = self.act(self.tr('FakeVim mode'), shct=Qt.CTRL+Qt.ALT+Qt.Key_V, trigbool=self.enableFakeVimMode) if globalSettings.useFakeVim: self.actionFakeVimMode.setChecked(True) self.enableFakeVimMode(True) self.actionFullScreen = self.act(self.tr('Fullscreen mode'), 'view-fullscreen', shct=Qt.Key_F11, trigbool=self.enableFullScreen) self.actionFullScreen.setChecked(self.isFullScreen()) self.actionFullScreen.setPriority(QAction.LowPriority) self.actionConfig = self.act(self.tr('Preferences'), icon='preferences-system', trig=self.openConfigDialog) self.actionConfig.setMenuRole(QAction.PreferencesRole) self.actionSaveHtml = self.act('HTML', 'text-html', self.saveFileHtml) self.actionPdf = self.act('PDF', 'application-pdf', self.savePdf) self.actionOdf = self.act('ODT', 'x-office-document', self.saveOdf) self.getExportExtensionsList() self.actionQuit = self.act(self.tr('Quit'), 'application-exit', shct=QKeySequence.Quit) self.actionQuit.setMenuRole(QAction.QuitRole) self.actionQuit.triggered.connect(self.close) self.actionUndo = self.act(self.tr('Undo'), 'edit-undo', lambda: self.currentTab.editBox.undo(), shct=QKeySequence.Undo) self.actionRedo = self.act(self.tr('Redo'), 'edit-redo', lambda: self.currentTab.editBox.redo(), shct=QKeySequence.Redo) self.actionCopy = self.act(self.tr('Copy'), 'edit-copy', lambda: self.currentTab.editBox.copy(), shct=QKeySequence.Copy) self.actionCut = self.act(self.tr('Cut'), 'edit-cut', lambda: self.currentTab.editBox.cut(), shct=QKeySequence.Cut) self.actionPaste = self.act(self.tr('Paste'), 'edit-paste', lambda: self.currentTab.editBox.paste(), shct=QKeySequence.Paste) self.actionPasteImage = self.act(self.tr('Paste image'), 'edit-paste', lambda: self.currentTab.editBox.pasteImage(), shct=Qt.CTRL+Qt.SHIFT+Qt.Key_V) self.actionMoveUp = self.act(self.tr('Move line up'), 'go-up', lambda: self.currentTab.editBox.moveLineUp(), shct=Qt.ALT+Qt.Key_Up) self.actionMoveDown = self.act(self.tr('Move line down'), 'go-down', lambda: self.currentTab.editBox.moveLineDown(), shct=Qt.ALT+Qt.Key_Down) self.actionUndo.setEnabled(False) self.actionRedo.setEnabled(False) self.actionCopy.setEnabled(False) self.actionCut.setEnabled(False) qApp = QApplication.instance() qApp.clipboard().dataChanged.connect(self.clipboardDataChanged) self.clipboardDataChanged() if enchant is not None: self.actionEnableSC = self.act(self.tr('Enable'), trigbool=self.enableSpellCheck) self.actionSetLocale = self.act(self.tr('Set locale'), trig=self.changeLocale) self.actionWebKit = self.act(self.tr('Use WebKit renderer'), trigbool=self.enableWebKit) if ReTextWebKitPreview is None: globalSettings.useWebKit = False self.actionWebKit.setEnabled(False) self.actionWebKit.setChecked(globalSettings.useWebKit) self.actionWebEngine = self.act(self.tr('Use WebEngine (Chromium) renderer'), trigbool=self.enableWebEngine) if ReTextWebEnginePreview is None: globalSettings.useWebEngine = False self.actionWebEngine.setChecked(globalSettings.useWebEngine) self.actionShow = self.act(self.tr('Show directory'), 'system-file-manager', self.showInDir) self.actionFind = self.act(self.tr('Next'), 'go-next', self.find, shct=QKeySequence.FindNext) self.actionFindPrev = self.act(self.tr('Previous'), 'go-previous', lambda: self.find(back=True), shct=QKeySequence.FindPrevious) self.actionReplace = self.act(self.tr('Replace'), 'edit-find-replace', lambda: self.find(replace=True)) self.actionReplaceAll = self.act(self.tr('Replace all'), trig=self.replaceAll) menuReplace = QMenu() menuReplace.addAction(self.actionReplaceAll) self.actionReplace.setMenu(menuReplace) self.actionCloseSearch = self.act(self.tr('Close'), 'window-close', lambda: self.searchBar.setVisible(False), shct=QKeySequence.Cancel) self.actionCloseSearch.setPriority(QAction.LowPriority) self.actionHelp = self.act(self.tr('Get help online'), 'help-contents', self.openHelp) self.aboutWindowTitle = self.tr('About ReText') self.actionAbout = self.act(self.aboutWindowTitle, 'help-about', self.aboutDialog) self.actionAbout.setMenuRole(QAction.AboutRole) self.actionAboutQt = self.act(self.tr('About Qt')) self.actionAboutQt.setMenuRole(QAction.AboutQtRole) self.actionAboutQt.triggered.connect(qApp.aboutQt) availableMarkups = markups.get_available_markups() if not availableMarkups: print('Warning: no markups are available!') if len(availableMarkups) > 1: self.chooseGroup = QActionGroup(self) markupActions = [] for markup in availableMarkups: markupAction = self.act(markup.name, trigbool=self.markupFunction(markup)) if markup.name == globalSettings.defaultMarkup: markupAction.setChecked(True) self.chooseGroup.addAction(markupAction) markupActions.append(markupAction) self.actionBold = self.act(self.tr('Bold'), shct=QKeySequence.Bold, trig=lambda: self.insertFormatting('bold')) self.actionItalic = self.act(self.tr('Italic'), shct=QKeySequence.Italic, trig=lambda: self.insertFormatting('italic')) self.actionUnderline = self.act(self.tr('Underline'), shct=QKeySequence.Underline, trig=lambda: self.insertFormatting('underline')) self.usefulTags = ('header', 'italic', 'bold', 'underline', 'numbering', 'bullets', 'image', 'link', 'inline code', 'code block', 'blockquote', 'table') self.usefulChars = ('deg', 'divide', 'euro', 'hellip', 'laquo', 'larr', 'lsquo', 'mdash', 'middot', 'minus', 'nbsp', 'ndash', 'raquo', 'rarr', 'rsquo', 'times') self.formattingBox = QComboBox(self.editBar) self.formattingBox.addItem(self.tr('Formatting')) self.formattingBox.addItems(self.usefulTags) self.formattingBox.activated[str].connect(self.insertFormatting) self.symbolBox = QComboBox(self.editBar) self.symbolBox.addItem(self.tr('Symbols')) self.symbolBox.addItems(self.usefulChars) self.symbolBox.activated.connect(self.insertSymbol) self.updateStyleSheet() menubar = self.menuBar() menuFile = menubar.addMenu(self.tr('File')) menuEdit = menubar.addMenu(self.tr('Edit')) menuHelp = menubar.addMenu(self.tr('Help')) menuFile.addAction(self.actionNew) menuFile.addAction(self.actionOpen) self.menuRecentFiles = menuFile.addMenu(self.tr('Open recent')) self.menuRecentFiles.aboutToShow.connect(self.updateRecentFiles) menuFile.addAction(self.actionShow) menuFile.addAction(self.actionSetEncoding) menuFile.addAction(self.actionReload) menuFile.addSeparator() menuFile.addAction(self.actionSave) menuFile.addAction(self.actionSaveAs) menuFile.addSeparator() menuFile.addAction(self.actionNextTab) menuFile.addAction(self.actionPrevTab) menuFile.addAction(self.actionCloseCurrentTab) menuFile.addSeparator() menuExport = menuFile.addMenu(self.tr('Export')) menuExport.addAction(self.actionSaveHtml) menuExport.addAction(self.actionOdf) menuExport.addAction(self.actionPdf) if self.extensionActions: menuExport.addSeparator() for action, mimetype in self.extensionActions: menuExport.addAction(action) menuExport.aboutToShow.connect(self.updateExtensionsVisibility) menuFile.addAction(self.actionPrint) menuFile.addAction(self.actionPrintPreview) menuFile.addSeparator() menuFile.addAction(self.actionQuit) menuEdit.addAction(self.actionUndo) menuEdit.addAction(self.actionRedo) menuEdit.addSeparator() menuEdit.addAction(self.actionCut) menuEdit.addAction(self.actionCopy) menuEdit.addAction(self.actionPaste) menuEdit.addAction(self.actionPasteImage) menuEdit.addSeparator() menuEdit.addAction(self.actionMoveUp) menuEdit.addAction(self.actionMoveDown) menuEdit.addSeparator() if enchant is not None: menuSC = menuEdit.addMenu(self.tr('Spell check')) menuSC.addAction(self.actionEnableSC) menuSC.addAction(self.actionSetLocale) menuEdit.addAction(self.actionSearch) menuEdit.addAction(self.actionGoToLine) menuEdit.addAction(self.actionChangeEditorFont) menuEdit.addAction(self.actionChangePreviewFont) menuEdit.addSeparator() if len(availableMarkups) > 1: self.menuMode = menuEdit.addMenu(self.tr('Default markup')) for markupAction in markupActions: self.menuMode.addAction(markupAction) menuFormat = menuEdit.addMenu(self.tr('Formatting')) menuFormat.addAction(self.actionBold) menuFormat.addAction(self.actionItalic) menuFormat.addAction(self.actionUnderline) if ReTextWebKitPreview is not None or ReTextWebEnginePreview is None: menuEdit.addAction(self.actionWebKit) else: menuEdit.addAction(self.actionWebEngine) menuEdit.addSeparator() menuEdit.addAction(self.actionViewHtml) menuEdit.addAction(self.actionPreview) menuEdit.addAction(self.actionInsertTable) menuEdit.addAction(self.actionTableMode) if ReTextFakeVimHandler: menuEdit.addAction(self.actionFakeVimMode) menuEdit.addSeparator() menuEdit.addAction(self.actionFullScreen) menuEdit.addAction(self.actionConfig) menuHelp.addAction(self.actionHelp) menuHelp.addSeparator() menuHelp.addAction(self.actionAbout) menuHelp.addAction(self.actionAboutQt) self.toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.toolBar.addAction(self.actionNew) self.toolBar.addSeparator() self.toolBar.addAction(self.actionOpen) self.toolBar.addAction(self.actionSave) self.toolBar.addAction(self.actionPrint) self.toolBar.addSeparator() self.toolBar.addAction(self.actionPreview) self.toolBar.addAction(self.actionFullScreen) self.editBar.addAction(self.actionUndo) self.editBar.addAction(self.actionRedo) self.editBar.addSeparator() self.editBar.addAction(self.actionCut) self.editBar.addAction(self.actionCopy) self.editBar.addAction(self.actionPaste) self.editBar.addSeparator() self.editBar.addWidget(self.formattingBox) self.editBar.addWidget(self.symbolBox) self.searchEdit = QLineEdit(self.searchBar) self.searchEdit.setPlaceholderText(self.tr('Search')) self.searchEdit.returnPressed.connect(self.find) self.replaceEdit = QLineEdit(self.searchBar) self.replaceEdit.setPlaceholderText(self.tr('Replace with')) self.replaceEdit.returnPressed.connect(self.find) self.csBox = QCheckBox(self.tr('Case sensitively'), self.searchBar) self.searchBar.addWidget(self.searchEdit) self.searchBar.addWidget(self.replaceEdit) self.searchBar.addSeparator() self.searchBar.addWidget(self.csBox) self.searchBar.addAction(self.actionFindPrev) self.searchBar.addAction(self.actionFind) self.searchBar.addAction(self.actionReplace) self.searchBar.addAction(self.actionCloseSearch) self.searchBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.searchBar.setVisible(False) self.autoSaveEnabled = globalSettings.autoSave if self.autoSaveEnabled: timer = QTimer(self) timer.start(60000) timer.timeout.connect(self.saveAll) self.ind = None if enchant is not None: self.sl = globalSettings.spellCheckLocale try: enchant.Dict(self.sl or None) except enchant.errors.Error as e: warnings.warn(str(e), RuntimeWarning) globalSettings.spellCheck = False if globalSettings.spellCheck: self.actionEnableSC.setChecked(True) self.fileSystemWatcher = QFileSystemWatcher() self.fileSystemWatcher.fileChanged.connect(self.fileChanged) def restoreLastOpenedFiles(self): for file in readListFromSettings("lastFileList"): self.openFileWrapper(file) # Show the tab of last opened file lastTabIndex = globalSettings.lastTabIndex if lastTabIndex >= 0 and lastTabIndex < self.tabWidget.count(): self.tabWidget.setCurrentIndex(lastTabIndex) def iterateTabs(self): for i in range(self.tabWidget.count()): yield self.tabWidget.widget(i) def updateStyleSheet(self): self.ss = None if globalSettings.styleSheet: sheetfile = QFile(globalSettings.styleSheet) sheetfile.open(QIODevice.ReadOnly) self.ss = QTextStream(sheetfile).readAll() sheetfile.close() def initTabWidget(self): def dragEnterEvent(e): e.acceptProposedAction() def dropEvent(e): fn = bytes(e.mimeData().data('text/plain')).decode().rstrip() if fn.startswith('file:'): fn = QUrl(fn).toLocalFile() self.openFileWrapper(fn) self.tabWidget.setTabsClosable(True) self.tabWidget.setAcceptDrops(True) self.tabWidget.setMovable(True) self.tabWidget.dragEnterEvent = dragEnterEvent self.tabWidget.dropEvent = dropEvent self.tabWidget.setTabBarAutoHide(globalSettings.tabBarAutoHide) def act(self, name, icon=None, trig=None, trigbool=None, shct=None): if not isinstance(shct, QKeySequence): shct = QKeySequence(shct) if icon: action = QAction(self.actIcon(icon), name, self) else: action = QAction(name, self) if trig: action.triggered.connect(trig) elif trigbool: action.setCheckable(True) action.triggered[bool].connect(trigbool) if shct: action.setShortcut(shct) return action def actIcon(self, name): return QIcon.fromTheme(name, QIcon(getBundledIcon(name))) def printError(self): import traceback print('Exception occurred while parsing document:', file=sys.stderr) traceback.print_exc() def tabFileNameChanged(self, tab): ''' Perform all UI state changes that need to be done when the filename of the current tab has changed. ''' if tab == self.currentTab: if tab.fileName: self.setWindowTitle("") if globalSettings.windowTitleFullPath: self.setWindowTitle(tab.fileName + '[*]') self.setWindowFilePath(tab.fileName) self.tabWidget.setTabText(self.ind, tab.getBaseName()) self.tabWidget.setTabToolTip(self.ind, tab.fileName) QDir.setCurrent(QFileInfo(tab.fileName).dir().path()) else: self.setWindowFilePath('') self.setWindowTitle(self.tr('New document') + '[*]') canReload = bool(tab.fileName) and not self.autoSaveActive(tab) self.actionSetEncoding.setEnabled(canReload) self.actionReload.setEnabled(canReload) def tabActiveMarkupChanged(self, tab): ''' Perform all UI state changes that need to be done when the active markup class of the current tab has changed. ''' if tab == self.currentTab: markupClass = tab.getActiveMarkupClass() dtMarkdown = (markupClass == markups.MarkdownMarkup) dtMkdOrReST = dtMarkdown or (markupClass == markups.ReStructuredTextMarkup) self.formattingBox.setEnabled(dtMarkdown) self.symbolBox.setEnabled(dtMarkdown) self.actionUnderline.setEnabled(dtMarkdown) self.actionBold.setEnabled(dtMkdOrReST) self.actionItalic.setEnabled(dtMkdOrReST) def tabModificationStateChanged(self, tab): ''' Perform all UI state changes that need to be done when the modification state of the current tab has changed. ''' if tab == self.currentTab: changed = tab.editBox.document().isModified() if self.autoSaveActive(tab): changed = False self.actionSave.setEnabled(changed) self.setWindowModified(changed) def createTab(self, fileName): previewStatesByName = { 'editor': PreviewDisabled, 'normal-preview': PreviewNormal, 'live-preview': PreviewLive, } previewState = previewStatesByName.get(globalSettings.defaultPreviewState, PreviewDisabled) if previewState == PreviewNormal and not fileName: previewState = PreviewDisabled # Opening empty document in preview mode makes no sense self.currentTab = ReTextTab(self, fileName, previewState) self.currentTab.fileNameChanged.connect(lambda: self.tabFileNameChanged(self.currentTab)) self.currentTab.modificationStateChanged.connect(lambda: self.tabModificationStateChanged(self.currentTab)) self.currentTab.activeMarkupChanged.connect(lambda: self.tabActiveMarkupChanged(self.currentTab)) self.tabWidget.addTab(self.currentTab, self.tr("New document")) self.currentTab.updateBoxesVisibility() if previewState > 0: QTimer.singleShot(500, self.currentTab.triggerPreviewUpdate) def closeTab(self, ind): if self.maybeSave(ind): if self.tabWidget.count() == 1: self.createTab("") closedTab = self.tabWidget.widget(ind) if closedTab.fileName: self.fileSystemWatcher.removePath(closedTab.fileName) self.tabWidget.removeTab(ind) closedTab.deleteLater() def changeIndex(self, ind): ''' This function is called when a different tab is selected. It changes the state of the window to mirror the current state of the newly selected tab. Future changes to this state will be done in response to signals emitted by the tab, to which the window was subscribed when the tab was created. The window is subscribed to all tabs like this, but only the active tab will logically generate these signals. Aside from the above this function also calls the handlers for the other changes that are implied by a tab switch: filename change, modification state change and active markup change. ''' self.currentTab = self.tabWidget.currentWidget() editBox = self.currentTab.editBox previewState = self.currentTab.previewState self.actionUndo.setEnabled(editBox.document().isUndoAvailable()) self.actionRedo.setEnabled(editBox.document().isRedoAvailable()) self.actionCopy.setEnabled(editBox.textCursor().hasSelection()) self.actionCut.setEnabled(editBox.textCursor().hasSelection()) self.actionPreview.setChecked(previewState >= PreviewLive) self.actionLivePreview.setChecked(previewState == PreviewLive) self.actionTableMode.setChecked(editBox.tableModeEnabled) self.editBar.setEnabled(previewState < PreviewNormal) self.ind = ind editBox.setFocus(Qt.OtherFocusReason) self.tabFileNameChanged(self.currentTab) self.tabModificationStateChanged(self.currentTab) self.tabActiveMarkupChanged(self.currentTab) def changeEditorFont(self): font, ok = QFontDialog.getFont(globalSettings.editorFont, self) if ok: self.setEditorFont(font) def setEditorFont(self, font): globalSettings.editorFont = font for tab in self.iterateTabs(): tab.editBox.updateFont() def changePreviewFont(self): font, ok = QFontDialog.getFont(globalSettings.font, self) if ok: self.setPreviewFont(font) def setPreviewFont(self, font): globalSettings.font = font for tab in self.iterateTabs(): tab.triggerPreviewUpdate() def preview(self, viewmode): self.currentTab.previewState = viewmode * 2 self.actionLivePreview.setChecked(False) self.editBar.setDisabled(viewmode) self.currentTab.updateBoxesVisibility() self.currentTab.triggerPreviewUpdate() def enableLivePreview(self, livemode): self.currentTab.previewState = int(livemode) self.actionPreview.setChecked(livemode) self.editBar.setEnabled(True) self.currentTab.updateBoxesVisibility() self.currentTab.triggerPreviewUpdate() def enableWebKit(self, enable): globalSettings.useWebKit = enable globalSettings.useWebEngine = False for tab in self.iterateTabs(): tab.rebuildPreviewBox() def enableWebEngine(self, enable): globalSettings.useWebKit = False globalSettings.useWebEngine = enable for tab in self.iterateTabs(): tab.rebuildPreviewBox() def enableCopy(self, copymode): self.actionCopy.setEnabled(copymode) self.actionCut.setEnabled(copymode) def enableFullScreen(self, yes): if yes: self.showFullScreen() else: self.showNormal() def openConfigDialog(self): dlg = ConfigDialog(self) dlg.setWindowTitle(self.tr('Preferences')) dlg.show() def enableFakeVimMode(self, yes): globalSettings.useFakeVim = yes if yes: FakeVimMode.init(self) for tab in self.iterateTabs(): tab.editBox.installFakeVimHandler() else: FakeVimMode.exit(self) def enableSpellCheck(self, yes): try: dict = enchant.Dict(self.sl or None) except enchant.errors.Error as e: QMessageBox.warning(self, '', str(e)) self.actionEnableSC.setChecked(False) yes = False self.setAllDictionaries(dict if yes else None) globalSettings.spellCheck = yes def setAllDictionaries(self, dictionary): for tab in self.iterateTabs(): hl = tab.highlighter hl.dictionary = dictionary hl.rehighlight() def changeLocale(self): localedlg = LocaleDialog(self, defaultText=self.sl) if localedlg.exec() != QDialog.Accepted: return sl = localedlg.localeEdit.text() try: enchant.Dict(sl or None) except enchant.errors.Error as e: QMessageBox.warning(self, '', str(e)) else: self.sl = sl or None self.enableSpellCheck(self.actionEnableSC.isChecked()) if localedlg.checkBox.isChecked(): globalSettings.spellCheckLocale = sl def search(self): self.searchBar.setVisible(True) self.searchEdit.setFocus(Qt.ShortcutFocusReason) def goToLine(self): line, ok = QInputDialog.getInt(self, self.tr("Go to line"), self.tr("Type the line number")) if ok: self.currentTab.goToLine(line-1) def searchBarVisibilityChanged(self, visible): if visible: self.searchEdit.setFocus(Qt.ShortcutFocusReason) def find(self, back=False, replace=False): flags = QTextDocument.FindFlags() if back: flags |= QTextDocument.FindBackward if self.csBox.isChecked(): flags |= QTextDocument.FindCaseSensitively text = self.searchEdit.text() replaceText = self.replaceEdit.text() if replace else None found = self.currentTab.find(text, flags, replaceText=replaceText) self.setSearchEditColor(found) def replaceAll(self): text = self.searchEdit.text() replaceText = self.replaceEdit.text() found = self.currentTab.replaceAll(text, replaceText) self.setSearchEditColor(found) def setSearchEditColor(self, found): palette = self.searchEdit.palette() palette.setColor(QPalette.Active, QPalette.Base, Qt.white if found else QColor(255, 102, 102)) self.searchEdit.setPalette(palette) def showInDir(self): if self.currentTab.fileName: path = QFileInfo(self.currentTab.fileName).path() QDesktopServices.openUrl(QUrl.fromLocalFile(path)) else: QMessageBox.warning(self, '', self.tr("Please, save the file somewhere.")) def moveToTopOfRecentFileList(self, fileName): if fileName: files = readListFromSettings("recentFileList") if fileName in files: files.remove(fileName) files.insert(0, fileName) recentCount = globalSettings.recentDocumentsCount if len(files) > recentCount: del files[recentCount:] writeListToSettings("recentFileList", files) def createNew(self, text=None): self.createTab("") self.ind = self.tabWidget.count()-1 self.tabWidget.setCurrentIndex(self.ind) if text: self.currentTab.editBox.textCursor().insertText(text) def switchTab(self, shift=1): self.tabWidget.setCurrentIndex((self.ind + shift) % self.tabWidget.count()) def updateRecentFiles(self): self.menuRecentFiles.clear() self.recentFilesActions = [] filesOld = readListFromSettings("recentFileList") files = [] for f in filesOld: if QFile.exists(f): files.append(f) self.recentFilesActions.append(self.act(f, trig=self.openFunction(f))) writeListToSettings("recentFileList", files) for action in self.recentFilesActions: self.menuRecentFiles.addAction(action) def markupFunction(self, markup): return lambda: self.setDefaultMarkup(markup) def openFunction(self, fileName): return lambda: self.openFileWrapper(fileName) def extensionFunction(self, data): return lambda: \ self.runExtensionCommand(data['Exec'], data['FileFilter'], data['DefaultExtension']) def getExportExtensionsList(self): extensions = [] for extsprefix in datadirs: extsdir = QDir(extsprefix+'/export-extensions/') if extsdir.exists(): for fileInfo in extsdir.entryInfoList(['*.desktop', '*.ini'], QDir.Files | QDir.Readable): extensions.append(self.readExtension(fileInfo.filePath())) locale = QLocale.system().name() self.extensionActions = [] for extension in extensions: try: if ('Name[%s]' % locale) in extension: name = extension['Name[%s]' % locale] elif ('Name[%s]' % locale.split('_')[0]) in extension: name = extension['Name[%s]' % locale.split('_')[0]] else: name = extension['Name'] data = {} for prop in ('FileFilter', 'DefaultExtension', 'Exec'): if 'X-ReText-'+prop in extension: data[prop] = extension['X-ReText-'+prop] elif prop in extension: data[prop] = extension[prop] else: data[prop] = '' action = self.act(name, trig=self.extensionFunction(data)) if 'Icon' in extension: action.setIcon(self.actIcon(extension['Icon'])) mimetype = extension['MimeType'] if 'MimeType' in extension else None except KeyError: print('Failed to parse extension: Name is required', file=sys.stderr) else: self.extensionActions.append((action, mimetype)) def updateExtensionsVisibility(self): markupClass = self.currentTab.getActiveMarkupClass() for action in self.extensionActions: if markupClass is None: action[0].setEnabled(False) continue mimetype = action[1] if mimetype is None: enabled = True elif markupClass == markups.MarkdownMarkup: enabled = (mimetype in ("text/x-retext-markdown", "text/x-markdown", "text/markdown")) elif markupClass == markups.ReStructuredTextMarkup: enabled = (mimetype in ("text/x-retext-rst", "text/x-rst")) else: enabled = False action[0].setEnabled(enabled) def readExtension(self, fileName): extFile = QFile(fileName) extFile.open(QIODevice.ReadOnly) extension = {} stream = QTextStream(extFile) while not stream.atEnd(): line = stream.readLine() if '=' in line: index = line.index('=') extension[line[:index].rstrip()] = line[index+1:].lstrip() extFile.close() return extension def openFile(self): supportedExtensions = ['.txt'] for markup in markups.get_all_markups(): supportedExtensions += markup.file_extensions fileFilter = ' (' + str.join(' ', ['*'+ext for ext in supportedExtensions]) + ');;' fileNames = QFileDialog.getOpenFileNames(self, self.tr("Select one or several files to open"), QDir.currentPath(), self.tr("Supported files") + fileFilter + self.tr("All files (*)")) for fileName in fileNames[0]: self.openFileWrapper(fileName) @pyqtSlot(str) def openFileWrapper(self, fileName): if not fileName: return fileName = QFileInfo(fileName).canonicalFilePath() exists = False for i, tab in enumerate(self.iterateTabs()): if tab.fileName == fileName: exists = True ex = i if exists: self.tabWidget.setCurrentIndex(ex) elif QFile.exists(fileName): noEmptyTab = ( (self.ind is None) or self.currentTab.fileName or self.currentTab.editBox.toPlainText() or self.currentTab.editBox.document().isModified() ) if noEmptyTab: self.createTab(fileName) self.ind = self.tabWidget.count()-1 self.tabWidget.setCurrentIndex(self.ind) if fileName: self.fileSystemWatcher.addPath(fileName) self.currentTab.readTextFromFile(fileName) self.moveToTopOfRecentFileList(self.currentTab.fileName) def showEncodingDialog(self): if not self.maybeSave(self.ind): return codecsSet = set(bytes(QTextCodec.codecForName(alias).name()) for alias in QTextCodec.availableCodecs()) encoding, ok = QInputDialog.getItem(self, '', self.tr('Select file encoding from the list:'), [bytes(b).decode() for b in sorted(codecsSet)], 0, False) if ok: self.currentTab.readTextFromFile(None, encoding) def saveFileAs(self): self.saveFile(dlg=True) def saveAll(self): for tab in self.iterateTabs(): if (tab.fileName and tab.editBox.document().isModified() and QFileInfo(tab.fileName).isWritable()): tab.saveTextToFile() def saveFile(self, dlg=False): fileNameToSave = self.currentTab.fileName if (not fileNameToSave) or dlg: proposedFileName = "" markupClass = self.currentTab.getActiveMarkupClass() if (markupClass is None) or not hasattr(markupClass, 'default_extension'): defaultExt = self.tr("Plain text (*.txt)") ext = ".txt" else: defaultExt = self.tr('%s files', 'Example of final string: Markdown files') \ % markupClass.name + ' (' + str.join(' ', ('*'+extension for extension in markupClass.file_extensions)) + ')' if markupClass == markups.MarkdownMarkup: ext = globalSettings.markdownDefaultFileExtension elif markupClass == markups.ReStructuredTextMarkup: ext = globalSettings.restDefaultFileExtension else: ext = markupClass.default_extension if fileNameToSave is not None: proposedFileName = fileNameToSave fileNameToSave = QFileDialog.getSaveFileName(self, self.tr("Save file"), proposedFileName, defaultExt)[0] if fileNameToSave: if not QFileInfo(fileNameToSave).suffix(): fileNameToSave += ext # Make sure we don't overwrite a file opened in other tab for tab in self.iterateTabs(): if tab is not self.currentTab and tab.fileName == fileNameToSave: QMessageBox.warning(self, "", self.tr("Cannot save to file which is open in another tab!")) return False self.actionSetEncoding.setDisabled(self.autoSaveActive()) if fileNameToSave: if self.currentTab.saveTextToFile(fileNameToSave): self.moveToTopOfRecentFileList(self.currentTab.fileName) return True else: QMessageBox.warning(self, '', self.tr("Cannot save to file because it is read-only!")) return False def saveHtml(self, fileName): if not QFileInfo(fileName).suffix(): fileName += ".html" try: _, htmltext, _ = self.currentTab.getDocumentForExport(webenv=True) except Exception: return self.printError() htmlFile = QFile(fileName) result = htmlFile.open(QIODevice.WriteOnly) if not result: QMessageBox.warning(self, '', self.tr("Cannot save to file because it is read-only!")) return html = QTextStream(htmlFile) if globalSettings.defaultCodec: html.setCodec(globalSettings.defaultCodec) html << htmltext htmlFile.close() def textDocument(self, title, htmltext): td = QTextDocument() td.setMetaInformation(QTextDocument.DocumentTitle, title) td.setHtml(htmltext) td.setDefaultFont(globalSettings.font) return td def saveOdf(self): title, htmltext, _ = self.currentTab.getDocumentForExport() try: document = self.textDocument(title, htmltext) except Exception: return self.printError() fileName = QFileDialog.getSaveFileName(self, self.tr("Export document to ODT"), self.currentTab.getBaseName() + ".odt", self.tr("OpenDocument text files (*.odt)"))[0] if not QFileInfo(fileName).suffix(): fileName += ".odt" writer = QTextDocumentWriter(fileName) writer.setFormat(b"odf") writer.write(document) def saveFileHtml(self): fileName = QFileDialog.getSaveFileName(self, self.tr("Save file"), self.currentTab.getBaseName() + ".html", self.tr("HTML files (*.html *.htm)"))[0] if fileName: self.saveHtml(fileName) def getDocumentForPrint(self, title, htmltext, preview): if globalSettings.useWebKit: return preview try: return self.textDocument(title, htmltext) except Exception: self.printError() def standardPrinter(self, title): printer = QPrinter(QPrinter.HighResolution) printer.setDocName(title) printer.setCreator('ReText %s' % app_version) if globalSettings.paperSize: pageSize = self.getPageSizeByName(globalSettings.paperSize) if pageSize is not None: printer.setPaperSize(pageSize) else: QMessageBox.warning(self, '', self.tr('Unrecognized paperSize setting "%s".') % globalSettings.paperSize) return printer def getPageSizeByName(self, pageSizeName): """ Returns a validated PageSize instance corresponding to the given name. Returns None if the name is not a valid PageSize. """ pageSize = None lowerCaseNames = {pageSize.lower(): pageSize for pageSize in self.availablePageSizes()} if pageSizeName.lower() in lowerCaseNames: pageSize = getattr(QPagedPaintDevice, lowerCaseNames[pageSizeName.lower()]) return pageSize def availablePageSizes(self): """ List available page sizes. """ sizes = [x for x in dir(QPagedPaintDevice) if type(getattr(QPagedPaintDevice, x)) == QPagedPaintDevice.PageSize] return sizes def savePdf(self): fileName = QFileDialog.getSaveFileName(self, self.tr("Export document to PDF"), self.currentTab.getBaseName() + ".pdf", self.tr("PDF files (*.pdf)"))[0] if fileName: if not QFileInfo(fileName).suffix(): fileName += ".pdf" title, htmltext, preview = self.currentTab.getDocumentForExport() if globalSettings.useWebEngine and hasattr(preview.page(), "printToPdf"): pageSize = self.getPageSizeByName(globalSettings.paperSize) if pageSize is None: pageSize = QPageSize(QPageSize.A4) margins = QMarginsF(20, 20, 13, 20) # left, top, right, bottom (in millimeters) layout = QPageLayout(pageSize, QPageLayout.Portrait, margins, QPageLayout.Millimeter) preview.page().printToPdf(fileName, layout) # Available since Qt 5.7 return printer = self.standardPrinter(title) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(fileName) document = self.getDocumentForPrint(title, htmltext, preview) if document != None: document.print(printer) def printFile(self): title, htmltext, preview = self.currentTab.getDocumentForExport() printer = self.standardPrinter(title) dlg = QPrintDialog(printer, self) dlg.setWindowTitle(self.tr("Print document")) if (dlg.exec() == QDialog.Accepted): document = self.getDocumentForPrint(title, htmltext, preview) if document != None: document.print(printer) def printPreview(self): title, htmltext, preview = self.currentTab.getDocumentForExport() document = self.getDocumentForPrint(title, htmltext, preview) if document is None: return printer = self.standardPrinter(title) preview = QPrintPreviewDialog(printer, self) preview.paintRequested.connect(document.print) preview.exec() def runExtensionCommand(self, command, filefilter, defaultext): import shlex of = ('%of' in command) html = ('%html' in command) if of: if defaultext and not filefilter: filefilter = '*'+defaultext fileName = QFileDialog.getSaveFileName(self, self.tr('Export document'), '', filefilter)[0] if not fileName: return if defaultext and not QFileInfo(fileName).suffix(): fileName += defaultext else: fileName = 'out' + defaultext basename = '.%s.retext-temp' % self.currentTab.getBaseName() if html: tmpname = basename+'.html' self.saveHtml(tmpname) else: tmpname = basename + self.currentTab.getActiveMarkupClass().default_extension self.currentTab.writeTextToFile(tmpname) command = command.replace('%of', shlex.quote(fileName)) command = command.replace('%html' if html else '%if', shlex.quote(tmpname)) try: Popen(str(command), shell=True).wait() except Exception as error: errorstr = str(error) QMessageBox.warning(self, '', self.tr('Failed to execute the command:') + '\n' + errorstr) QFile(tmpname).remove() def autoSaveActive(self, tab=None): tab = tab if tab else self.currentTab return bool(self.autoSaveEnabled and tab.fileName and QFileInfo(tab.fileName).isWritable()) def clipboardDataChanged(self): mimeData = QApplication.instance().clipboard().mimeData() if mimeData is not None: self.actionPaste.setEnabled(mimeData.hasText()) self.actionPasteImage.setEnabled(mimeData.hasImage()) def insertFormatting(self, formatting): if formatting == 'table': dialog = InsertTableDialog(self) dialog.show() self.formattingBox.setCurrentIndex(0) return cursor = self.currentTab.editBox.textCursor() text = cursor.selectedText() moveCursorTo = None def c(cursor): nonlocal moveCursorTo moveCursorTo = cursor.position() def ensurenl(cursor): if not cursor.atBlockStart(): cursor.insertText('\n\n') toinsert = { 'header': (ensurenl, '# ', text), 'italic': ('*', text, c, '*'), 'bold': ('**', text, c, '**'), 'underline': ('<u>', text, c, '</u>'), 'numbering': (ensurenl, ' 1. ', text), 'bullets': (ensurenl, ' * ', text), 'image': ('![', text or self.tr('Alt text'), c, '](', self.tr('URL'), ')'), 'link': ('[', text or self.tr('Link text'), c, '](', self.tr('URL'), ')'), 'inline code': ('`', text, c, '`'), 'code block': (ensurenl, ' ', text), 'blockquote': (ensurenl, '> ', text), } if formatting not in toinsert: return cursor.beginEditBlock() for token in toinsert[formatting]: if callable(token): token(cursor) else: cursor.insertText(token) cursor.endEditBlock() self.formattingBox.setCurrentIndex(0) # Bring back the focus on the editor self.currentTab.editBox.setFocus(Qt.OtherFocusReason) if moveCursorTo: cursor.setPosition(moveCursorTo) self.currentTab.editBox.setTextCursor(cursor) def insertSymbol(self, num): if num: self.currentTab.editBox.insertPlainText('&'+self.usefulChars[num-1]+';') self.symbolBox.setCurrentIndex(0) def fileChanged(self, fileName): tab = None for testtab in self.iterateTabs(): if testtab.fileName == fileName: tab = testtab if tab is None: self.fileSystemWatcher.removePath(fileName) return if not QFile.exists(fileName): self.tabWidget.setCurrentWidget(tab) tab.editBox.document().setModified(True) QMessageBox.warning(self, '', self.tr( 'This file has been deleted by other application.\n' 'Please make sure you save the file before exit.')) elif not tab.editBox.document().isModified(): # File was not modified in ReText, reload silently tab.readTextFromFile() else: self.tabWidget.setCurrentWidget(tab) text = self.tr( 'This document has been modified by other application.\n' 'Do you want to reload the file (this will discard all ' 'your changes)?\n') if self.autoSaveEnabled: text += self.tr( 'If you choose to not reload the file, auto save mode will ' 'be disabled for this session to prevent data loss.') messageBox = QMessageBox(QMessageBox.Warning, '', text) reloadButton = messageBox.addButton(self.tr('Reload'), QMessageBox.YesRole) messageBox.addButton(QMessageBox.Cancel) messageBox.exec() if messageBox.clickedButton() is reloadButton: tab.readTextFromFile() else: self.autoSaveEnabled = False tab.editBox.document().setModified(True) if fileName not in self.fileSystemWatcher.files(): # https://github.com/retext-project/retext/issues/137 self.fileSystemWatcher.addPath(fileName) def maybeSave(self, ind): tab = self.tabWidget.widget(ind) if self.autoSaveActive(tab): tab.saveTextToFile() return True if not tab.editBox.document().isModified(): return True self.tabWidget.setCurrentIndex(ind) ret = QMessageBox.warning(self, '', self.tr("The document has been modified.\nDo you want to save your changes?"), QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) if ret == QMessageBox.Save: return self.saveFile(False) elif ret == QMessageBox.Cancel: return False return True def closeEvent(self, closeevent): for ind in range(self.tabWidget.count()): if not self.maybeSave(ind): return closeevent.ignore() if globalSettings.saveWindowGeometry: globalSettings.windowGeometry = self.saveGeometry() if globalSettings.openLastFilesOnStartup: files = [tab.fileName for tab in self.iterateTabs()] writeListToSettings("lastFileList", files) globalSettings.lastTabIndex = self.tabWidget.currentIndex() closeevent.accept() def viewHtml(self): htmlDlg = HtmlDialog(self) try: _, htmltext, _ = self.currentTab.getDocumentForExport(includeStyleSheet=False) except Exception: return self.printError() winTitle = self.currentTab.getBaseName() htmlDlg.setWindowTitle(winTitle+" ("+self.tr("HTML code")+")") htmlDlg.textEdit.setPlainText(htmltext.rstrip()) htmlDlg.hl.rehighlight() htmlDlg.show() htmlDlg.raise_() htmlDlg.activateWindow() def openHelp(self): QDesktopServices.openUrl(QUrl('https://github.com/retext-project/retext/wiki')) def aboutDialog(self): QMessageBox.about(self, self.aboutWindowTitle, '<p><b>' + (self.tr('ReText %s (using PyMarkups %s)') % (app_version, markups.__version__)) +'</b></p>' + self.tr('Simple but powerful editor' ' for Markdown and reStructuredText') +'</p><p>'+self.tr('Author: Dmitry Shachnev, 2011').replace('2011', '2011–2017') +'<br><a href="https://github.com/retext-project/retext">'+self.tr('Website') +'</a> | <a href="http://daringfireball.net/projects/markdown/syntax">' +self.tr('Markdown syntax') +'</a> | <a href="http://docutils.sourceforge.net/docs/user/rst/quickref.html">' +self.tr('reStructuredText syntax')+'</a></p>') def setDefaultMarkup(self, markupClass): globalSettings.defaultMarkup = markupClass.name for tab in self.iterateTabs(): if not tab.fileName: tab.updateActiveMarkupClass()
class MainWindow(QMainWindow): """Main Window Class Following class contains several public functions to implement GUI of the app. """ def __init__(self): """Initialize Function Following function creates main window and executes all other initialization functions. Args: QMainWindow object: main window of the app. Returns: None """ super().__init__() self.resize(600, 200) self.init_ui() self.setStyleSheet(__style__) self.show() def init_ui(self): """Initialize User Interface Function Following function executes all other initialization functions, defining whole look of the app. Args: QMainWindow object: main window of the app. Returns: None """ self.init_combo_box() self.init_text_edit() self.init_push_button() def init_combo_box(self): """Initialize Combo Boxes Function Following function defines all of the combo boxes of the app. Args: QMainWindow object: main window of the app. Returns: None """ self.adjust_query = QComboBox(self) self.adjust_query.resize(200, 40) self.adjust_query.move(150, 140) def init_text_edit(self): """Initialize Text Edits Function Following function defines all of the text edits of the app. Args: QMainWindow object: main window of the app. Returns: None """ self.russian_text_edit = QTextEdit(self) self.russian_text_edit.setPlaceholderText('Введите термин') self.russian_text_edit.setStyleSheet(__style__) self.russian_text_edit.resize(250, 100) self.russian_text_edit.move(20, 20) self.english_text_edit = QTextEdit(self) self.english_text_edit.setPlaceholderText('Enter term') self.english_text_edit.setStyleSheet(__style__) self.english_text_edit.resize(250, 100) self.english_text_edit.move(330, 20) def init_push_button(self): """Initialize Buttons Function Following function defines all of the buttons of the app. Args: QMainWindow object: main window of the app. Returns: None """ self.translate_to_english_button = QPushButton('>', self) self.translate_to_english_button.clicked.connect( self.translate_to_english_button_clicked) self.translate_to_english_button.resize(20, 20) self.translate_to_english_button.move(290, 40) self.translate_to_russian_button = QPushButton('<', self) self.translate_to_russian_button.clicked.connect( self.translate_to_russian_button_clicked) self.translate_to_russian_button.resize(20, 20) self.translate_to_russian_button.move(290, 80) self.adjust_query_button = QPushButton('Adjust query', self) self.adjust_query_button.clicked.connect( self.adjust_query_button_clicked) self.adjust_query_button.resize(100, 30) self.adjust_query_button.move(370, 140) def translate_to_english_button_clicked(self): """Translate to English Button Clicked Function Following function implements logic, executing when user wants to translate term into English. Args: QMainWindow object: main window of the app. Returns: None """ term = self.russian_text_edit.toPlainText() self.language = 'ru' search_result = Translator.search_user_term(term, self.language) if Translator.translate_user_term(term, self.language)[0] == '0': self.adjust_query.clear() for i in range(len(search_result)): self.adjust_query.addItem(search_result[i]) term = self.adjust_query.currentText() self.english_text_edit.setText( Translator.translate_user_term(term, self.language)[1:]) else: QMessageBox.warning( self, 'Error', Translator.translate_user_term(term, self.language)[1:], QMessageBox.Ok) def translate_to_russian_button_clicked(self): """Translate to Russian Button Clicked Function Following function implements logic, executing when user wants to translate term into Russian. Args: QMainWindow object: main window of the app. Returns: None """ term = self.english_text_edit.toPlainText() self.language = 'en' search_result = Translator.search_user_term(term, self.language) if Translator.translate_user_term(term, self.language)[0] == '0': self.adjust_query.clear() for i in range(len(search_result)): self.adjust_query.addItem(search_result[i]) term = self.adjust_query.currentText() self.russian_text_edit.setText( Translator.translate_user_term(term, self.language)[1:]) else: QMessageBox.warning( self, 'Error', Translator.translate_user_term(term, self.language)[1:], QMessageBox.Ok) def adjust_query_button_clicked(self): """Adjust Query Button Clicked Function Following function implements logic, executing when user wants to adjust query. Args: QMainWindow object: main window of the app. Returns: None """ try: term = self.adjust_query.currentText() adjust_language = self.language search_result = Translator.search_user_term(term, adjust_language) if Translator.translate_user_term(term, adjust_language)[0] == '0': if adjust_language == 'en': self.russian_text_edit.setText( Translator.translate_user_term(term, adjust_language)[1:]) else: self.english_text_edit.setText( Translator.translate_user_term(term, adjust_language)[1:]) else: QMessageBox.warning( self, 'Error', Translator.translate_user_term(term, adjust_language)[1:], QMessageBox.Ok) except UnboundLocalError: QMessageBox.warning(self, 'Error', 'Input term to translate first', QMessageBox.Ok)
class MLSVM_Predict(ElementMaster): pixmap_path = 'images/MLSVM_Predict.png' child_pos = (True, False) def __init__(self, row, column): self.row = row self.column = column # scale_option, scale_mean, scale_std, predict_val, filename, log_state scale_option = 0 scale_mean = True scale_std = True predict_val = False filename = None rel_path = False log_state = False self.config = scale_option, scale_mean, scale_std, predict_val, filename, rel_path, log_state super().__init__(self.row, self.column, self.pixmap_path, True, self.config) super().edit_sig.connect(self.edit) logging.debug( 'MLSVM_Predict::__init__() called at row {}, column {}'.format( row, column)) self.addFunction(MLSVM_PredictFunction) def __setstate__(self, state): logging.debug('MLSVM_Predict::__setstate__() called') self.row, self.column, self.config = state super().__init__(self.row, self.column, self.pixmap_path, True, self.config) super().edit_sig.connect(self.edit) self.addFunction(MLSVM_PredictFunction) def __getstate__(self): logging.debug('MLSVM_Predict::__getstate__() called') return (self.row, self.column, self.config) def openEditor(self): logging.debug('MLSVM_Predict::openEditor() called') def edit(self): logging.debug('MLSVM_Predict::edit()') # scale_option, scale_mean, scale_std, predict_val, filename, log_state self.scale_option, self.scale_mean, self.scale_std, self.predict_val, \ self.filename, self.rel_path, self.log_state = self.config self.home_dict = str(Path.home()) self.scale_label = QLabel() self.scale_label.setText(QC.translate('', 'Scale n_samples ?')) self.scale_list = QComboBox() self.scale_list.addItem(QC.translate('', 'No'), QVariant(False)) self.scale_list.addItem(QC.translate('', 'Yes'), QVariant(True)) self.scale_center_input_line = QWidget() self.scale_center_input_line_layout = QHBoxLayout( self.scale_center_input_line) self.scale_center_label = QLabel() self.scale_center_label.setText( QC.translate('', 'Center data before scaling?')) self.scale_center_checkbox = QCheckBox() self.scale_center_input_line_layout.addWidget(self.scale_center_label) self.scale_center_input_line_layout.addWidget( self.scale_center_checkbox) self.scale_std_input_line = QWidget() self.scale_std_input_line_layout = QHBoxLayout( self.scale_std_input_line) self.scale_std_label = QLabel() self.scale_std_label.setText( QC.translate('', 'Scale data until variance?')) self.scale_std_checkbox = QCheckBox() self.scale_std_input_line_layout.addWidget(self.scale_std_label) self.scale_std_input_line_layout.addWidget(self.scale_std_checkbox) self.scale_input_area = QWidget() self.scale_input_area_layout = QVBoxLayout(self.scale_input_area) self.scale_input_area_layout.addWidget(self.scale_center_input_line) self.scale_input_area_layout.addWidget(self.scale_std_input_line) self.last_value_line = QWidget() self.last_value_line_layout = QHBoxLayout(self.last_value_line) self.last_value_label = QLabel() self.last_value_label.setText( QC.translate('', 'Predict only last value [-1]?')) self.last_value_checkbox = QCheckBox() self.last_value_line_layout.addWidget(self.last_value_label) self.last_value_line_layout.addWidget(self.last_value_checkbox) self.conn_rest_layout = QVBoxLayout() self.confirm_button = QPushButton(QC.translate('', 'Ok')) """ self.filename_text = QLabel() self.filename_text.setWordWrap(True) self.file_button = QPushButton(QC.translate('', 'Select model file')) self.file_button.clicked.connect(self.openFileNameDialog) """ self.filename_text = QLabel() self.filename_text.setWordWrap(True) self.file_button = QPushButton( QC.translate('', 'Select model output file')) self.file_button.clicked.connect(self.openFileNameDialog) self.relative_file_check = QWidget() self.relative_file_check_layout = QHBoxLayout(self.relative_file_check) self.relative_file_label = QLabel() self.relative_file_label.setText( QC.translate('', 'Filename relative to $HOME.')) self.relative_file_checkbox = QCheckBox() self.relative_file_check_layout.addWidget(self.relative_file_checkbox) self.relative_file_check_layout.addWidget(self.relative_file_label) self.relative_file_check_layout.addStretch(1) self.relative_filepath_input = QLineEdit() self.relative_filepath_input.setPlaceholderText('my_folder/my_file') self.file_input = QWidget() self.file_input_layout = QVBoxLayout(self.file_input) self.file_input_layout.addWidget(self.filename_text) self.file_input_layout.addWidget(self.file_button) self.file_input_layout.addWidget(self.relative_file_check) self.file_input_layout.addWidget(self.relative_filepath_input) """ output: prediction quality """ self.help_text_1 = QLabel() self.help_text_1.setText( QC.translate('', 'Expects an array of samples as input.')) self.help_text_2 = QLabel() self.help_text_2.setText( QC.translate('', 'Outputs a single value or an array.')) # hier logging option einfügen self.log_line = QWidget() self.ask_for_logging = QLabel() self.ask_for_logging.setText(QC.translate('', 'Log output?')) self.log_checkbox = QCheckBox() self.log_line_layout = QHBoxLayout(self.log_line) self.log_line_layout.addWidget(self.ask_for_logging) self.log_line_layout.addWidget(self.log_checkbox) self.log_line_layout.addStretch(1) self.ml_svm_predict_edit = ElementEditor(self) self.ml_svm_predict_edit.setWindowTitle( QC.translate('', 'Support Vector Machine Prediction')) self.ml_svm_predict_edit.setMinimumHeight(450) # signals and slots self.relative_file_checkbox.stateChanged.connect(self.toggleFileInput) self.scale_list.currentIndexChanged.connect(self.scaledIndexChanged) self.confirm_button.clicked.connect( self.ml_svm_predict_edit.closeEvent) self.ml_svm_predict_edit.window_closed.connect(self.edit_done) # load config self.loadLastConfig() self.conn_rest_layout.addWidget(self.help_text_1) self.conn_rest_layout.addWidget( self.scale_label) # scale: copy = false self.conn_rest_layout.addWidget(self.scale_list) self.conn_rest_layout.addWidget(self.scale_input_area) self.conn_rest_layout.addWidget(self.last_value_line) self.conn_rest_layout.addWidget(self.file_input) self.conn_rest_layout.addStretch(1) self.conn_rest_layout.addWidget(self.help_text_2) self.conn_rest_layout.addWidget(self.log_line) self.conn_rest_layout.addWidget(self.confirm_button) self.ml_svm_predict_edit.setLayout(self.conn_rest_layout) self.ml_svm_predict_edit.show() def loadLastConfig(self): logging.debug('MLSVM_Predict::loadLastConfig() called') self.scale_list.setCurrentIndex(self.scale_option) self.scaledIndexChanged(self.scale_option) self.scale_center_checkbox.setChecked(self.scale_mean) self.scale_std_checkbox.setChecked(self.scale_std) self.last_value_checkbox.setChecked(self.predict_val) self.log_checkbox.setChecked(self.log_state) self.relative_file_checkbox.setChecked(self.rel_path) if self.rel_path: self.toggleFileInput(2) if self.filename: self.relative_filepath_input.setText(self.filename) else: self.toggleFileInput(0) if self.filename: self.filename_text.setText(self.filename) def toggleFileInput(self, event): logging.debug('MLSVM::toggleFileInput() called: {}'.format(event)) # 0 = FALSE, 2 = TRUE if event: # TRUE self.file_button.setDisabled(True) self.relative_filepath_input.setDisabled(False) self.filename_text.setText('') else: self.file_button.setDisabled(False) self.relative_filepath_input.clear() self.relative_filepath_input.setDisabled(True) self.relative_filepath_input.setPlaceholderText( 'my_folder/my_file') def scaledIndexChanged(self, event): current_index = event logging.debug( 'MLSVM_Predict::scaledIndexChanged() called: {}'.format(event)) if event == 1: self.scale_input_area.setVisible(True) else: self.scale_input_area.setVisible(False) def openFileNameDialog(self, event): options = QFileDialog.Options() #options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, QC.translate('', 'Open SVM model file'), self.home_dict, "All Files (*);;Pythonic Files (*.pyc)", options=options) if fileName: logging.debug( 'MLSVM_Predict::openFileNameDialog() called with filename: {}'. format(fileName)) self.filename = fileName self.filename_text.setText(self.filename) def edit_done(self): logging.debug('MLSVM_Predict::edit_done() called') # scale_option, scale_mean, scale_std, predict_val, filename, log_state scale_option = self.scale_list.currentIndex() scale_mean = self.scale_center_checkbox.isChecked() scale_std = self.scale_std_checkbox.isChecked() predict_val = self.last_value_checkbox.isChecked() log_state = self.log_checkbox.isChecked() rel_path = self.relative_file_checkbox.isChecked() if rel_path: filename = self.relative_filepath_input.text() else: filename = self.filename if filename == '': filename = None self.config = scale_option, scale_mean, scale_std, predict_val, filename, rel_path, log_state self.addFunction(MLSVM_PredictFunction)
class MainWindow(QWidget): def __init__(self, inList): super().__init__() self.inList = inList self.nameFrom = 'Folder' self.codec = 'utvideo' self.alpha = False self.frameRate = 24 self.defaulStyle = '' self.initUI() def initUI(self): #self.hbox = QVBoxLayout(self) self.gridLayout = QGridLayout(self) self.gridLayout.setContentsMargins(11, 11, 11, 11) self.lblCodec = QLabel("Codec", self) self.lblAlpha = QLabel("Alpha", self) self.lblFrameRate = QLabel("Frame Rate", self) self.gridLayout.addWidget(self.lblCodec, 0, 0, 1, 1) self.gridLayout.addWidget(self.lblAlpha, 0, 1, 1, 1) self.gridLayout.addWidget(self.lblFrameRate, 0, 2, 1, 1) self.comboCodec = QComboBox(self) self.comboCodec.setMinimumWidth(80) self.comboCodec.addItem("UT Video") self.comboAlpha = QComboBox(self) self.comboAlpha.setMinimumWidth(80) self.comboAlpha.addItem("No Alpha") self.comboAlpha.addItem("with Alpha") self.comboFrameRate = QComboBox(self) self.comboFrameRate.setMinimumWidth(80) self.comboFrameRate.addItem("24.00") self.comboFrameRate.addItem("30.00") self.buttonCompress = QPushButton("Compress", self) self.buttonCompress.clicked[bool].connect(self.compressPress) self.gridLayout.addWidget(self.comboCodec, 1, 0, 1, 1) self.gridLayout.addWidget(self.comboAlpha, 1, 1, 1, 1) self.gridLayout.addWidget(self.comboFrameRate, 1, 2, 1, 1) self.gridLayout.addWidget(self.buttonCompress, 1, 3, 1, 1) self.groupBox = QButtonGroup(self) self.radio1 = QRadioButton('Output file name from Folder name', self) self.radio2 = QRadioButton('Output file name from File name', self) self.groupBox.addButton(self.radio1, 1) self.groupBox.addButton(self.radio2, 2) self.radio1.setChecked(True) self.gridLayout.addWidget(self.radio1, 2, 0, 1, 2) self.gridLayout.addWidget(self.radio2, 2, 2, 1, 2) self.groupBox.buttonClicked[int].connect(self.radioBtnState) self.pbList = [] for i in range(len(self.inList)): self.tempPB = QProgressBar(self) self.tempPB.setMinimum(0) self.tempPB.setMaximum(100) self.tempPB.setTextVisible(True) self.tempPB.setFormat(str(self.inList[i]) + " %p%") self.tempPB.setAlignment(Qt.AlignCenter) self.tempPB.setValue(0) if i == 0: self.defaulStyle = self.tempPB.styleSheet() self.gridLayout.addWidget(self.tempPB, i + 3, 0, 1, 4) self.pbList.append(self.tempPB) self.errorLlb = QLabel("Output", self) self.gridLayout.addWidget(self.errorLlb, len(self.inList) + 4, 0, 1, 4) self.errorText = QPlainTextEdit('', self) self.gridLayout.addWidget(self.errorText, len(self.inList) + 5, 0, 1, 4) self.spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.spacerItem, len(self.inList) + 6, 0, 1, 1) self.comboCodec.activated[str].connect(self.chooseCodec) self.comboAlpha.activated[str].connect(self.chooseAlpha) self.comboFrameRate.activated[str].connect(self.chooseFrameRate) self.setGeometry(300, 300, 750, 100) #self.gridLayout.setGeometry(QRect(19, 19, 581, 100)) self.setWindowTitle('FFMpeg Python Compressor') self.show() self.threadpool = QThreadPool() self.threadpool.setMaxThreadCount(1) print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount()) ''' Button Functions ''' def chooseAlpha(self, text): switcher = {"No Alpha": False, "with Alpha": True} self.alpha = switcher.get(text, "Invalid day of week") #print (self.alpha) def chooseCodec(self, text): switcher = {"UT Video": "utvideo"} self.codec = switcher.get(text, "Invalid day of week") #print (self.codec) def chooseFrameRate(self, text): self.frameRate = float(text) #print (self.frameRate) def currentData(self, widget): return widget.currentText() def radioBtnState(self, text): switcher = {1: 'Folder', 2: 'File'} self.nameFrom = switcher.get(text, "Invalid day of week") #print(self.nameFrom) ''' Execution Functions ''' def execute_this_fn(self, path, codec, alpha, frameRate, progress_callback, errorFFMPEG_callback): #print(path) pyCompression = pyFFMEGCompress(path, codec, alpha, frameRate) ffProcess = pyCompression.ffmpegCompress() #with kwargs kwargs = { 'progress_callback': progress_callback, 'errorFFMPEG_callback': errorFFMPEG_callback } pyCompression.printProcess(ffProcess, **kwargs) return pyCompression.debugString def printOutput(self, s): print("Printing output " + str(s)) def threadComplete(self, r): print("THREAD COMPLETE! WITH ERROR " + str(r)) def errorPB(self, err): for o in self.pbList: if o.format() == err: o.setValue(100) o.setStyleSheet( "QProgressBar::chunk {background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #FF0350,stop: 0.4999 #FF0020,stop: 0.5 #FF0019,stop: 1 #FF0000 );border-radius: 3px; border: 1px solid #a60233;}QProgressBar{color:white}" ) #("QProgressBar::chunk { background-color: red; }") #pb.setStyleSheet("QProgressBar::chunk { background-color: red; }") o.setFormat(o.format() + " - Error") def resetProgressBar(self, pb, text): pb.setValue(0) pb.setFormat(text + ' %p%') pb.setStyleSheet(self.defaulStyle) def compressPress(self): for i in range(len(self.pbList)): self.resetProgressBar(self.pbList[i], self.inList[i]) worker = Worker( self.execute_this_fn, self.inList[i], self.codec, self.alpha, self.frameRate ) # Any other args, kwargs are passed to the run function #worker.signals.result.connect(self.printOutput) worker.signals.result.connect(self.errorText.appendPlainText) worker.signals.progress.connect(self.pbList[i].setValue) worker.signals.errorFFMPEG.connect(self.errorPB) worker.signals.error.connect(self.errorPB) worker.signals.finished.connect(self.threadComplete) #worker.signals.finished.connect(self.errorText.appendPlainText) # Execute self.threadpool.start(worker)
class Compass(COMCUPluginBase): def __init__(self, *args): super().__init__(BrickletCompass, *args) self.compass = self.device self.cbe_mfd = CallbackEmulator(self.compass.get_magnetic_flux_density, None, self.cb_mfd, self.increase_error_count) self.calibration = None self.compass_widget = CompassWidget() self.current_mfd_x = CurveValueWrapper() # int, µT self.current_mfd_y = CurveValueWrapper() # int, µT self.current_mfd_z = CurveValueWrapper() # int, µT self.heading_label = HeadingLabel() self.inclination_label = InclinationLabel() self.label_widget = QWidget() self.label_layout = QVBoxLayout() self.label_layout.addWidget(self.heading_label) self.label_layout.addWidget(self.inclination_label) self.label_widget.setLayout(self.label_layout) plots = [('X', Qt.red, self.current_mfd_x, '{0} µT'.format), ('Y', Qt.darkGreen, self.current_mfd_y, '{0} µT'.format), ('Z', Qt.blue, self.current_mfd_z, '{0} µT'.format)] self.plot_widget = PlotWidget( 'Magnetic Flux Density [µT]', plots, extra_key_widgets=[self.compass_widget, self.label_widget], update_interval=0.1, y_resolution=1) self.dr_label = QLabel('Data Rate:') self.dr_combo = QComboBox() self.dr_combo.addItem("100 Hz") self.dr_combo.addItem("200 Hz") self.dr_combo.addItem("400 Hz") self.dr_combo.addItem("600 Hz") self.dr_combo.currentIndexChanged.connect(self.new_config) self.button_calibration = QPushButton('Calibrate') self.button_calibration.clicked.connect(self.calibration_clicked) hlayout = QHBoxLayout() hlayout.addStretch() hlayout.addWidget(self.dr_label) hlayout.addWidget(self.dr_combo) hlayout.addStretch() hlayout.addWidget(self.button_calibration) hlayout.addStretch() line = QFrame() line.setObjectName("line") line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout = QVBoxLayout(self) layout.addWidget(self.plot_widget) layout.addWidget(line) layout.addLayout(hlayout) def calibration_clicked(self): if self.calibration == None: self.calibration = Calibration(self) self.button_calibration.setEnabled(False) self.calibration.show() def new_config(self): dr = self.dr_combo.currentIndex() self.compass.set_configuration(dr, True) def cb_mfd(self, data): x, y, z = data inclination = round(180 / math.pi * math.atan2(z, math.hypot(y, x))) heading = math.atan2(y, x) * 180 / math.pi if heading < 0: heading += 360 self.current_mfd_x.value = round(x / 100.0) self.current_mfd_y.value = round(y / 100.0) self.current_mfd_z.value = round(z / 100.0) self.heading_label.setText(round(heading)) self.compass_widget.set_angle(heading) self.inclination_label.setText(inclination) def get_configuration_async(self, conf): self.dr_combo.setCurrentIndex(conf.data_rate) def start(self): async_call(self.compass.get_configuration, None, self.get_configuration_async, self.increase_error_count) self.cbe_mfd.set_period(50) self.plot_widget.stop = False def stop(self): self.cbe_mfd.set_period(0) self.plot_widget.stop = True def destroy(self): pass @staticmethod def has_device_identifier(device_identifier): return device_identifier == BrickletCompass.DEVICE_IDENTIFIER
class App(QWidget): def __init__(self): super().__init__() self.title = 'Extract Videos App' self.left = 10 self.top = 10 self.width = 600 self.height = 300 self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.labl = QLabel(self) # self.labl.setText('abc') self.all_label = QLabel(self) self.video_label = QLabel(self) self.ann_label = QLabel(self) button = QPushButton('Select annotation file', self) button.move(0, 10) button.resize(180, 32) button.clicked.connect(self.on_click) button_video = QPushButton('Select video file', self) button_video.move(0, 50) button_video.resize(180, 32) button_video.clicked.connect(self.video_click) self.info_label1 = QLabel(self) self.info_label1.move(15, 130) self.info_label1.setText( "Select tier from which you want to extract the annotations") button_all = QPushButton('Extract all annotations from tier', self) button_all.move(200, 150) button_all.resize(230, 32) button_all.clicked.connect(self.all_annotations) button_one = QPushButton('Extract one annotation', self) button_one.move(200, 198) button_one.resize(230, 32) button_one.clicked.connect(self.extract_one) self.combo = QComboBox(self) # combo.addItem("Apple") self.combo.move(10, 150) self.combo.activated[str].connect(self.to_print) self.combo_annotations = QComboBox(self) # combo.addItem("Apple") self.combo_annotations.move(10, 200) self.combo_annotations.activated[str].connect(self.only_one_annotation) self.show() @pyqtSlot() def on_click(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( None, "Choose a file", "", "All Files (*);;Python Files (*.py)", options=options) if fileName: self.combo.clear() self.labl.setText(str(fileName)) self.labl.adjustSize() self.labl.move(190, 16) self.file_eaf = pympi.Eaf(file_path=fileName) self.tier_names = self.file_eaf.get_tier_names() for tier_name in self.tier_names: self.combo.addItem(str(tier_name)) def video_click(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( None, "Choose a file", "", "All Files (*);;Python Files (*.py)", options=options) if fileName: self.video_label.setText(str(fileName)) self.video_label.adjustSize() self.video_label.move(190, 57) def to_print(self, text): self.all_label.setText(str(text)) self.all_label.adjustSize() self.all_label.move(200, 150) self.all_label.hide() # add all the annotations to the other combo box my_file = pympi.Eaf(file_path=self.labl.text()) my_annotations = my_file.get_annotation_data_for_tier(str(text)) self.combo_annotations.clear() for annotatio in my_annotations: self.combo_annotations.addItem(str(annotatio[2])) def all_annotations(self): # print(self.all_label.text()) options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog path = QFileDialog.getExistingDirectory( parent=self, caption='Select directory to save extracted videos', ) if path: print(path) selected_file = pympi.Eaf(file_path=self.labl.text()) annotations = selected_file.get_annotation_data_for_tier( self.all_label.text()) video_name = self.video_label.text() count = 0 for annotation in annotations: # t1 = annotation[0]/1000 # t2 = annotation[1]/1000 # input_video_path = video_name # output_video_path = path+'/'+str(annotation[0])+".mp4" # print(output_video_path) # with VideoFileClip(input_video_path) as video: # new = video.subclip(t_start= t1) # new.write_videofile(filename=output_video_path, audio_codec='aac') start = annotation[0] end = annotation[1] print(start / 1000, end / 1000) ffmpeg_extract_subclip(video_name, start / 1000, end / 1000, targetname=path + '/' + str(annotation[2]) + '_' + str(count) + ".mp4") # Comment next line if you don't want to extract the frames for each video # video_to_frames("Data/"+str(gloss)+"/Videos/"+"%#05d.mp4" % (count+1), "Data/"+str(gloss)+"/"+"%#05d" % (count+1) ) count = count + 1 print("FINISHED") def only_one_annotation(self, text): self.ann_label.setText(str(text)) self.ann_label.adjustSize() self.ann_label.move(200, 350) self.ann_label.hide() def extract_one(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog path = QFileDialog.getExistingDirectory( parent=self, caption='Select directory to save extracted video', ) if path: print(path) selected_file = pympi.Eaf(file_path=self.labl.text()) annotations2 = selected_file.get_annotation_data_for_tier( self.all_label.text()) video_name = self.video_label.text() for annotation in annotations2: # print(self.ann_label.text()) if annotation[2] == self.ann_label.text(): start = annotation[0] end = annotation[1] # print(start/1000,end/1000) ffmpeg_extract_subclip(video_name, start / 1000, end / 1000, targetname=path + '/' + str(self.ann_label.text()) + ".mp4")
def __init__(self, **kwargs): super().__init__() main_layout = QHBoxLayout() main_layout.setContentsMargins(20, 0, 20, 0) #(left, top, right, bottom) main_layout.setSpacing(0) h_options = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ] h_select = QComboBox() for option in h_options: h_select.addItem(option) m_options = [ "00", "05", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55" ] m_select = QComboBox() for option in m_options: m_select.addItem(option) space_item = QSpacerItem(20, 20, QSizePolicy.Expanding) am_pm = QComboBox() am_pm.addItem("ص") am_pm.addItem("م") separator = QLabel(" : ") if "value" in kwargs: time_parts = kwargs["value"].split(":") hour = int(time_parts[0]) minute = int(time_parts[1]) minute = self.myround(minute) the_hour, the_period = self.handle_am_pm(hour) ShortTimeWidget.hour_value = str(the_hour) ShortTimeWidget.minute_value = str(minute) ShortTimeWidget.am_pm_value = the_period h_select.setCurrentText(str(the_hour)) m_select.setCurrentText(str(minute)) am_pm.setCurrentText(the_period) else: current_hour = datetime.datetime.now().hour current_minute = datetime.datetime.now().minute current_minute = self.myround(current_minute) the_hour, the_period = self.handle_am_pm(current_hour) h_select.setCurrentText(str(the_hour)) m_select.setCurrentText(str(current_minute)) am_pm.setCurrentText(the_period) ShortTimeWidget.hour_value = str(the_hour) ShortTimeWidget.minute_value = str(current_minute) ShortTimeWidget.am_pm_value = the_period h_select.activated[str].connect(self.update_hour) m_select.activated[str].connect(self.update_minute) am_pm.activated[str].connect(self.update_am_pm) main_layout.addWidget(m_select) main_layout.addWidget(separator) main_layout.addWidget(h_select) main_layout.addSpacerItem(space_item) main_layout.addWidget(am_pm) self.setLayout(main_layout) self.setFixedWidth(200) self.setFixedHeight(37) self.setLayoutDirection(Qt.RightToLeft)