class SearchBox(QLineEdit): search_musics_signal = pyqtSignal(str) searchtype_changed_signal = pyqtSignal(int) def __init__(self, parent=None): super(SearchBox, self).__init__(parent) self.setup_ui() self.create_connections() def create_connections(self): self.returnPressed.connect(self.search_musics) self.searchCombo.currentIndexChanged.connect(self.searchtype_changed_signal.emit) def setup_ui(self): self.setObjectName('searchBox') self.searchButton = QToolButton(clicked = self.search_musics) self.searchButton.setFocusPolicy(Qt.NoFocus) self.searchButton.setIconSize(QSize(21, 21)) self.searchButton.setIcon(QIcon(IconsHub.Search)) self.searchButton.setCursor(Qt.ArrowCursor) self.searchCombo = QComboBox() self.searchCombo.setObjectName('searchCombo') musicIcon = QIcon(IconsHub.SearchMusictitle) artistIcon = QIcon(IconsHub.SearchArtist) albumIcon = QIcon(IconsHub.SearchAlbum) self.searchCombo.setIconSize(QSize(20, 20)) self.searchCombo.insertItem(0, musicIcon, "歌曲") self.searchCombo.insertItem(1, artistIcon, "歌手") self.searchCombo.insertItem(2, albumIcon, "专辑") self.searchCombo.setFixedSize(90, 26) self.searchCombo.setCursor(Qt.ArrowCursor) self.searchCombo.setCurrentIndex(0) searchLayout = QHBoxLayout(self) searchLayout.addWidget(self.searchCombo) searchLayout.addStretch() searchLayout.addWidget(self.searchButton) searchLayout.setSpacing(0) searchLayout.setContentsMargins(0, 0, 2, 0) self.setTextMargins(95, 0, 25, 0) def search_musics(self): self.search_musics_signal.emit(self.text())
class DurationInput(QWidget): def __init__(self, parent): super().__init__(parent) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.input = QLineEdit(self) self.input.setAlignment(Qt.AlignRight) self.input.setValidator(QIntValidator(self.input)) self.input.setText('1') layout.addWidget(self.input, 1) units = ['seconds', 'minutes', 'hours', 'days'] self.unit = QComboBox(self) for i in range(len(units)): self.unit.insertItem(i, units[i]) self.unit.setCurrentIndex(2) #hours layout.addWidget(self.unit, 0) self.setLayout(layout) def getValue(self): multiplier = \ { 'seconds': 1, 'minutes': 60, 'hours' : 60*60, 'days' : 60*60*24 }[self.unit.currentText()] value = decimal.Decimal(self.input.text()) return int(value * multiplier)
class fontWin(QWidget, parent.posClass, parent.win): def __init__(self, font, size): #, screenSize, parPos): super().__init__() self.dim = [720, 480] # self.setGeometry(100, 100, 720, 480) self.layout = QGridLayout() self.sizeBox = QComboBox() self.fontBox = QComboBox() self.sizeBox.setEditable(False) self.fontBox.setEditable(False) self.sizeBox.activated.connect(self.reload) self.fontBox.activated.connect(self.reload) self.sampleText = QTextEdit() self.sampleText.setText( "Please select font size and family, and then close the window.") self.font = QFont() self.font.setFamily(font) self.font.setPointSize(int(size)) self.loadSize() self.sizeBox.setCurrentText(size) self.layout.addWidget(self.sizeBox, 2, 0, 1, 1) self.layout.addWidget(self.fontBox, 2, 4, 1, 3) self.layout.addWidget(self.sampleText, 0, 0, 2, -1) self.setLayout(self.layout) self.loadFonts() self.sampleText.setFont(self.font) self.fontBox.setCurrentText(font) # def updatePos(self, parentPos, parentDim): # pos = self.findPos(parentPos, parentDim, self.dim) # self.setGeometry(pos[0], pos[1], self.dim[0], self.dim[1]) def reload(self): self.font.setFamily(self.fontBox.currentText()) self.font.setPointSize(int(self.sizeBox.currentText())) self.sampleText.setFont(self.font) def loadFonts(self): database = QFontDatabase() for family in database.families(): self.fontBox.insertItem(999999, family) def loadSize(self): for x in range(7, 73): if x % 2 == 0: self.sizeBox.insertItem(100, str(x))
def _create_options(options): """Create a UI combo widget to display a restricted set of options :param options: permitted option values """ widget = QComboBox() for i, option in enumerate(options): widget.insertItem(i, str(option), option) getter = lambda: widget.itemData(widget.currentIndex()) setter = lambda value: widget.setCurrentIndex(widget.findData(value)) controller = WidgetController(getter, setter) widget.activated.connect(lambda value: controller._on_changed()) return widget, controller
class MakeLessExerWindow(QWidget): def __init__(self, mode, msgSignal): super().__init__() self.mode = mode self.msgSignal = msgSignal self.initUI() def initUI(self): grid = QGridLayout() grid.setSpacing(10) self.lessonCb = QComboBox() self.makeItem() grid.addWidget(self.lessonCb, 0, 0) makeBT = QPushButton("make lesson") makeBT.clicked.connect(self.makeLesson) grid.addWidget(makeBT, 1, 0) self.setLayout(grid) self.setWindowTitle("Lesson Exercise") self.setGeometry(700, 400, 150, 50) def makeItem(self): lessonList = WordSpell.getLessonName() index = 0 for item in lessonList: self.lessonCb.insertItem(index, item) index += 1 def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() def makeLesson(self): self.close() lesson = self.lessonCb.currentText() self.lessonUI = LessonWindow(lesson, self.mode, self.msgSignal)
class SearchBox(QLineEdit): search_musics_signal = pyqtSignal(str) searchtype_changed_signal = pyqtSignal(int) def __init__(self, parent=None): super(SearchBox, self).__init__(parent) self.setup_ui() self.create_connections() def create_connections(self): self.returnPressed.connect(self.search_musics) self.searchCombo.currentIndexChanged.connect( self.searchtype_changed_signal.emit) def setup_ui(self): self.setObjectName('searchBox') self.searchButton = QToolButton(clicked=self.search_musics) self.searchButton.setFocusPolicy(Qt.NoFocus) self.searchButton.setIconSize(QSize(21, 21)) self.searchButton.setIcon(QIcon(IconsHub.Search)) self.searchButton.setCursor(Qt.ArrowCursor) self.searchCombo = QComboBox() self.searchCombo.setObjectName('searchCombo') musicIcon = QIcon(IconsHub.SearchMusictitle) artistIcon = QIcon(IconsHub.SearchArtist) albumIcon = QIcon(IconsHub.SearchAlbum) self.searchCombo.setIconSize(QSize(20, 20)) self.searchCombo.insertItem(0, musicIcon, "歌曲") self.searchCombo.insertItem(1, artistIcon, "歌手") self.searchCombo.insertItem(2, albumIcon, "专辑") self.searchCombo.setFixedSize(90, 26) self.searchCombo.setCursor(Qt.ArrowCursor) self.searchCombo.setCurrentIndex(0) searchLayout = QHBoxLayout(self) searchLayout.addWidget(self.searchCombo) searchLayout.addStretch() searchLayout.addWidget(self.searchButton) searchLayout.setSpacing(0) searchLayout.setContentsMargins(0, 0, 2, 0) self.setTextMargins(95, 0, 25, 0) def search_musics(self): self.search_musics_signal.emit(self.text())
class ParamSpinBox(QAbstractSpinBox): # signals valueChanged = pyqtSignal(float) def __init__(self, parent): QAbstractSpinBox.__init__(self, parent) self.fName = "" self.fMinimum = 0.0 self.fMaximum = 1.0 self.fDefault = 0.0 self.fValue = None self.fStep = 0.01 self.fStepSmall = 0.0001 self.fStepLarge = 0.1 self.fIsReadOnly = False self.fScalePoints = None self.fUseScalePoints = False self.fBar = ParamProgressBar(self) self.fBar.setContextMenuPolicy(Qt.NoContextMenu) #self.fBar.show() self.fBox = None self.lineEdit().hide() self.customContextMenuRequested.connect(self.slot_showCustomMenu) self.fBar.valueChanged.connect(self.slot_progressBarValueChanged) QTimer.singleShot(0, self.slot_updateProgressBarGeometry) def setDefault(self, value): value = geFixedValue(self.fName, value, self.fMinimum, self.fMaximum) self.fDefault = value def setMinimum(self, value): self.fMinimum = value self.fBar.setMinimum(value) def setMaximum(self, value): self.fMaximum = value self.fBar.setMaximum(value) def setValue(self, value): value = geFixedValue(self.fName, value, self.fMinimum, self.fMaximum) if self.fValue == value: return False self.fValue = value self.fBar.setValue(value) if self.fUseScalePoints: self._setScalePointValue(value) self.valueChanged.emit(value) self.update() return True def setStep(self, value): if value == 0.0: self.fStep = 0.001 else: self.fStep = value if self.fStepSmall > value: self.fStepSmall = value if self.fStepLarge < value: self.fStepLarge = value self.fBar.fIsInteger = bool(self.fStepSmall == 1.0) def setStepSmall(self, value): if value == 0.0: self.fStepSmall = 0.0001 elif value > self.fStep: self.fStepSmall = self.fStep else: self.fStepSmall = value self.fBar.fIsInteger = bool(self.fStepSmall == 1.0) def setStepLarge(self, value): if value == 0.0: self.fStepLarge = 0.1 elif value < self.fStep: self.fStepLarge = self.fStep else: self.fStepLarge = value def setLabel(self, label): self.fBar.setLabel(label) def setName(self, name): self.fName = name self.fBar.setName(name) def setTextCallback(self, textCall): self.fBar.setTextCall(textCall) def setReadOnly(self, yesNo): self.fIsReadOnly = yesNo self.setButtonSymbols(QAbstractSpinBox.UpDownArrows if yesNo else QAbstractSpinBox.NoButtons) QAbstractSpinBox.setReadOnly(self, yesNo) # FIXME use change event def setEnabled(self, yesNo): self.fBar.setEnabled(yesNo) QAbstractSpinBox.setEnabled(self, yesNo) def setScalePoints(self, scalePoints, useScalePoints): if len(scalePoints) == 0: self.fScalePoints = None self.fUseScalePoints = False return self.fScalePoints = scalePoints self.fUseScalePoints = useScalePoints if not useScalePoints: return # Hide ProgressBar and create a ComboBox self.fBar.close() self.fBox = QComboBox(self) self.fBox.setContextMenuPolicy(Qt.NoContextMenu) #self.fBox.show() self.slot_updateProgressBarGeometry() # Add items, sorted boxItemValues = [] for scalePoint in scalePoints: value = scalePoint['value'] if self.fStep == 1.0: label = "%i - %s" % (int(value), scalePoint['label']) else: label = "%f - %s" % (value, scalePoint['label']) if len(boxItemValues) == 0: self.fBox.addItem(label) boxItemValues.append(value) else: if value < boxItemValues[0]: self.fBox.insertItem(0, label) boxItemValues.insert(0, value) elif value > boxItemValues[-1]: self.fBox.addItem(label) boxItemValues.append(value) else: for index in range(len(boxItemValues)): if value >= boxItemValues[index]: self.fBox.insertItem(index+1, label) boxItemValues.insert(index+1, value) break if self.fValue is not None: self._setScalePointValue(self.fValue) self.fBox.currentIndexChanged['QString'].connect(self.slot_comboBoxIndexChanged) def stepBy(self, steps): if steps == 0 or self.fValue is None: return value = self.fValue + (self.fStep * steps) if value < self.fMinimum: value = self.fMinimum elif value > self.fMaximum: value = self.fMaximum self.setValue(value) def stepEnabled(self): if self.fIsReadOnly or self.fValue is None: return QAbstractSpinBox.StepNone if self.fValue <= self.fMinimum: return QAbstractSpinBox.StepUpEnabled if self.fValue >= self.fMaximum: return QAbstractSpinBox.StepDownEnabled return (QAbstractSpinBox.StepUpEnabled | QAbstractSpinBox.StepDownEnabled) def updateAll(self): self.update() self.fBar.update() if self.fBox is not None: self.fBox.update() def resizeEvent(self, event): QAbstractSpinBox.resizeEvent(self, event) self.slot_updateProgressBarGeometry() @pyqtSlot(str) def slot_comboBoxIndexChanged(self, boxText): if self.fIsReadOnly: return value = float(boxText.split(" - ", 1)[0]) lastScaleValue = self.fScalePoints[-1]['value'] if value == lastScaleValue: value = self.fMaximum self.setValue(value) @pyqtSlot(float) def slot_progressBarValueChanged(self, value): if self.fIsReadOnly: return if value <= self.fMinimum: realValue = self.fMinimum elif value >= self.fMaximum: realValue = self.fMaximum else: curStep = int((value - self.fMinimum) / self.fStep + 0.5) realValue = self.fMinimum + (self.fStep * curStep) if realValue < self.fMinimum: realValue = self.fMinimum elif realValue > self.fMaximum: realValue = self.fMaximum self.setValue(realValue) @pyqtSlot() def slot_showCustomMenu(self): clipboard = QApplication.instance().clipboard() pasteText = clipboard.text() pasteValue = None if pasteText: try: pasteValue = float(pasteText) except: pass menu = QMenu(self) actReset = menu.addAction(self.tr("Reset (%f)" % self.fDefault)) actRandom = menu.addAction(self.tr("Random")) menu.addSeparator() actCopy = menu.addAction(self.tr("Copy (%f)" % self.fValue)) if pasteValue is None: actPaste = menu.addAction(self.tr("Paste")) actPaste.setEnabled(False) else: actPaste = menu.addAction(self.tr("Paste (%f)" % pasteValue)) menu.addSeparator() actSet = menu.addAction(self.tr("Set value...")) if self.fIsReadOnly: actReset.setEnabled(False) actRandom.setEnabled(False) actPaste.setEnabled(False) actSet.setEnabled(False) actSel = menu.exec_(QCursor.pos()) if actSel == actReset: self.setValue(self.fDefault) elif actSel == actRandom: value = random() * (self.fMaximum - self.fMinimum) + self.fMinimum self.setValue(value) elif actSel == actCopy: clipboard.setText("%f" % self.fValue) elif actSel == actPaste: self.setValue(pasteValue) elif actSel == actSet: dialog = CustomInputDialog(self, self.fName, self.fValue, self.fMinimum, self.fMaximum, self.fStep, self.fScalePoints) if dialog.exec_(): value = dialog.returnValue() self.setValue(value) @pyqtSlot() def slot_updateProgressBarGeometry(self): self.fBar.setGeometry(self.lineEdit().geometry()) if self.fUseScalePoints: self.fBox.setGeometry(self.lineEdit().geometry()) def _getNearestScalePoint(self, realValue): finalValue = 0.0 for i in range(len(self.fScalePoints)): scaleValue = self.fScalePoints[i]["value"] if i == 0: finalValue = scaleValue else: srange1 = abs(realValue - scaleValue) srange2 = abs(realValue - finalValue) if srange2 > srange1: finalValue = scaleValue return finalValue def _setScalePointValue(self, value): value = self._getNearestScalePoint(value) for i in range(self.fBox.count()): if float(self.fBox.itemText(i).split(" - ", 1)[0]) == value: self.fBox.setCurrentIndex(i) break
def askSessionFromUser(self): ''' @return: QString ''' self._fillSessionsMetaDataListIfNeeded() dialog = QDialog(gVar.app.getWindow(), Qt.WindowStaysOnTopHint) label = QLabel(_('Please select the startup session:'), dialog) comboBox = QComboBox(dialog) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, dialog) buttonBox.accepted.connect(dialog.accept) buttonBox.rejected.connect(dialog.reject) layout = QVBoxLayout() layout.addWidget(label) layout.addWidget(comboBox) layout.addWidget(buttonBox) dialog.setLayout(layout) lastActiveSessionFileInfo = QFileInfo(self._lastActiveSessionPath) for metaData in self._sessionsMetaDataList: if QFileInfo(metaData.filePath) != lastActiveSessionFileInfo: comboBox.addItem(metaData.name, metaData.filePath) else: comboBox.insertItem(0, _('%s (last session)') % metaData.name, metaData.filePath) comboBox.setCurrentIndex(0) if dialog.exec_() == QDialog.Accepted: self._lastActiveSessionPath = comboBox.currentData() return self._lastActiveSessionPath
class fontWin(QWidget): closed = pyqtSignal() def __init__(self, font, size): super().__init__() self.setGeometry(100, 100, 720, 480) self.layout = QGridLayout() self.sizeBox = QComboBox() self.fontBox = QComboBox() self.sizeBox.setEditable(False) self.fontBox.setEditable(False) self.sizeBox.activated.connect(self.reload) self.fontBox.activated.connect(self.reload) self.sampleText = QTextEdit() self.sampleText.setText("The quick brown fox jumps over the lazy dog.") self.font = QFont() self.font.setFamily(font) self.font.setPointSize(int(size)) self.loadSize() self.sizeBox.setCurrentText(size) self.layout.addWidget(self.sizeBox, 2, 0, 1, 1) self.layout.addWidget(self.fontBox, 2, 4, 1, 3) self.layout.addWidget(self.sampleText, 0, 0, 2, -1) self.setLayout(self.layout) self.loadFonts() self.sampleText.setFont(self.font) self.fontBox.setCurrentText(font) def closeEvent(self, event): self.closed.emit() self.close() def reload(self): self.font.setFamily(self.fontBox.currentText()) self.font.setPointSize(int(self.sizeBox.currentText())) self.sampleText.setFont(self.font) def loadFonts(self): database = QFontDatabase() for family in database.families(): self.fontBox.insertItem(999999, family) def loadSize(self): for x in range(7, 73): if x % 2 == 0: self.sizeBox.insertItem(100, str(x))
class MainWindow(QWidget): def __init__(self): super().__init__() # We need to instantiate a "private" variable and define getters # and setters on it for QT databinding to work properly. self._n = 0 self.initUI() @property def n(self): return self._n @n.setter def n(self, value): self.button.setText(str(value)) self.progressBar.setValue(value) self._n = value def initUI(self): self.setGeometry(600, 600, 600, 600) layoutGrid = QGridLayout(self) # Basic Button Functionality self.button = QPushButton(str(self.n), self) self.button.clicked.connect(self.buttonClicked) layoutGrid.addWidget(self.button, 1, 1) # Progress Bar self.progressBar = QProgressBar(self) self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) layoutGrid.addWidget(self.progressBar, 1, 2) # Dropdown self.dropDownMenu = QComboBox(self) self.entries = ["qtdemo/screenshot1.png", "qtdemo/screenshot2.png"] for i in range(len(self.entries)): self.dropDownMenu.insertItem(i, self.entries[i]) self.dropDownMenu.currentIndexChanged.connect(self.updateImage) layoutGrid.addWidget(self.dropDownMenu, 1, 0) # Images self.img = QLabel(self) pixmap = QPixmap(self.entries[0]) self.img.setPixmap(pixmap) layoutGrid.addWidget(self.img, 0, 0) # Show the window self.show() def buttonClicked(self, event): self.n = self.n + 1 def updateImage(self, newIndex): pixmap = QPixmap(self.entries[newIndex]) self.img.setPixmap(pixmap)
class ChannelWidget(QGroupBox): def __init__(self, channel: Channel, sgn_mng: SignageManager): super().__init__() self._channel = channel self._sgn_mng = sgn_mng self._label = QLabel() self._cbox_signages = QComboBox() self.init_ui() def load_data_on_ui(self) -> None: self._cbox_signages.clear() sgn = self._channel.signage signage_texts = list() curr_sgn_idx = 0 for sgn_id in self._sgn_mng.signages.keys(): if sgn_id == sgn.id: curr_sgn_idx = len(signage_texts) signage = self._sgn_mng.get_signage(sgn_id) signage_texts.append(utils.gen_ui_text(signage.title, signage.id)) self._cbox_signages.addItem(signage_texts[curr_sgn_idx]) for sgn_text in reversed(signage_texts[:curr_sgn_idx]): self._cbox_signages.insertItem(0, sgn_text) for sgn_text in signage_texts[curr_sgn_idx + 1:]: self._cbox_signages.addItem(sgn_text) label_text = "Number of connections: " + str( self._channel.request_connection_count()) self._label.setText(label_text) def init_ui(self) -> None: self.setTitle(self._channel.id) signage_texts = list() for sgn_id in self._sgn_mng.signages.keys(): signage = self._sgn_mng.get_signage(sgn_id) signage_texts.append(utils.gen_ui_text(signage.title, signage.id)) self._cbox_signages.addItems(signage_texts) self._cbox_signages.currentIndexChanged.connect(self._signage_changed) vbox_outmost = QVBoxLayout() vbox_outmost.addWidget(self._label) vbox_outmost.addWidget(self._cbox_signages) self.setLayout(vbox_outmost) def _signage_changed(self): sgn_id = utils.ui_text_to_id(self._cbox_signages.currentText()) if not sgn_id: return self._channel.signage = self._sgn_mng.get_signage(sgn_id)
def __init__(self, app_context: ApplicationContext, flashcard_manager: FlashcardManager, *args, **kwargs): super(CardListWindow, self).__init__(*args, **kwargs) self.app_context = app_context self.flashcard_manager = flashcard_manager self.current_language = Language(0) self.setFixedSize(400, 600) self.setWindowTitle("Meine Lernkarteien - TangoCards") main_widget = QWidget() main_widget.setProperty("cssClass", "background") main_layout = QVBoxLayout() # Initialized up here because the combobox already fires the currentIndexChanged signal on creation self.card_list_model = QStringListModel(self.flashcard_manager.get_flashcard_list_names(self.current_language)) self.card_list = QListView() self.card_list.setEditTriggers(QAbstractItemView.NoEditTriggers) self.card_list.doubleClicked.connect(self.on_list_doubleclick) language_select = QComboBox() language_select.currentIndexChanged.connect(self.on_select_language) for language in Language: # if len(self.flashcard_manager.get_flashcard_lists(language)) < 1: # continue language_select.insertItem(language.value, language.get_display_name(), language.value) language_select.setItemIcon(language.value, QIcon(app_context.get_resource("icons/flag_" + language.name + ".png"))) main_layout.addWidget(language_select) main_layout.addWidget(self.card_list) tool_buttons_widget = QWidget() tool_buttons_layout = QHBoxLayout() tool_buttons_widget.setLayout(tool_buttons_layout) learn_button = QPushButton("Lernen") learn_button.clicked.connect(self.on_click_learn) add_button = QPushButton("Hinzufügen") add_button.clicked.connect(self.on_click_add) delete_button = QPushButton("Löschen") delete_button.clicked.connect(self.on_click_delete) tool_buttons_layout.addWidget(learn_button) tool_buttons_layout.addWidget(add_button) tool_buttons_layout.addWidget(delete_button) main_layout.addWidget(tool_buttons_widget) main_widget.setLayout(main_layout) self.setCentralWidget(main_widget)
def createEditor(self, parent, option, index): editor = QComboBox(parent) editor.currentIndexChanged.connect(editor.clearFocus) colorNames = QColor().colorNames() for i in range(len(colorNames)): color = QColor(colorNames[i]) editor.insertItem(i, colorNames[i]) editor.setItemData(i, color, Qt.DecorationRole) return editor
def display_ports(ports: typing.List[QtSerialPort.QSerialPortInfo], combo: QComboBox) -> typing.Dict[str, str]: known_keys = set() remove_indices = [] was_empty = combo.count() == 0 def make_description(p: QtSerialPort.QSerialPortInfo) -> str: out = f'{p.portName()}: {p.manufacturer() or "Unknown vendor"} - {p.description() or "Unknown product"}' if p.serialNumber().strip(): out += ' #' + str(p.serialNumber()) return out description_location_mapping = {} description_icon_mapping = {} for x in ports: desc = make_description(x) icon = _get_port_icon(x) description_location_mapping[desc] = x.systemLocation() if icon: description_icon_mapping[desc] = icon # Marking known and scheduling for removal for idx in itertools.count(): tx = combo.itemText(idx) if not tx: break known_keys.add(tx) if tx not in description_location_mapping: _logger.debug('Removing port %r', tx) remove_indices.append(idx) # Removing - starting from the last item in order to retain indexes for idx in remove_indices[::-1]: combo.removeItem(idx) # Adding new items - starting from the last item in order to retain the final order for key in list(description_location_mapping.keys())[::-1]: if key not in known_keys: _logger.debug('Adding port %r', key) try: combo.insertItem(0, description_icon_mapping[key], key) except KeyError: combo.insertItem(0, key) # Updating selection if was_empty: combo.setCurrentIndex(0) return description_location_mapping
class HistoryAnalysisUI(QWidget): def __init__(self, ssq, title): super().__init__() self.ssq = ssq self.title = title self.initUI() def initUI(self): self.periodCb = QComboBox() self.makeItem() self.analysisBt = QPushButton("分析") self.analysisBt.clicked.connect(self.analysis) grid = QGridLayout() grid.setSpacing(10) grid.addWidget(self.periodCb, 0, 0) grid.addWidget(self.analysisBt, 0, 1) self.setLayout(grid) self.move(200, 400) self.setWindowTitle(self.title) def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() def analysis(self): period = int(self.periodCb.currentText()) text = self.ssq.historyAnalysis(period) self.showUI = ShowWindow(text, "往期分析") self.showUI.show() def getItem(self): itemList = [] for key in self.ssq.record.keys(): itemList.append(str(key)) if len(itemList) == 50: break return itemList def makeItem(self): index = 0 itemList = self.getItem() for item in itemList: self.periodCb.insertItem(index, item) index += 1
def g_type_combobox(self, type_str, root=False): cb = QComboBox() items = [list, dict] if not root: items.append(self.lang.node_none) for item in [str, int, bool, None.__class__]: items.append(item) items = [type_map.get(item, item) for item in items] for index, item in enumerate(items): if item == self.lang.node_none: cb.insertSeparator(index) else: cb.insertItem(index, item) cb.setCurrentText(type_str) return cb
class PortSelector(QWidget): tty_pfxs = ("ttyUSB",) def __init__(self, *args): QWidget.__init__(self, *args) self.setLayout(QHBoxLayout()) self.layout().setContentsMargins(0,0,0,0) self._combo = QComboBox() self._button = QPushButton("...") self.layout().addWidget(self._combo, 1) self.layout().addWidget(self._button, 0) self.rescan() self.connect(self._button, QtCore.SIGNAL("clicked()"), self.show_prompt) def value(self): return self._combo.itemText(self._combo.currentIndex()) def set_value(self, text): found = False for i in range(self._combo.count()): if self._combo.itemText(i) == text: self._combo.setCurrentIndex(i) found = True break if not found: self.set_custom(text) def set_custom(self, text): if self._custom_port: self._combo.removeItem(0) self._combo.insertItem(0, text) self._combo.setCurrentIndex(0) self._custom_port = True def show_prompt(self): text, ok = QInputDialog.getText(self, "Custom entry", "Port", text="/dev/") if ok: self.set_custom(text) def rescan(self): self._combo.clear() self._custom_port = False for x in os.listdir("/dev/"): for y in self.tty_pfxs: if x[:len(y)] == y: self._combo.addItem("/dev/" + x) break
def add_row(self): _row_position = self.composition_table.rowCount() self.composition_table.insertRow(_row_position) _element_editor = QComboBox() _element_editor.setStyleSheet('QComboBox {border: 0px ;} ') for index, element in enumerate(CompositionGroupBox._element_dict): _element_editor.insertItem(index, element) # Could use a default style? e.g.: # _element_editor.setStyle(QStyleFactory.create('Cleanlooks')) # Block composition_table signals while setting the cells self.composition_table.blockSignals(True) self.composition_table.setCellWidget(_row_position, 0, _element_editor) _element_editor.setCurrentIndex(30) # No need to set default here # self.composition_table.setItem(_row_position , 0, QTableWidgetItem('Ga')) self.composition_table.setItem(_row_position, 1, QTableWidgetItem('31')) self.composition_table.setItem(_row_position, 2, QTableWidgetItem('0')) self.composition_table.setItem(_row_position, 3, QTableWidgetItem('1')) # Re-enable signals self.composition_table.blockSignals(False) self.composition_table.item( _row_position, 1).setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.composition_table.item( _row_position, 1).setTextAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.composition_table.item(_row_position, 1).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.composition_table.item(_row_position, 2).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.composition_table.item(_row_position, 3).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter) # Create Signal _element_editor.currentIndexChanged.connect(self.update_cb_val) self.update_mass_density()
def init_UI(self): vbox = QVBoxLayout(self) hbox = QHBoxLayout() vbox.addLayout(hbox) button = QPushButton("Turn on\ngenerator") button.setProperty("turn_on", self.state) button.clicked.connect(self._turn) generator_type = QComboBox(self) current_indx = 0 for i, key in enumerate(GENERATOR_FACTORY.keys()): generator_type.insertItem(i, key) if self.settings.last_generator == key: current_indx = i vbox_1 = QVBoxLayout() vbox_1.addWidget(generator_type) vbox_1.addWidget(self._create_reset()) hbox.addLayout(vbox_1, 1) hbox.addWidget(button, 1) generator_type.currentIndexChanged.connect( lambda x: self.change_generator(generator_type.itemText(x))) generator_type.setCurrentIndex(current_indx) vbox.addWidget(self.current_generator) def turn(state): generator_type.setDisabled(state) button.setProperty("turn_on", state) update_style(button) if state: button.setText("Turn off\ngenerator") self.current_generator.start() else: button.setText("Turn on\ngenerator") self.current_generator.stop() if self.settings.auto_reset_generator: self.device.reset_value() self.state_signal.connect(turn)
class AppSettingsGroupBox(QGroupBox): def __init__(self, preferences): super(AppSettingsGroupBox, self).__init__() self.setTitle('Application Options') self.setAlignment(Qt.AlignLeft) self.setStyleSheet( 'GroupBox::title{subcontrol-origin: margin; subcontrol-position: top left;}' ) self.create_widgets() self.set_data(preferences) self.style_widgets() self.create_layout() def create_widgets(self): self.log_mode_label = QLabel('Log mode: ') self.log_mode_input = QComboBox() self.log_mode_input.insertItem(0, 'Append') self.log_mode_input.insertItem(1, 'Overwrite') def set_data(self, preferences): self.log_mode_input.setCurrentIndex(1 - preferences['append_log_mode']) def style_widgets(self): self.log_mode_label.setAlignment(Qt.AlignVCenter | Qt.AlignLeft) self.log_mode_input.setMaximumWidth(95) def create_layout(self): self.main_layout = QVBoxLayout() self.main_layout.setContentsMargins(20, 10, 20, 7) self.main_layout.setSpacing(25) self.grid_layout = QGridLayout() self.grid_layout.setSpacing(15) self.grid_layout.addWidget(self.log_mode_label, 0, 0) self.grid_layout.addWidget(self.log_mode_input, 0, 1) self.main_layout.addLayout(self.grid_layout) self.setLayout(self.main_layout)
class LateralPanel(QWidget): def __init__(self, explorer): super(LateralPanel, self).__init__() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.addWidget(explorer) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) self.labelText = "Ln: %s, Col: %s" self.labelCursorPosition = QLabel(_translate("LateralPanel", self.labelText % (0, 0))) hbox.addWidget(self.labelCursorPosition) self.combo = QComboBox() ui_tools.ComboBoxButton(self.combo, self.combo.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.combo.setToolTip(_translate("LateralPanel", "Select the item from the Paste " "Historial list.\nYou can Copy items into this list with: " "%s\nor Paste them using: %s") % (resources.get_shortcut("History-Copy").toString( QKeySequence.NativeText), resources.get_shortcut("History-Paste").toString( QKeySequence.NativeText))) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox.addWidget(self.combo) vbox.addLayout(hbox) def update_line_col(self, line, col): self.labelCursorPosition.setText(_translate("LateralPanel", self.labelText % (line, col))) def add_new_copy(self, copy): self.combo.insertItem(0, copy) self.combo.setCurrentIndex(0) if self.combo.count() > settings.COPY_HISTORY_BUFFER: self.combo.removeItem(self.combo.count() - 1) def get_paste(self): return self.combo.currentText()
class LateralPanel(QWidget): splitEditor = pyqtSignal('QObject*', 'QObject*', bool) closeSplit = pyqtSignal(QWidget) def __init__(self, parent=None): super(LateralPanel, self).__init__(parent) self.has_component = False self.vbox = QVBoxLayout(self) self.vbox.setContentsMargins(0, 0, 0, 0) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 5, 5) self.combo = QComboBox() ui_tools.ComboBoxButton(self.combo, self.combo.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.combo.setToolTip(self.tr("Select the item from the Paste " "History list.\nYou can Copy items into this list with: " "%s\nor Paste them using: %s") % (resources.get_shortcut("History-Copy").toString( QKeySequence.NativeText), resources.get_shortcut("History-Paste").toString( QKeySequence.NativeText))) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox.addWidget(self.combo) self.vbox.addLayout(hbox) def add_component(self, widget): self.vbox.insertWidget(0, widget) self.has_component = True def add_new_copy(self, copy): self.combo.insertItem(0, copy) self.combo.setCurrentIndex(0) if self.combo.count() > settings.COPY_HISTORY_BUFFER: self.combo.removeItem(self.combo.count() - 1) def get_paste(self): return self.combo.currentText()
class MainWindow(QDialog): def __init__(self): super().__init__() self.m_modVal = [0, 1, 2, 3, 4, 8, 0x24, 0x26, 0x43, 0X46, 0x82] self.fskCounter = 0 self.ofdmCounter = 0 self.oqpskCounter = 0 self.pkt_rssi = 0 self.noiseFloor = 0 self.m_serialPort = serialPort.serialPort() self.m_spectrumAnalyzer = spectrumAnalyzer.spectrumAnalyzer() self.m_signalGenerator = signalGenerator.signalGenerator() self.m_txContainerWidget = QWidget( self) # container for widgets in tx box self.m_connectPort = QPushButton("Connect", self.m_txContainerWidget) self.m_disconnectPort = QPushButton("Disconnect", self.m_txContainerWidget) self.m_disconnectPort.setEnabled(False) self.m_txMod = QComboBox( self.m_txContainerWidget) # tx modulation selection self.psdulen = QLineEdit(self.m_txContainerWidget) # psdu length self.m_txFreq = QLineEdit(self.m_txContainerWidget) # tx frequency self.m_txPower = QComboBox( self.m_txContainerWidget) # tx power selection self.m_numOfPacket = QLineEdit( self.m_txContainerWidget) # tx number of packets self.m_gap = QLineEdit(self.m_txContainerWidget) # tx interpacket gap self.m_txLoopEnable = QCheckBox( "Loop test", self.m_txContainerWidget) # tx loop test section self.m_txFreqOffsetEnable = QCheckBox("Freq offset", self.m_txContainerWidget) self.m_txFreqStop = QLineEdit(self.m_txContainerWidget) self.m_txFreqStep = QLineEdit(self.m_txContainerWidget) self.m_txPowerStop = QComboBox(self.m_txContainerWidget) self.m_txPowerStep = QComboBox(self.m_txContainerWidget) self.m_testMode = QCheckBox("Test mode", self.m_txContainerWidget) # tx test mode self.m_txContinuous = QCheckBox("Continuous", self.m_txContainerWidget) self.m_txCW = QCheckBox("CW", self.m_txContainerWidget) self.m_ant = QComboBox(self.m_txContainerWidget) self.m_txStart = QPushButton("Start TX", self.m_txContainerWidget) self.m_txStop = QPushButton("Stop TX", self.m_txContainerWidget) self.m_txACLR = QPushButton("ACLR test", self.m_txContainerWidget) self.txGroupBox = QGroupBox("Tx", self) self.m_rxContainerWidget = QWidget(self) self.rxGroupBox = QGroupBox("Rx", self) self.m_rxFreq = QLineEdit(self.m_rxContainerWidget) self.m_rxLoopEnable = QCheckBox("Loop test", self.m_rxContainerWidget) self.m_rxTestMode = QCheckBox("Test mode", self.m_rxContainerWidget) self.m_rxFreqStop = QLineEdit(self.m_rxContainerWidget) self.m_rxFreqStep = QLineEdit(self.m_rxContainerWidget) self.m_rxPowerStart = QLineEdit(self.m_rxContainerWidget) self.m_rxPowerStop = QLineEdit(self.m_rxContainerWidget) self.m_rxPowerStep = QLineEdit(self.m_rxContainerWidget) self.m_cableLoss = QLineEdit(self.m_rxContainerWidget) self.m_rssiRequest = QPushButton( "Noise floor", self.m_rxContainerWidget) # RSSI request, disabled by default self.m_rssi = QLineEdit(self.m_rxContainerWidget) self.m_rxConfig = QPushButton( "Start Rx", self.m_rxContainerWidget) # rx config and RSSI loop test self.m_fskCounter = QLineEdit(self.m_rxContainerWidget) self.m_ofdmCounter = QLineEdit(self.m_rxContainerWidget) self.m_oqpskCounter = QLineEdit(self.m_rxContainerWidget) self.m_pkt_rssi = QLineEdit(self.m_rxContainerWidget) self.m_FSK150k = QCheckBox("FSK150k", self.m_rxContainerWidget) self.m_OFDM200k = QCheckBox("OFDM200k", self.m_rxContainerWidget) self.m_OFDM600k = QCheckBox("OFDM600k", self.m_rxContainerWidget) self.m_LR125k = QCheckBox("LR12.5k", self.m_rxContainerWidget) self.m_SSNFSK100k = QCheckBox("SSNFSK100k", self.m_rxContainerWidget) self.m_SSNFSK150k = QCheckBox("SSNFSK150k", self.m_rxContainerWidget) self.m_SSNGFSK150k = QCheckBox("SSNGFSK150k", self.m_rxContainerWidget) self.m_SSNGFSK200k = QCheckBox("SSNGFSK200k", self.m_rxContainerWidget) self.m_SSNGFSK300k = QCheckBox("SSNGFSK300k", self.m_rxContainerWidget) self.m_OFDM1200k = QCheckBox("OFDM1200k", self.m_rxContainerWidget) self.m_OFDM2400k = QCheckBox("OFDM2400k", self.m_rxContainerWidget) self.m_packets = QLineEdit(self.m_rxContainerWidget) self.m_sensitivity = QPushButton("Sensitivity", self.m_rxContainerWidget) self.m_rssiSweep = QPushButton("RSSI sweep", self.m_rxContainerWidget) self.setWindowTitle("RF_PHY") self.createTxBox() self.createRxBox() """ Toolbar section for equipments """ m_toolbars = QToolBar() m_sa_panel = QAction("Spectrum analyzer", self) m_toolbars.addAction(m_sa_panel) m_sa_panel.triggered.connect(lambda: self.m_spectrumAnalyzer.show()) m_sg_panel = QAction("Signal generator", self) m_toolbars.addAction(m_sg_panel) m_toolbars.setMovable(False) m_toolbars.addSeparator() m_sg_panel.triggered.connect(lambda: self.m_signalGenerator.show()) main_layout = QGridLayout() main_layout.addWidget(m_toolbars) main_layout.addWidget(self.txGroupBox, 1, 0) main_layout.addWidget(self.rxGroupBox, 1, 1) self.setLayout(main_layout) """ delete objects on closing in destructor """ def closeEvent(self, event): del self.m_serialPort # close serial ports if open del self.m_spectrumAnalyzer del self.m_signalGenerator ''' Create Tx management Box ''' def createTxBox(self): m_txFormLayout = QFormLayout(self.m_txContainerWidget) m_txConnectDisconnectHBox = QHBoxLayout(self.m_txContainerWidget) m_txConnectDisconnectHBox.addWidget(self.m_connectPort) m_txConnectDisconnectHBox.addWidget(self.m_disconnectPort) m_txFormLayout.addRow(m_txConnectDisconnectHBox) self.m_txMod.insertItem(0, "SSN_FSK_100") # 300KHz spacing self.m_txMod.insertItem(1, "SSN_FSK_150") self.m_txMod.insertItem(2, "SSN_GFSK_150") # 300KHz spacing self.m_txMod.insertItem(3, "SSN_GFSK_200") self.m_txMod.insertItem(4, "SSN_GFSK_300") self.m_txMod.insertItem(5, "MRFSK150") self.m_txMod.insertItem(6, "OFDM_OPT1_MCS4") # 1200KHz spacing self.m_txMod.insertItem(7, "OFDM_OPT1_MCS6") # 1200KHz spacing self.m_txMod.insertItem(8, "OFDM_OPT3_MCS3") self.m_txMod.insertItem(9, "OFDM_OPT3_MCS6") self.m_txMod.insertItem(10, "OQPSK12.5") m_txFormLayout.addRow("Modulation", self.m_txMod) self.psdulen.insert("32") self.psdulen.setEnabled(False) m_txFormLayout.addRow("Packet length (B)", self.psdulen) self.m_txFreq.insert("902") m_txFormLayout.addRow("Frequency (MHz)", self.m_txFreq) for i in range(61): self.m_txPower.insertItem(i, str(i) + "*0.5") self.m_txPower.setCurrentIndex(25) m_txFormLayout.addRow("Power(dBm)", self.m_txPower) self.m_numOfPacket.insert("1") self.m_numOfPacket.setEnabled(False) m_txFormLayout.addRow("Number of packets", self.m_numOfPacket) self.m_gap.insert("100") self.m_gap.setEnabled(False) m_txFormLayout.addRow("Gap (ms)", self.m_gap) m_loopEnableBox = QHBoxLayout(self.m_txContainerWidget) m_loopEnableBox.addWidget(self.m_txLoopEnable) m_loopEnableBox.addWidget(self.m_txFreqOffsetEnable) m_txFormLayout.addRow(m_loopEnableBox) self.m_txFreqStop.insert("928") m_txFormLayout.addRow("Stop Frequency (MHz)", self.m_txFreqStop) self.m_txFreqStep.insert("1") m_txFormLayout.addRow("Frequency step (MHz)", self.m_txFreqStep) for i in range(59): self.m_txPowerStop.insertItem(i, str(i) + "*0.5") self.m_txPowerStop.setCurrentIndex(25) m_txFormLayout.addRow("Stop Power (dBm)", self.m_txPowerStop) for i in range(6): self.m_txPowerStep.insertItem(i, str(1 << i) + "*0.5") m_txFormLayout.addRow("Power Step (dB)", self.m_txPowerStep) self.m_txFreqStop.setEnabled(False) self.m_txFreqStep.setEnabled(False) self.m_txPowerStop.setEnabled(False) self.m_txPowerStep.setEnabled(False) self.m_testMode.setChecked(True) m_txFormLayout.addRow(self.m_testMode) m_testModeHBox2 = QHBoxLayout(self.m_txContainerWidget) m_testModeHBox2.addWidget(self.m_txContinuous) m_testModeHBox2.addWidget(self.m_txCW) m_txFormLayout.addRow(m_testModeHBox2) for i in range(2): self.m_ant.insertItem(i, str(i)) m_txFormLayout.addRow("ANT", self.m_ant) self.m_ant.setEnabled(False) self.m_txStart.setEnabled(False) self.m_txStop.setEnabled(False) m_startStopTxHBox = QHBoxLayout(self.m_txContainerWidget) m_startStopTxHBox.addWidget(self.m_txStart) m_startStopTxHBox.addWidget(self.m_txStop) m_txFormLayout.addRow(m_startStopTxHBox) self.m_txACLR.setEnabled(False) m_txFormLayout.addRow(self.m_txACLR) self.txGroupBox.setLayout(m_txFormLayout) self.m_connectPort.clicked.connect( lambda: self.m_serialPort.slot_connect(self)) self.m_disconnectPort.clicked.connect( lambda: self.m_serialPort.slot_disconnect(self)) self.m_txLoopEnable.stateChanged.connect( lambda: self.slot_txLoopEnable()) self.m_testMode.stateChanged.connect( lambda: self.slot_txTestModeEnable()) self.m_txStart.clicked.connect(lambda: self.m_serialPort.slot_startTx( self, self.m_spectrumAnalyzer)) self.m_txStop.clicked.connect(lambda: self.m_serialPort.slot_stopTx()) self.m_txACLR.clicked.connect(lambda: self.m_serialPort.slot_startACLR( self, self.m_spectrumAnalyzer)) ''' Create Rx management Box ''' def createRxBox(self): m_rxFormLayout = QFormLayout(self.m_rxContainerWidget) self.m_rxFreq.insert("902") m_rxFormLayout.addRow("Frequency (MHz)", self.m_rxFreq) m_loopEnableBox = QHBoxLayout(self.m_rxContainerWidget) m_loopEnableBox.addWidget(self.m_rxLoopEnable) m_loopEnableBox.addWidget(self.m_rxTestMode) m_rxFormLayout.addRow(m_loopEnableBox) self.m_rxFreqStop.insert("928") m_rxFormLayout.addRow("Stop Frequency (MHz)", self.m_rxFreqStop) self.m_rxFreqStep.insert("1") m_rxFormLayout.addRow("Frequency step (MHz)", self.m_rxFreqStep) self.m_rxPowerStart.insert("-100") m_rxFormLayout.addRow("Start Power (dBm)", self.m_rxPowerStart) self.m_rxPowerStop.insert("0") m_rxFormLayout.addRow("Stop Power (dBm)", self.m_rxPowerStop) self.m_rxPowerStep.insert("10") m_rxFormLayout.addRow("Step Power (dBm)", self.m_rxPowerStep) self.m_cableLoss.insert("12") m_rxFormLayout.addRow("Cable Loss (dB)", self.m_cableLoss) self.m_rxFreqStop.setEnabled(False) self.m_rxFreqStep.setEnabled(False) self.m_rxPowerStart.setEnabled(False) self.m_rxPowerStop.setEnabled(False) self.m_rxPowerStep.setEnabled(False) self.m_cableLoss.setEnabled(False) self.m_rssiRequest.setEnabled(False) m_RSSIHBox = QHBoxLayout(self.m_rxContainerWidget) m_RSSIHBox.addWidget(self.m_rssiRequest) m_RSSIHBox.addWidget(self.m_rssi) m_rxFormLayout.addRow(m_RSSIHBox) self.m_rxConfig.setEnabled(False) m_rxFormLayout.addRow(self.m_rxConfig) self.m_fskCounter.insert("0") self.m_fskCounter.setEnabled(False) m_rxFormLayout.addRow("FSK", self.m_fskCounter) self.m_ofdmCounter.insert("0") self.m_ofdmCounter.setEnabled(False) m_rxFormLayout.addRow("OFDM", self.m_ofdmCounter) self.m_oqpskCounter.insert("0") self.m_oqpskCounter.setEnabled(False) m_rxFormLayout.addRow("OQPSK", self.m_oqpskCounter) self.m_pkt_rssi.insert("0") self.m_pkt_rssi.setEnabled(False) m_rxFormLayout.addRow("RSSI", self.m_pkt_rssi) self.m_FSK150k.setChecked(True) m_modHBox1 = QHBoxLayout(self.m_rxContainerWidget) m_modHBox1.addWidget(self.m_FSK150k) m_modHBox1.addWidget(self.m_OFDM200k) m_modHBox1.addWidget(self.m_OFDM600k) m_rxFormLayout.addRow(m_modHBox1) m_modHBox2 = QHBoxLayout(self.m_rxContainerWidget) m_modHBox2.addWidget(self.m_LR125k) m_modHBox2.addWidget(self.m_SSNFSK100k) m_modHBox2.addWidget(self.m_SSNFSK150k) m_rxFormLayout.addRow(m_modHBox2) m_modHBox3 = QHBoxLayout(self.m_rxContainerWidget) m_modHBox3.addWidget(self.m_SSNGFSK150k) m_modHBox3.addWidget(self.m_SSNGFSK200k) m_modHBox3.addWidget(self.m_SSNGFSK300k) m_rxFormLayout.addRow(m_modHBox3) m_modHBox4 = QHBoxLayout(self.m_rxContainerWidget) m_modHBox4.addWidget(self.m_OFDM1200k) m_modHBox4.addWidget(self.m_OFDM2400k) m_rxFormLayout.addRow(m_modHBox4) self.m_packets.insert("100") m_rxFormLayout.addRow("Packets", self.m_packets) m_rxFormLayout.addRow(self.m_sensitivity) self.m_sensitivity.setEnabled(False) m_rxFormLayout.addRow(self.m_rssiSweep) self.m_rssiSweep.setEnabled(False) self.rxGroupBox.setLayout(m_rxFormLayout) self.m_rxConfig.clicked.connect( lambda: self.m_serialPort.slot_rx(self, self.m_signalGenerator)) self.m_rssiRequest.clicked.connect( lambda: self.m_serialPort.slot_rssiReq()) self.m_rxLoopEnable.stateChanged.connect( lambda: self.slot_rxLoopEnable()) self.m_sensitivity.clicked.connect( lambda: self.m_serialPort.slot_sensitivity(self, self. m_signalGenerator)) self.m_rssiSweep.clicked.connect( lambda: self.m_serialPort.slot_rssi_sweep(self, self. m_signalGenerator)) """ enable the tx test mode section only when selected""" def slot_txTestModeEnable(self): if self.m_testMode.isChecked(): self.m_txContinuous.setEnabled(True) self.m_txCW.setEnabled(True) self.m_ant.setEnabled(True) else: self.m_txContinuous.setEnabled(False) self.m_txCW.setEnabled(False) self.m_ant.setEnabled(False) """ Enable the tx loop test section only when selected """ def slot_txLoopEnable(self): if self.m_txLoopEnable.isChecked(): self.m_txFreqStop.setEnabled(True) self.m_txFreqStep.setEnabled(True) self.m_testMode.setChecked(True) self.m_txPowerStop.setEnabled(True) self.m_txPowerStep.setEnabled(True) self.m_txCW.setChecked(True) self.m_txACLR.setEnabled(True) else: self.m_txFreqStop.setEnabled(False) self.m_txFreqStep.setEnabled(False) self.m_testMode.setChecked(False) self.m_txPowerStop.setEnabled(False) self.m_txPowerStep.setEnabled(False) self.m_txCW.setChecked(False) self.m_txACLR.setEnabled(False) def slot_rxLoopEnable(self): if self.m_rxLoopEnable.isChecked(): self.m_rxFreqStop.setEnabled(True) self.m_rxFreqStep.setEnabled(True) self.m_rxPowerStart.setEnabled(True) self.m_rxPowerStop.setEnabled(True) self.m_rxPowerStep.setEnabled(True) self.m_cableLoss.setEnabled(True) else: self.m_rxFreqStop.setEnabled(False) self.m_rxFreqStep.setEnabled(False) self.m_rxPowerStart.setEnabled(False) self.m_rxPowerStop.setEnabled(False) self.m_rxPowerStep.setEnabled(False) self.m_cableLoss.setEnabled(False)
class MyWindow(QMainWindow): def __init__(self, parent=None): super(MyWindow, self).__init__() self.setObjectName("SqliteViewer") root = QFileInfo(__file__).absolutePath() self.setAttribute(Qt.WA_DeleteOnClose) self.settings = QSettings('Axel Schneider', self.objectName()) self.viewer = QTableView() self.viewer.setSelectionBehavior(QAbstractItemView.SelectRows) self.viewer.setSelectionMode(QAbstractItemView.SingleSelection | QItemSelectionModel.Select) self.viewer.verticalHeader().setSectionsMovable(True) self.viewer.verticalHeader().setDragEnabled(True) self.viewer.verticalHeader().setDragDropMode( QAbstractItemView.InternalMove) self.db = QtSql.QSqlDatabase.addDatabase('QSQLITE') self.model = QtSql.QSqlTableModel() self.delrow = -1 self.dbfile = "" self.tablename = "" self.headers = [] self.results = "" self.mycolumn = 0 self.viewer.verticalHeader().setVisible(False) self.setStyleSheet(stylesheet(self)) self.viewer.setModel(self.model) # self.viewer.clicked.connect(self.findrow) self.dlg = QDialog() self.layout = QGridLayout() self.layout.addWidget(self.viewer, 0, 0, 1, 4) self.myWidget = QWidget() self.myWidget.setLayout(self.layout) self.createToolbar() self.statusBar().showMessage("Ready") self.setCentralWidget(self.myWidget) self.setWindowIcon(QIcon.fromTheme("office-database")) self.setGeometry(0, 26, 800, 550) self.setWindowTitle("SqliteViewer") self.msg("Ready") self.viewer.setFocus() def createToolbar(self): # self.actionOpen = QPushButton("Open DB") # self.actionOpen.clicked.connect(self.fileOpen) # icon = QIcon.fromTheme("document-open") # self.actionOpen.setShortcut("Ctrl+O") # self.actionOpen.setShortcutEnabled(True) # self.actionOpen.setIcon(icon) # self.actionOpen.setObjectName("actionOpen") # self.actionOpen.setStatusTip("Open Database") # self.actionOpen.setToolTip("Open Database") # # self.actionImport = QPushButton("Import CSV") # self.actionImport.clicked.connect(self.importCSV) # icon = QIcon.fromTheme("document-open") # self.actionImport.setShortcut("Shift+Ctrl+O") # self.actionImport.setShortcutEnabled(True) # self.actionImport.setIcon(icon) # self.actionImport.setObjectName("actionImport") # self.actionImport.setStatusTip("Import CSV & create Database") # self.actionImport.setToolTip("Import CSV & create Database") self.actionSave_as = QPushButton("Export TSV") self.actionSave_as.clicked.connect(self.fileSaveTab) icon = QIcon.fromTheme("document-save") self.actionSave_as.setShortcut("Ctrl+S") self.actionSave_as.setShortcutEnabled(True) self.actionSave_as.setIcon(icon) self.actionSave_as.setObjectName("actionSave_as") self.actionSave_as.setStatusTip("save tab delimited Text") self.actionSave_as.setToolTip("save tab delimited Text") self.actionSave_comma = QPushButton("Export CSV") self.actionSave_comma.clicked.connect(self.fileSaveComma) icon = QIcon.fromTheme("document-save-as") self.actionSave_comma.setShortcut("Shift+Ctrl+S") self.actionSave_comma.setShortcutEnabled(True) self.actionSave_comma.setIcon(icon) self.actionSave_comma.setObjectName("actionSave_comma") self.actionSave_comma.setStatusTip("save comma delimited Text") self.actionSave_comma.setToolTip("save comma delimited Text") self.actionHide = QPushButton() self.actionHide.clicked.connect(self.toggleVerticalHeaders) icon = QIcon.fromTheme("go-first-symbolic") self.actionHide.setIcon(icon) self.actionHide.setToolTip("toggle vertical Headers") self.actionHide.setShortcut("F3") self.actionHide.setShortcutEnabled(True) self.actionHide.setStatusTip("toggle vertical Headers") ### first row as headers self.actionHeaders = QPushButton() icon = QIcon.fromTheme("ok") self.actionHeaders.setIcon(icon) self.actionHeaders.setToolTip("selected row to headers") self.actionHeaders.setShortcut("F5") self.actionHeaders.setShortcutEnabled(True) self.actionHeaders.setStatusTip("selected row to headers") self.actionPreview = QPushButton() self.actionPreview.clicked.connect(self.handlePreview) icon = QIcon.fromTheme("document-print-preview") self.actionPreview.setShortcut("Shift+Ctrl+P") self.actionPreview.setShortcutEnabled(True) self.actionPreview.setIcon(icon) self.actionPreview.setObjectName("actionPreview") self.actionPreview.setStatusTip("Print Preview") self.actionPreview.setToolTip("Print Preview") self.actionPrint = QPushButton() self.actionPrint.clicked.connect(self.handlePrint) icon = QIcon.fromTheme("document-print") self.actionPrint.setShortcut("Shift+Ctrl+P") self.actionPrint.setShortcutEnabled(True) self.actionPrint.setIcon(icon) self.actionPrint.setObjectName("actionPrint") self.actionPrint.setStatusTip("Print") self.actionPrint.setToolTip("Print") ############################### self.tb = self.addToolBar("ToolBar") self.tb.setIconSize(QSize(16, 16)) self.tb.setMovable(False) # self.tb.addWidget(self.actionOpen) # self.tb.addWidget(self.actionImport) # self.tb.addSeparator() self.tb.addWidget(self.actionSave_as) self.tb.addSeparator() self.tb.addWidget(self.actionSave_comma) self.tb.addSeparator() self.tb.addWidget(self.actionPreview) self.tb.addWidget(self.actionPrint) ### sep self.tb.addSeparator() self.tb.addSeparator() ### popupMenu self.pop = QComboBox() self.pop.setFixedWidth(200) self.pop.currentIndexChanged.connect(self.setTableName) self.tb.addWidget(self.pop) self.tb.addSeparator() self.tb.addWidget(self.actionHide) self.addToolBar(self.tb) def toggleVerticalHeaders(self): if self.viewer.verticalHeader().isVisible() == False: self.viewer.verticalHeader().setVisible(True) icon = QIcon.fromTheme("go-last-symbolic") self.actionHide.setIcon(icon) else: self.viewer.verticalHeader().setVisible(False) icon = QIcon.fromTheme("go-first-symbolic") self.actionHide.setIcon(icon) # def fileOpen(self): # tablelist = [] # fileName, _ = QFileDialog.getOpenFileName(None, "Open Database File", "/home/brian/Dokumente/DB", "DB (*.sqlite *.db *.sql3);; All Files (*.*)") # if fileName: # self.db.close() # self.dbfile = fileName # conn = sqlite3.connect(self.dbfile) # cur = conn.cursor() # res = conn.execute("SELECT name FROM sqlite_master WHERE type='table';") # for name in res: # print (name[0]) # tablelist.append(name[0]) # self.db.setDatabaseName(self.dbfile) # self.db.open() # self.fillComboBox(tablelist) # self.msg("please choose Table from the ComboBox") def fileOpenStartup(self, fileName): tablelist = [] if fileName: self.dbfile = fileName self.db.setDatabaseName(self.dbfile) self.db.open() tablelist = self.db.tables() self.fillComboBox(tablelist) print(self.db.driverName()) self.msg("please choose Table from the ComboBox") # def importCSV(self): # csvfile, _ = QFileDialog.getOpenFileName(None, "Open CSV File", "", "CSV (*.csv *.tsv *.txt)") # if csvfile: # filename = csvfile.rpartition("/")[2].replace(".csv", "") # print(filename) # sqlfile, _ = QFileDialog.getSaveFileName(None, "Save Database File", "/tmp/" + filename + ".sqlite", "SQLite (*.sqlite)") # if sqlfile: # if QFile.exists(sqlfile): # QFile.remove(sqlfile) # con = sqlite3.connect(sqlfile) # cur = con.cursor() # file = QFile(csvfile) # if not file.open(QFile.ReadOnly | QFile.Text): # QMessageBox.warning(self, "Meldung", # "Cannot read file %s:\n%s." % (fileName, file.errorString())) # return # infile = QTextStream(file) # mytext = infile.readLine() # # ### ask for header # ret = QMessageBox.question(self, "SQLiteViewer Message", # "use this line as header?\n\n" + mytext, # QMessageBox.Ok | QMessageBox.No, defaultButton = QMessageBox.Ok) # if ret == QMessageBox.Ok: # df = pandas.read_csv(csvfile, encoding = 'utf-8', delimiter = '\t') # if ret == QMessageBox.No: # df = pandas.read_csv(csvfile, encoding = 'utf-8', delimiter = '\t', header=None) # df.to_sql(filename, con, if_exists='append', index=False) # self.fileOpenStartup(sqlfile) # def fileSaveTab(self): if not self.model.rowCount() == 0: self.msg("exporting Table") conn = sqlite3.connect(self.dbfile) c = conn.cursor() data = c.execute("SELECT * FROM " + self.tablename) self.headers = [description[0] for description in c.description] fileName, _ = QFileDialog.getSaveFileName( None, "Export Table to CSV", self.tablename + ".tsv", "CSV Files (*.csv *.tsv)") if fileName: with open(fileName, 'w') as f: writer = csv.writer(f, delimiter='\t') writer.writerow(self.headers) writer.writerows(data) else: self.msg("nothing to export") def setAutoWidth(self): self.viewer.resizeColumnsToContents() def fillComboBox(self, tablelist): self.pop.clear() self.pop.insertItem(0, "choose Table ...") self.pop.setCurrentIndex(0) for row in tablelist: self.pop.insertItem(self.pop.count(), row) if self.pop.count() > 1: self.pop.setCurrentIndex(1) self.setTableName() def fileSaveComma(self): if not self.model.rowCount() == 0: self.msg("exporting Table") conn = sqlite3.connect(self.dbfile) c = conn.cursor() data = c.execute("SELECT * FROM " + self.tablename) headers = [description[0] for description in c.description] fileName, _ = QFileDialog.getSaveFileName(None, "Export Table to CSV", self.tablename + ".csv", "CSV Files (*.csv)") if fileName: with open(fileName, 'w') as f: writer = csv.writer(f, delimiter=',') writer.writerow(headers) writer.writerows(data) else: self.msg("nothing to export") def editCell(self): item = self.viewer.selectedIndexes()[0] row = self.selectedRow() column = self.selectedColumn() self.model.setData(item, self.editor.text()) def setTableName(self): if not self.pop.currentText() == "choose Table ...": self.tablename = self.pop.currentText() print("DB is:", self.dbfile) self.msg("initialize") self.initializeModel() def initializeModel(self): print("Table selected:", self.tablename) self.model.setTable(self.tablename) self.model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange) self.model.select() self.setAutoWidth() self.msg(self.tablename + " loaded *** " + str(self.model.rowCount()) + " records") # def addrow(self): # if self.viewer.selectionModel().hasSelection(): # row = self.viewer.selectionModel().selectedIndexes()[0].row() # else: # row = self.model.rowCount() # # ret = self.model.insertRow(row) # if ret: # self.viewer.selectRow(row) # item = self.viewer.selectedIndexes()[0] # self.model.setData(item, str("")) # # def findrow(self, i): # self.delrow = i.row() def selectedRow(self): if self.viewer.selectionModel().hasSelection(): row = self.viewer.selectionModel().selectedIndexes()[0].row() return int(row) def selectedColumn(self): column = self.viewer.selectionModel().selectedIndexes()[0].column() return int(column) def closeEvent(self, e): e.accept() # def readSettings(self): # print("reading settings") # if self.settings.contains('geometry'): # self.setGeometry(self.settings.value('geometry')) # # def writeSettings(self): # print("writing settings") # self.settings.setValue('geometry', self.geometry()) def msg(self, message): self.statusBar().showMessage(message) def handlePrint(self): if self.model.rowCount() == 0: self.msg("no rows") else: dialog = QtPrintSupport.QPrintDialog() if dialog.exec_() == QDialog.Accepted: self.handlePaintRequest(dialog.printer()) self.msg("Document printed") def handlePreview(self): if self.model.rowCount() == 0: self.msg("no rows") else: dialog = QtPrintSupport.QPrintPreviewDialog() dialog.setFixedSize(1000, 700) dialog.paintRequested.connect(self.handlePaintRequest) dialog.exec_() self.msg("Print Preview closed") def handlePaintRequest(self, printer): printer.setDocName(self.tablename) document = QTextDocument() cursor = QTextCursor(document) model = self.viewer.model() tableFormat = QTextTableFormat() tableFormat.setBorder(0.2) tableFormat.setBorderStyle(3) tableFormat.setCellSpacing(0) tableFormat.setTopMargin(0) tableFormat.setCellPadding(4) table = cursor.insertTable(model.rowCount() + 1, model.columnCount(), tableFormat) model = self.viewer.model() ### get headers myheaders = [] for i in range(0, model.columnCount()): myheader = model.headerData(i, Qt.Horizontal) cursor.insertText(myheader) cursor.movePosition(QTextCursor.NextCell) # ## get cells for row in range(0, model.rowCount()): for col in range(0, model.columnCount()): index = model.index(row, col) cursor.insertText(str(index.data())) cursor.movePosition(QTextCursor.NextCell) document.print_(printer)
class PyMultiPageWidget(QWidget): currentIndexChanged = pyqtSignal(int) pageTitleChanged = pyqtSignal(str) def __init__(self, parent=None): super(PyMultiPageWidget, self).__init__(parent) self.comboBox = QComboBox() # MAGIC # It is important that the combo box has an object name beginning # with '__qt__passive_', otherwise, it is inactive in the form editor # of the designer and you can't change the current page via the # combo box. # MAGIC self.comboBox.setObjectName('__qt__passive_comboBox') self.stackWidget = QStackedWidget() self.comboBox.activated.connect(self.setCurrentIndex) self.layout = QVBoxLayout() self.layout.addWidget(self.comboBox) self.layout.addWidget(self.stackWidget) self.setLayout(self.layout) def sizeHint(self): return QSize(200, 150) def count(self): return self.stackWidget.count() def widget(self, index): return self.stackWidget.widget(index) @pyqtSlot(QWidget) def addPage(self, page): self.insertPage(self.count(), page) @pyqtSlot(int, QWidget) def insertPage(self, index, page): page.setParent(self.stackWidget) self.stackWidget.insertWidget(index, page) title = page.windowTitle() if title == "": title = "Page %d" % (self.comboBox.count() + 1) page.setWindowTitle(title) self.comboBox.insertItem(index, title) @pyqtSlot(int) def removePage(self, index): widget = self.stackWidget.widget(index) self.stackWidget.removeWidget(widget) self.comboBox.removeItem(index) def getPageTitle(self): return self.stackWidget.currentWidget().windowTitle() @pyqtSlot(str) def setPageTitle(self, newTitle): self.comboBox.setItemText(self.getCurrentIndex(), newTitle) self.stackWidget.currentWidget().setWindowTitle(newTitle) self.pageTitleChanged.emit(newTitle) def getCurrentIndex(self): return self.stackWidget.currentIndex() @pyqtSlot(int) def setCurrentIndex(self, index): if index != self.getCurrentIndex(): self.stackWidget.setCurrentIndex(index) self.comboBox.setCurrentIndex(index) self.currentIndexChanged.emit(index) pageTitle = pyqtProperty(str, fget=getPageTitle, fset=setPageTitle, stored=False) currentIndex = pyqtProperty(int, fget=getCurrentIndex, fset=setCurrentIndex)
class LanguageSelectWidget(QWidget): language_changed = pyqtSignal(str) def __init__(self, lyrics_path, current_language, *args, **kwargs): super(LanguageSelectWidget, self).__init__(*args, **kwargs) self.lyrics_path = QStandardPaths.locate(QStandardPaths.AppDataLocation, lyrics_path, QStandardPaths.LocateDirectory) self.current_language = current_language layout = QVBoxLayout() layout.setSpacing(5) layout.setContentsMargins(0, 0, 0, 0) languages = [] try: for filename in os.listdir(self.lyrics_path): if filename != "timing" and os.path.isdir(os.path.join(self.lyrics_path, filename)): languages.append(filename) except FileNotFoundError: pass self.languages_combo_box = QComboBox() self.languages_combo_box.addItems(sorted(languages) + [self.tr("New Language...")]) self.languages_combo_box.currentTextChanged.connect(self._language_changed) self._select_current_language() layout.addWidget(self.languages_combo_box) self.edit_button = QPushButton(text=self.tr("Edit Language..."), clicked=self._edit_current_language) layout.addWidget(self.edit_button) self.setLayout(layout) self.import_lyrics_wizard = ImportLyricsWizard(lyrics_path, accepted=self._wizard_done, rejected=self._wizard_aborted, ) self._editing_language = False if not languages: self.import_lyrics_wizard.open() def _language_changed(self, name): if name == self.tr("New Language..."): self.import_lyrics_wizard.open() else: self.current_language = name self.language_changed.emit(name) def _wizard_done(self): languages = [self.languages_combo_box.itemText(i) for i in range(self.languages_combo_box.count() - 1)] if self._editing_language: self._editing_language = False old_index = languages.index(self.current_language) self.languages_combo_box.removeItem(old_index) languages.pop(old_index) new_language = self.import_lyrics_wizard.language print("new", new_language) languages.append(new_language) languages.sort() index = languages.index(new_language) self.languages_combo_box.insertItem(index, new_language) self.languages_combo_box.setCurrentIndex(index) def _wizard_aborted(self): self._select_current_language() def _select_current_language(self): languages = [self.languages_combo_box.itemText(i) for i in range(self.languages_combo_box.count() - 1)] if languages: self.languages_combo_box.setCurrentIndex(languages.index(self.current_language)) def _edit_current_language(self): self._editing_language = True self.import_lyrics_wizard.open() self.import_lyrics_wizard.edit_language(self.current_language)
def addParam(self, *, layout=None, label='some param name', box=None, paramName='n/a', rowIndex=1, decimals=2, minimum=0, maximum=10000, unit='', float=True, listport=False, listmonitor=False, boolean=False): self.settings += [paramName] layout.addWidget(QLabel(label, box), rowIndex, 1, 1, 1) if listmonitor: valc = QComboBox() i = 0 for monitor in QApplication.screens(): valc.insertItem(i, str(i) + ': ' + monitor.name(), i) i += 1 sindex = valc.findData(AppData.configParams[paramName][-1][0]) if sindex == -1: sindex = 0 valc.setCurrentIndex(sindex) elif listport: valc = QComboBox() i = 0 for port in self.comports: valc.insertItem(i, 'RTS on ' + port[0] + ': ' + port[1], (port[0], 'RTS')) valc.insertItem(i, 'BREAK on ' + port[0] + ': ' + port[1], (port[0], 'BREAK')) i += 1 sindex = valc.findData(AppData.configParams[paramName][-1][0][1]) if sindex == -1: valc.insertItem( i, AppData.configParams[paramName][-1][0][1] + ' on ' + AppData.configParams[paramName][-1][0][0] + ': no device detected', AppData.configParams[paramName][-1][0]) else: valc.setCurrentIndex(sindex) elif boolean: valc = QComboBox() valc.insertItem(0, 'True', True) valc.insertItem(1, 'False', False) sindex = valc.findData(AppData.configParams[paramName][-1][0]) valc.setCurrentIndex(sindex) else: if float: valc = QDoubleSpinBox() valc.setDecimals(decimals) else: valc = QSpinBox() valc.lineEdit().setCursor(AppData.cursors['text']) valc.setMinimum(minimum) valc.setMaximum(maximum) valc.setValue(AppData.configParams[paramName][-1][0]) setattr(self, paramName, valc) dowc = QLabel() checkc = QPushButton() filec = QLabel() setattr(self, paramName + 'Default', checkc) def resetParam(): setattr(self, paramName + 'Override', False) if AppData.configParams[paramName][-1][1] == self.filename: dowc.setText('') checkc.setText('') filec.setText(unit + ' from ' + AppData.configParams[paramName][-2][1]) dowc.setEnabled(False) checkc.setEnabled(False) filec.setEnabled(False) valc.blockSignals(True) if listmonitor or listport or boolean: sindex = valc.findData( AppData.configParams[paramName][-2][0]) valc.setCurrentIndex(sindex) else: valc.setValue(AppData.configParams[paramName][-2][0]) valc.blockSignals(False) else: dowc.setText('') checkc.setText('') filec.setText(unit + ' from ' + AppData.configParams[paramName][-1][1]) dowc.setEnabled(False) checkc.setEnabled(False) filec.setEnabled(False) valc.blockSignals(True) if listmonitor or listport or boolean: sindex = valc.findData( AppData.configParams[paramName][-1][0]) valc.setCurrentIndex(sindex) else: valc.setValue(AppData.configParams[paramName][-1][0]) valc.blockSignals(False) def trumpParam(): setattr(self, paramName + 'Override', True) if AppData.configParams[paramName][-1][1] == self.filename: dowc.setText(unit + ' overriding') checkc.setText( str(AppData.configParams[paramName][-2][0]) + ' ' + unit) filec.setText('specified in ' + AppData.configParams[paramName][-2][1]) dowc.setEnabled(True) checkc.setEnabled(True) filec.setEnabled(True) else: dowc.setText(unit + ' overriding') checkc.setText( str(AppData.configParams[paramName][-1][0]) + ' ' + unit) filec.setText('\tspecified in ' + AppData.configParams[paramName][-1][1]) dowc.setEnabled(True) checkc.setEnabled(True) filec.setEnabled(True) checkc.pressed.connect(resetParam) if listport or listmonitor or boolean: valc.currentIndexChanged.connect(trumpParam) else: valc.valueChanged.connect(trumpParam) overridesParam = AppData.configParams[paramName][-1][ 1] == self.filename setattr(self, paramName + 'Override', overridesParam) if overridesParam: trumpParam() else: resetParam() layout.addWidget(valc, rowIndex, 2, 1, 1) layout.addWidget(dowc, rowIndex, 3, 1, 1) layout.addWidget(checkc, rowIndex, 4, 1, 1) layout.addWidget(filec, rowIndex, 5, 1, 1)
class LoginScreen(QWidget): """ The login screen lets the user select a user profile or create a new one. """ login_successful = pyqtSignal(str, UserProfile, name="login_successful") def __init__(self, *args, **kwargs): """ Load the user profiles and create the login controls. """ super().__init__(*args, **kwargs) # Load the user profile collection. try: self.user_profile_collection = UserProfileCollection.from_dict(global_settings["users"]) except KeyError: self.user_profile_collection = UserProfileCollection() # Create and set the widget layout. layout = QVBoxLayout() layout.setAlignment(Qt.AlignCenter) self.setLayout(layout) # Fill the select-user combobox with the loaded profile names. self.select_user_combobox = QComboBox() layout.addWidget(self.select_user_combobox) self.select_user_combobox.addItem("") names = self.user_profile_collection.names() names = [(name.lower(), name) for name in names] # convert to lower case for sorting for _, name in sorted(names): self.select_user_combobox.addItem(name) # Add the login button. self.login_btn = QPushButton(text="Login", enabled=False) layout.addWidget(self.login_btn) # Add the create-user link. txt = QLabel(text="<a href='#'>Create new user</a>") layout.addWidget(txt) txt.setContextMenuPolicy(Qt.PreventContextMenu) # Connect signals and slots. This must be done after initializing all class members. self.select_user_combobox.currentIndexChanged.connect(self.on_selection_changed) self.login_btn.clicked.connect(self.on_login) txt.linkActivated.connect(self.on_show_create_user_dialog) @pyqtSlot(int, name="on_selection_changed") @log_exceptions def on_selection_changed(self, i): """ Disable the login button if no username is selected, enable it otherwise. :param i: The current selected index in the selection combobox. """ self.login_btn.setEnabled(i != 0) @pyqtSlot(name="on_login") @log_exceptions def on_login(self): """ If something is selected in the select-user combobox, the login_successful is emitted. """ if self.select_user_combobox.currentIndex() != 0: name = self.select_user_combobox.currentText() profile = self.user_profile_collection[name] self.login_successful.emit(name, profile) else: logging.warning("LoginScreen.on_login(): Tried to login without selecting a user.") @pyqtSlot(name="on_show_create_user_dialog") @log_exceptions def on_show_create_user_dialog(self): """ Show the dialog to create a new user. """ names = self.user_profile_collection.names() db_locations = self.user_profile_collection.db_locations() w = CreateUserDialog(names, db_locations, parent=self) w.setAttribute(Qt.WA_DeleteOnClose, True) w.accepted.connect(self.on_create_user) w.show() @pyqtSlot(dict, name="on_create_user") @log_exceptions def on_create_user(self, data): """ Add the user to the profile collection. """ try: name = data.pop("display_name") profile = UserProfile() for key, value in data.items(): profile[key] = value # Add the profile to the collection. self.user_profile_collection[name] = profile # Add the new name to the combobox while keeping the alphabetical order. for i in range(self.select_user_combobox.count()): if name.lower() < self.select_user_combobox.itemText(i).lower(): self.select_user_combobox.insertItem(i, name) break else: self.select_user_combobox.addItem(name) self.select_user_combobox.setCurrentText(name) # Save the created user. global_settings["users"] = self.user_profile_collection except (KeyError, IndexError, OSError) as ex: logging.warning(str(ex))
class FindInFilesDialog(QDialog): """Dialog to configure and trigger the search in the files.""" findStarted = pyqtSignal() def __init__(self, result_widget, parent): super(FindInFilesDialog, self).__init__(parent) self._find_thread = FindInFilesThread() self.setWindowTitle(translations.TR_FIND_IN_FILES) self.resize(400, 300) #MAIN LAYOUT main_vbox = QVBoxLayout(self) self.pattern_line_edit = QLineEdit() self.pattern_line_edit.setPlaceholderText(translations.TR_FIND + "...") self.dir_name_root = None self.user_home = os.path.expanduser('~') self.dir_combo = QComboBox() self.dir_combo.addItem(self.user_home) self.dir_combo.setEditable(True) self.open_button = QPushButton(QIcon(":img/find"), translations.TR_OPEN) self.filters_line_edit = QLineEdit("*.py") self.filters_line_edit.setPlaceholderText("*.py") self.filters_line_edit.setCompleter(QCompleter( ["*{}".format(item) for item in settings.SUPPORTED_EXTENSIONS])) self.replace_line = QLineEdit() self.replace_line.setEnabled(False) self.replace_line.setPlaceholderText( translations.TR_TEXT_FOR_REPLACE + "...") self.check_replace = QCheckBox(translations.TR_REPLACE) self.case_checkbox = QCheckBox(translations.TR_CASE_SENSITIVE) self.type_checkbox = QCheckBox(translations.TR_REGULAR_EXPRESSION) self.recursive_checkbox = QCheckBox(translations.TR_RECURSIVE) self.recursive_checkbox.setCheckState(Qt.Checked) self.phrase_radio = QRadioButton(translations.TR_SEARCH_BY_PHRASE) self.phrase_radio.setChecked(True) self.words_radio = QRadioButton( translations.TR_SEARCH_FOR_ALL_THE_WORDS) self.find_button = QPushButton(translations.TR_FIND + "!") self.find_button.setMaximumWidth(150) self.cancel_button = QPushButton(translations.TR_CANCEL) self.cancel_button.setMaximumWidth(150) self.result_widget = result_widget hbox = QHBoxLayout() hbox.addWidget(self.find_button) hbox.addWidget(self.cancel_button) #main section find_group_box = QGroupBox(translations.TR_MAIN) grid = QGridLayout() grid.addWidget(QLabel(translations.TR_TEXT), 0, 0) grid.addWidget(self.pattern_line_edit, 0, 1) grid.addWidget(QLabel(translations.TR_DIRECTORY), 1, 0) grid.addWidget(self.dir_combo, 1, 1) grid.addWidget(self.open_button, 1, 2) grid.addWidget(QLabel(translations.TR_FILTER), 2, 0) grid.addWidget(self.filters_line_edit, 2, 1) grid.addWidget(self.check_replace, 3, 0) grid.addWidget(self.replace_line, 3, 1) find_group_box.setLayout(grid) #add main section to MAIN LAYOUT main_vbox.addWidget(find_group_box) #options sections options_group_box = QGroupBox(translations.TR_OPTIONS) gridOptions = QGridLayout() gridOptions.addWidget(self.case_checkbox, 0, 0) gridOptions.addWidget(self.type_checkbox, 1, 0) gridOptions.addWidget(self.recursive_checkbox, 2, 0) gridOptions.addWidget(self.phrase_radio, 0, 1) gridOptions.addWidget(self.words_radio, 1, 1) options_group_box.setLayout(gridOptions) #add options sections to MAIN LAYOUT main_vbox.addWidget(options_group_box) #add buttons to MAIN LAYOUT main_vbox.addLayout(hbox) #Focus self.pattern_line_edit.setFocus() self.open_button.setFocusPolicy(Qt.NoFocus) #signal self.open_button.clicked['bool'].connect(self._select_dir) self.find_button.clicked['bool'].connect(self._find_in_files) self.cancel_button.clicked['bool'].connect(self._kill_thread) self._find_thread.found_pattern.connect(self._found_match) self._find_thread.finished.connect(self._find_thread_finished) self.type_checkbox.stateChanged[int].connect(self._change_radio_enabled) self.check_replace.stateChanged[int].connect(self._replace_activated) self.words_radio.clicked['bool'].connect(self._words_radio_pressed) def _replace_activated(self): """If replace is activated, display the replace widgets.""" self.replace_line.setEnabled(self.check_replace.isChecked()) self.phrase_radio.setChecked(True) def _words_radio_pressed(self, value): """If search by independent words is activated, replace is not.""" self.replace_line.setEnabled(not value) self.check_replace.setChecked(not value) self.words_radio.setChecked(True) def _change_radio_enabled(self, val): """Control the state of the radio buttons.""" enabled = not self.type_checkbox.isChecked() self.phrase_radio.setEnabled(enabled) self.words_radio.setEnabled(enabled) def show(self, actual_project=None, actual=None): """Display the dialog and load the projects.""" self.dir_combo.clear() self.dir_name_root = actual_project if \ actual_project else [self.user_home] self.dir_combo.addItems(self.dir_name_root) if actual: index = self.dir_combo.findText(actual) self.dir_combo.setCurrentIndex(index) super(FindInFilesDialog, self).show() self.pattern_line_edit.setFocus() def reject(self): """Close the dialog and hide the tools dock.""" self._kill_thread() tools_dock = IDE.get_service('tools_dock') if tools_dock: tools_dock.hide() super(FindInFilesDialog, self).reject() def _find_thread_finished(self): """Wait on thread finished.""" self.finished.emit(0) self._find_thread.wait() def _select_dir(self): """When a new folder is selected, add to the combo if needed.""" dir_name = QFileDialog.getExistingDirectory(self, translations.TR_OPEN, self.dir_combo.currentText(), QFileDialog.ShowDirsOnly) index = self.dir_combo.findText(dir_name) if index >= 0: self.dir_combo.setCurrentIndex(index) else: self.dir_combo.insertItem(0, dir_name) self.dir_combo.setCurrentIndex(0) def _found_match(self, result): """Update the tree for each match found.""" file_name = result[0] items = result[1] self.result_widget.update_result( self.dir_combo.currentText(), file_name, items) def _kill_thread(self): """Kill the thread.""" if self._find_thread.isRunning(): self._find_thread.cancel() self.accept() def _find_in_files(self): """Trigger the search on the files.""" self.findStarted.emit() self._kill_thread() self.result_widget.clear() pattern = self.pattern_line_edit.text() dir_name = self.dir_combo.currentText() filters = re.split("[,;]", self.filters_line_edit.text()) #remove the spaces in the words Ex. (" *.foo"--> "*.foo") filters = [f.strip() for f in filters] case_sensitive = self.case_checkbox.isChecked() type_ = QRegExp.RegExp if \ self.type_checkbox.isChecked() else QRegExp.FixedString recursive = self.recursive_checkbox.isChecked() by_phrase = True if self.phrase_radio.isChecked() or self.type_checkbox.isChecked(): regExp = QRegExp(pattern, case_sensitive, type_) elif self.words_radio.isChecked(): by_phrase = False type_ = QRegExp.RegExp pattern = '|'.join( [word.strip() for word in pattern.split()]) regExp = QRegExp(pattern, case_sensitive, type_) #save a reference to the root directory where we find self.dir_name_root = dir_name self._find_thread.find_in_files(dir_name, filters, regExp, recursive, by_phrase)
class SchemeSelector(QWidget): currentChanged = pyqtSignal() changed = pyqtSignal() def __init__(self, parent=None): super(SchemeSelector, self).__init__(parent) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.label = QLabel() self.scheme = QComboBox() self.menuButton = QPushButton(flat=True) menu = QMenu(self.menuButton) self.menuButton.setMenu(menu) layout.addWidget(self.label) layout.addWidget(self.scheme) layout.addWidget(self.menuButton) layout.addStretch(1) # action generator def act(slot, icon=None): a = QAction(self, triggered=slot) self.addAction(a) icon and a.setIcon(icons.get(icon)) return a # add action a = self.addAction_ = act(self.slotAdd, 'list-add') menu.addAction(a) # remove action a = self.removeAction = act(self.slotRemove, 'list-remove') menu.addAction(a) # rename action a = self.renameAction = act(self.slotRename, 'document-edit') menu.addAction(a) menu.addSeparator() # import action a = self.importAction = act(self.slotImport, 'document-open') menu.addAction(a) # export action a = self.exportAction = act(self.slotExport, 'document-save-as') menu.addAction(a) self.scheme.currentIndexChanged.connect(self.slotSchemeChanged) app.translateUI(self) def translateUI(self): self.label.setText(_("Scheme:")) self.menuButton.setText(_("&Menu")) self.addAction_.setText(_("&Add...")) self.removeAction.setText(_("&Remove")) self.renameAction.setText(_("Re&name...")) self.importAction.setText(_("&Import...")) self.exportAction.setText(_("&Export...")) def slotSchemeChanged(self, index): """Called when the Scheme combobox is changed by the user.""" self.disableDefault(self.scheme.itemData(index) == 'default') self.currentChanged.emit() self.changed.emit() def disableDefault(self, val): self.removeAction.setDisabled(val) self.renameAction.setDisabled(val) def schemes(self): """Returns the list with internal names of currently available schemes.""" return [self.scheme.itemData(i) for i in range(self.scheme.count())] def currentScheme(self): """Returns the internal name of the currently selected scheme""" return self.scheme.itemData(self.scheme.currentIndex()) def insertSchemeItem(self, name, scheme): for i in range(1, self.scheme.count()): n = self.scheme.itemText(i) if n.lower() > name.lower(): self.scheme.insertItem(i, name, scheme) break else: self.scheme.addItem(name, scheme) def addScheme(self, name): num, key = 1, 'user1' while key in self.schemes() or key in self._schemesToRemove: num += 1 key = 'user{0}'.format(num) self.insertSchemeItem(name, key) self.scheme.setCurrentIndex(self.scheme.findData(key)) return key def slotAdd(self): name, ok = QInputDialog.getText(self, app.caption(_("Add Scheme")), _("Please enter a name for the new scheme:")) if ok: self.addScheme(name) def slotRemove(self): index = self.scheme.currentIndex() scheme = self.scheme.itemData(index) if scheme == 'default': return # default can not be removed self._schemesToRemove.add(scheme) self.scheme.removeItem(index) def slotRename(self): index = self.scheme.currentIndex() name = self.scheme.itemText(index) scheme = self.scheme.itemData(index) newName, ok = QInputDialog.getText(self, _("Rename"), _("New name:"), text=name) if ok: self.scheme.blockSignals(True) self.scheme.removeItem(index) self.insertSchemeItem(newName, scheme) self.scheme.setCurrentIndex(self.scheme.findData(scheme)) self.scheme.blockSignals(False) self.changed.emit() def slotImport(self): filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption(_("dialog title", "Import color theme")) filename = QFileDialog.getOpenFileName(self, caption, QDir.homePath(), filetypes)[0] if filename: self.parent().import_(filename) def slotExport(self): name = self.scheme.currentText() filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption(_("dialog title", "Export {name}").format(name=name)) path = os.path.join(QDir.homePath(), name+'.xml') filename = QFileDialog.getSaveFileName(self, caption, path, filetypes)[0] if filename: if os.path.splitext(filename)[1] != '.xml': filename += '.xml' self.parent().export(name, filename) def loadSettings(self, currentKey, namesGroup): # don't mark schemes for removal anymore self._schemesToRemove = set() s = QSettings() cur = s.value(currentKey, "default", str) # load the names for the shortcut schemes s.beginGroup(namesGroup) block = self.scheme.blockSignals(True) self.scheme.clear() self.scheme.addItem(_("Default"), "default") lst = [(s.value(key, key, str), key) for key in s.childKeys()] for name, key in sorted(lst, key=lambda f: f[0].lower()): self.scheme.addItem(name, key) # find out index index = self.scheme.findData(cur) self.disableDefault(cur == 'default') self.scheme.setCurrentIndex(index) self.scheme.blockSignals(block) self.currentChanged.emit() def saveSettings(self, currentKey, namesGroup, removePrefix=None): # first save new scheme names s = QSettings() s.beginGroup(namesGroup) for i in range(self.scheme.count()): if self.scheme.itemData(i) != 'default': s.setValue(self.scheme.itemData(i), self.scheme.itemText(i)) for scheme in self._schemesToRemove: s.remove(scheme) s.endGroup() if removePrefix: for scheme in self._schemesToRemove: s.remove("{0}/{1}".format(removePrefix, scheme)) # then save current scheme = self.currentScheme() s.setValue(currentKey, scheme) # clean up self._schemesToRemove = set()
class update_database(QWidget): #界面设计 def __init__(self): super().__init__() self.center() self.init_ui() self.cdb = create_database() #self.show() def init_ui(self): self.resize(560, 450) self.setWindowTitle('MySQL Administrator 1.2.17') self.setStyleSheet('font:bold 18px') self.combox = QComboBox(self) self.sd = show_data() Label1 = QLabel("请在下面输入要录入的内容:", self) Label1.move(30, 30) SnoLabel = QLabel('学号:', self) SnoLabel.move(150, 70) self.SnoText = QLineEdit(self) self.SnoText.setPlaceholderText('学号为11位数字') self.SnoText.move(210, 70) SnameLabel = QLabel('姓名:', self) SnameLabel.move(150, 120) self.SnameText = QLineEdit(self) self.SnameText.setFixedWidth(100) self.SnameText.move(210, 120) xbLabel = QLabel('性别:', self) xbLabel.move(150, 170) self.xb_man = QRadioButton('男', self) self.xb_man.move(210, 170) self.xb_feman = QRadioButton('女', self) self.xb_feman.move(210, 190) AgeLabel = QLabel('年龄:', self) AgeLabel.move(150, 220) self.AgeText = QLineEdit(self) self.AgeText.setFixedWidth(50) self.AgeText.move(210, 220) SdepartLabel = QLabel('院系:', self) SdepartLabel.move(150, 270) self.combox.move(210, 270) self.combox.insertItem(1, self.tr('MATH')) self.combox.insertItem(2, self.tr('SCIENCE')) self.EnterButton = QToolButton(self) self.EnterButton.setText('确定') self.EnterButton.resize(80, 50) self.EnterButton.move(310, 350) self.CancelButton = QToolButton(self) self.CancelButton.setText('取消') self.CancelButton.resize(80, 50) self.CancelButton.move(420, 350) self.FindButton = QToolButton(self) self.FindButton.setText('查询') self.FindButton.resize(80, 50) self.FindButton.move(200, 350) self.EnterButton.clicked.connect(self.get_sex) self.EnterButton.clicked.connect(self.Insert) self.EnterButton.clicked.connect(self.refresh) self.CancelButton.clicked.connect(self.close) self.FindButton.clicked.connect(self.sd.show) self.FindButton.clicked.connect(self.sd.insert_table) def refresh(self): self.SnoText.clear() self.SnameText.clear() self.AgeText.clear() def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) #处理函数 def Insert(self): sno = self.SnoText.text() sname = self.SnameText.text() ssex = Ssex sage = self.AgeText.text() sdept = self.combox.currentText() print(sno, sname, ssex, sage, sdept) self.cdb.insert_data(sno, sname, ssex, sage, sdept) def get_sex(self): global Ssex if self.xb_man.isChecked(): Ssex = '男' else: Ssex = '女'
class MainWindow(QMainWindow): receiveUpdateSignal = pyqtSignal(str) errorSignal = pyqtSignal(str) isDetectSerialPort = False receiveCount = 0 sendCount = 0 isScheduledSending = False def __init__(self): super().__init__() self.initWindow() self.initTool() self.initEvent() self.programStartGetSavedParameters() return def __del__(self): return def initTool(self): self.com = serial.Serial() return def initWindow(self): QToolTip.setFont(QFont('SansSerif', 10)) # main layout mainWidget = QWidget() settingLayout = QVBoxLayout() sendReceiveLayout = QVBoxLayout() sendFunctionalLayout = QVBoxLayout() mainLayout = QHBoxLayout() mainLayout.addLayout(settingLayout) mainLayout.addLayout(sendReceiveLayout) mainLayout.addLayout(sendFunctionalLayout) mainWidget.setLayout(mainLayout) mainLayout.setStretch(0, 2) mainLayout.setStretch(1, 6) mainLayout.setStretch(2, 2) self.setCentralWidget(mainWidget) # widgets receive and send area self.receiveArea = QTextEdit() self.sendArea = QTextEdit() self.clearReceiveButtion = QPushButton(parameters.strClearReceive) self.sendButtion = QPushButton(parameters.strSend) self.sendHistory = QComboBox() sendAreaWidgetsLayout = QHBoxLayout() buttonLayout = QVBoxLayout() buttonLayout.addWidget(self.clearReceiveButtion) buttonLayout.addStretch(1) buttonLayout.addWidget(self.sendButtion) sendAreaWidgetsLayout.addWidget(self.sendArea) sendAreaWidgetsLayout.addLayout(buttonLayout) sendReceiveLayout.addWidget(self.receiveArea) sendReceiveLayout.addLayout(sendAreaWidgetsLayout) sendReceiveLayout.addWidget(self.sendHistory) sendReceiveLayout.setStretch(0, 7) sendReceiveLayout.setStretch(1, 2) sendReceiveLayout.setStretch(2, 1) # widgets serial settings serialSettingsGroupBox = QGroupBox(parameters.strSerialSettings) serialSettingsLayout = QGridLayout() serialReceiveSettingsLayout = QGridLayout() serialSendSettingsLayout = QGridLayout() serialPortLabek = QLabel(parameters.strSerialPort) serailBaudrateLabel = QLabel(parameters.strSerialBaudrate) serailBytesLabel = QLabel(parameters.strSerialBytes) serailParityLabel = QLabel(parameters.strSerialParity) serailStopbitsLabel = QLabel(parameters.strSerialStopbits) self.serialPortCombobox = Combobox.Combobox() self.serailBaudrateCombobox = QComboBox() self.serailBaudrateCombobox.addItem("9600") self.serailBaudrateCombobox.addItem("19200") self.serailBaudrateCombobox.addItem("38400") self.serailBaudrateCombobox.addItem("57600") self.serailBaudrateCombobox.addItem("115200") self.serailBaudrateCombobox.setCurrentIndex(4) self.serailBaudrateCombobox.setEditable(True) self.serailBytesCombobox = QComboBox() self.serailBytesCombobox.addItem("5") self.serailBytesCombobox.addItem("6") self.serailBytesCombobox.addItem("7") self.serailBytesCombobox.addItem("8") self.serailBytesCombobox.setCurrentIndex(3) self.serailParityCombobox = QComboBox() self.serailParityCombobox.addItem("None") self.serailParityCombobox.addItem("Odd") self.serailParityCombobox.addItem("Even") self.serailParityCombobox.addItem("Mark") self.serailParityCombobox.addItem("Space") self.serailParityCombobox.setCurrentIndex(0) self.serailStopbitsCombobox = QComboBox() self.serailStopbitsCombobox.addItem("1") self.serailStopbitsCombobox.addItem("1.5") self.serailStopbitsCombobox.addItem("2") self.serailStopbitsCombobox.setCurrentIndex(0) self.serialOpenCloseButton = QPushButton(parameters.strOpen) serialSettingsLayout.addWidget(serialPortLabek, 0, 0) serialSettingsLayout.addWidget(serailBaudrateLabel, 1, 0) serialSettingsLayout.addWidget(serailBytesLabel, 2, 0) serialSettingsLayout.addWidget(serailParityLabel, 3, 0) serialSettingsLayout.addWidget(serailStopbitsLabel, 4, 0) serialSettingsLayout.addWidget(self.serialPortCombobox, 0, 1) serialSettingsLayout.addWidget(self.serailBaudrateCombobox, 1, 1) serialSettingsLayout.addWidget(self.serailBytesCombobox, 2, 1) serialSettingsLayout.addWidget(self.serailParityCombobox, 3, 1) serialSettingsLayout.addWidget(self.serailStopbitsCombobox, 4, 1) serialSettingsLayout.addWidget(self.serialOpenCloseButton, 5, 0, 1, 2) serialSettingsGroupBox.setLayout(serialSettingsLayout) settingLayout.addWidget(serialSettingsGroupBox) # serial receive settings serialReceiveSettingsGroupBox = QGroupBox( parameters.strSerialReceiveSettings) self.receiveSettingsAscii = QRadioButton(parameters.strAscii) self.receiveSettingsHex = QRadioButton(parameters.strHex) self.receiveSettingsAscii.setChecked(True) self.receiveSettingsAutoLinefeed = QCheckBox( parameters.strAutoLinefeed) self.receiveSettingsAutoLinefeedTime = QLineEdit( parameters.strAutoLinefeedTime) self.receiveSettingsAutoLinefeed.setMaximumWidth(75) self.receiveSettingsAutoLinefeedTime.setMaximumWidth(75) serialReceiveSettingsLayout.addWidget(self.receiveSettingsAscii, 1, 0, 1, 1) serialReceiveSettingsLayout.addWidget(self.receiveSettingsHex, 1, 1, 1, 1) serialReceiveSettingsLayout.addWidget(self.receiveSettingsAutoLinefeed, 2, 0, 1, 1) serialReceiveSettingsLayout.addWidget( self.receiveSettingsAutoLinefeedTime, 2, 1, 1, 1) serialReceiveSettingsGroupBox.setLayout(serialReceiveSettingsLayout) settingLayout.addWidget(serialReceiveSettingsGroupBox) # serial send settings serialSendSettingsGroupBox = QGroupBox( parameters.strSerialSendSettings) self.sendSettingsAscii = QRadioButton(parameters.strAscii) self.sendSettingsHex = QRadioButton(parameters.strHex) self.sendSettingsAscii.setChecked(True) self.sendSettingsScheduledCheckBox = QCheckBox(parameters.strScheduled) self.sendSettingsScheduled = QLineEdit(parameters.strScheduledTime) self.sendSettingsScheduledCheckBox.setMaximumWidth(75) self.sendSettingsScheduled.setMaximumWidth(75) self.sendSettingsCFLF = QCheckBox(parameters.strCRLF) self.sendSettingsCFLF.setChecked(False) serialSendSettingsLayout.addWidget(self.sendSettingsAscii, 1, 0, 1, 1) serialSendSettingsLayout.addWidget(self.sendSettingsHex, 1, 1, 1, 1) serialSendSettingsLayout.addWidget(self.sendSettingsScheduledCheckBox, 2, 0, 1, 1) serialSendSettingsLayout.addWidget(self.sendSettingsScheduled, 2, 1, 1, 1) serialSendSettingsLayout.addWidget(self.sendSettingsCFLF, 3, 0, 1, 2) serialSendSettingsGroupBox.setLayout(serialSendSettingsLayout) settingLayout.addWidget(serialSendSettingsGroupBox) settingLayout.setStretch(0, 5) settingLayout.setStretch(1, 2.5) settingLayout.setStretch(2, 2.5) # right functional layout self.addButton = QPushButton(parameters.strAdd) self.settingsButton = QPushButton(parameters.strSettings) self.aboutButton = QPushButton(parameters.strAbout) menuLayout = QHBoxLayout() menuLayout.addWidget(self.settingsButton) menuLayout.addWidget(self.aboutButton) functionalGroupBox = QGroupBox(parameters.strFunctionalSend) functionalGridLayout = QGridLayout() functionalGridLayout.addWidget(self.addButton, 0, 1) functionalGroupBox.setLayout(functionalGridLayout) sendFunctionalLayout.addLayout(menuLayout) sendFunctionalLayout.addWidget(functionalGroupBox) # main window self.statusBarStauts = QLabel() self.statusBarStauts.setMinimumWidth(80) self.statusBarStauts.setText("<font color=%s>%s</font>" % ("#008200", parameters.strReady)) self.statusBarSendCount = QLabel(parameters.strSend + "(bytes): " + "0") self.statusBarReceiveCount = QLabel(parameters.strReceive + "(bytes): " + "0") self.statusBar().addWidget(self.statusBarStauts) self.statusBar().addWidget(self.statusBarSendCount, 2) self.statusBar().addWidget(self.statusBarReceiveCount, 3) # self.statusBar() self.resize(800, 500) self.MoveToCenter() self.setWindowTitle(parameters.appName + " V" + str(helpAbout.versionMajor) + "." + str(helpAbout.versionMinor)) self.setWindowIcon(QIcon(parameters.appIcon)) self.show() return def initEvent(self): self.serialOpenCloseButton.clicked.connect(self.openCloseSerial) self.sendButtion.clicked.connect(self.sendData) self.receiveUpdateSignal.connect(self.updateReceivedDataDisplay) self.clearReceiveButtion.clicked.connect(self.clearReceiveBuffer) self.serialPortCombobox.clicked.connect(self.portComboboxClicked) self.sendSettingsHex.clicked.connect(self.onSendSettingsHexClicked) self.sendSettingsAscii.clicked.connect(self.onSendSettingsAsciiClicked) self.errorSignal.connect(self.errorHint) self.sendHistory.currentIndexChanged.connect( self.sendHistoryIndexChanged) self.settingsButton.clicked.connect(self.showSettings) self.aboutButton.clicked.connect(self.showAbout) self.addButton.clicked.connect(self.functionAdd) return def openCloseSerial(self): try: if self.com.is_open: self.com.close() self.serialOpenCloseButton.setText(parameters.strOpen) self.statusBarStauts.setText("<font color=%s>%s</font>" % ("#f31414", parameters.strClosed)) self.receiveProgressStop = True self.serialPortCombobox.setDisabled(False) self.serailBaudrateCombobox.setDisabled(False) self.serailParityCombobox.setDisabled(False) self.serailStopbitsCombobox.setDisabled(False) self.serailBytesCombobox.setDisabled(False) self.programExitSaveParameters() else: try: self.com.baudrate = int( self.serailBaudrateCombobox.currentText()) self.com.port = self.serialPortCombobox.currentText( ).split(" ")[0] self.com.bytesize = int( self.serailBytesCombobox.currentText()) self.com.parity = self.serailParityCombobox.currentText( )[0] self.com.stopbits = float( self.serailStopbitsCombobox.currentText()) self.com.timeout = None self.com.open() self.serialOpenCloseButton.setText(parameters.strClose) self.statusBarStauts.setText( "<font color=%s>%s</font>" % ("#008200", parameters.strReady)) self.serialPortCombobox.setDisabled(True) self.serailBaudrateCombobox.setDisabled(True) self.serailParityCombobox.setDisabled(True) self.serailStopbitsCombobox.setDisabled(True) self.serailBytesCombobox.setDisabled(True) receiveProcess = threading.Thread(target=self.receiveData) receiveProcess.setDaemon(True) receiveProcess.start() except Exception as e: self.com.close() self.receiveProgressStop = True self.errorHint(parameters.strOpenFailed + str(e)) except Exception: pass return def portComboboxClicked(self): self.detectSerialPort() return def getSendData(self): data = self.sendArea.toPlainText() if self.sendSettingsCFLF.isChecked(): data = data.replace("\n", "\r\n") if self.sendSettingsHex.isChecked(): if self.sendSettingsCFLF.isChecked(): data = data.replace("\r\n", " ") else: data = data.replace("\n", " ") data = self.hexStringB2Hex(data) if data == -1: self.errorHint(parameters.strWriteFormatError) return -1 else: data = data.encode() return data def sendData(self): try: if self.com.is_open: data = self.getSendData() if data == -1: return print("send:", data) self.sendCount += len(data) self.com.write(data) self.sendHistoryFindDelete(data.decode()) self.sendHistory.insertItem(0, data.decode()) self.sendHistory.setCurrentIndex(0) self.receiveUpdateSignal.emit(None) # scheduled send if self.sendSettingsScheduledCheckBox.isChecked(): if not self.isScheduledSending: t = threading.Thread(target=self.scheduledSend) t.setDaemon(True) t.start() except Exception as e: self.errorHint(parameters.strWriteError) print(e) return def scheduledSend(self): self.isScheduledSending = True while self.sendSettingsScheduledCheckBox.isChecked(): self.sendData() try: time.sleep( int(self.sendSettingsScheduled.text().strip()) / 1000) except Exception: self.errorHint(parameters.strTimeFormatError) self.isScheduledSending = False return def receiveData(self): self.receiveProgressStop = False self.timeLastReceive = 0 while (not self.receiveProgressStop): try: length = self.com.in_waiting if length > 0: bytes = self.com.read(length) self.receiveCount += len(bytes) if self.receiveSettingsHex.isChecked(): strReceived = self.asciiB2HexString(bytes) self.receiveUpdateSignal.emit(strReceived) else: self.receiveUpdateSignal.emit( bytes.decode("utf-8", "ignore")) if self.receiveSettingsAutoLinefeed.isChecked(): if time.time() - self.timeLastReceive > int( self.receiveSettingsAutoLinefeedTime.text( )) / 1000: if self.sendSettingsCFLF.isChecked(): self.receiveUpdateSignal.emit("\r\n") else: self.receiveUpdateSignal.emit("\n") self.timeLastReceive = time.time() except Exception as e: print("receiveData error") if self.com.is_open and not self.serialPortCombobox.isEnabled( ): self.openCloseSerial() self.serialPortCombobox.clear() self.detectSerialPort() print(e) time.sleep(0.009) return def updateReceivedDataDisplay(self, str): if str != None: curScrollValue = self.receiveArea.verticalScrollBar().value() self.receiveArea.moveCursor(QTextCursor.End) endScrollValue = self.receiveArea.verticalScrollBar().value() self.receiveArea.insertPlainText(str) if curScrollValue < endScrollValue: self.receiveArea.verticalScrollBar().setValue(curScrollValue) else: self.receiveArea.moveCursor(QTextCursor.End) self.statusBarSendCount.setText("%s(bytes):%d" % (parameters.strSend, self.sendCount)) self.statusBarReceiveCount.setText( "%s(bytes):%d" % (parameters.strReceive, self.receiveCount)) return def onSendSettingsHexClicked(self): data = self.sendArea.toPlainText().replace("\n", "\r\n") data = self.asciiB2HexString(data.encode()) self.sendArea.clear() self.sendArea.insertPlainText(data) return def onSendSettingsAsciiClicked(self): try: data = self.sendArea.toPlainText().replace("\n", " ").strip() self.sendArea.clear() if data != "": data = self.hexStringB2Hex(data).decode('utf-8', 'ignore') self.sendArea.insertPlainText(data) except Exception as e: QMessageBox.information(self, parameters.strWriteFormatError, parameters.strWriteFormatError) return def sendHistoryIndexChanged(self): self.sendArea.clear() self.sendArea.insertPlainText(self.sendHistory.currentText()) return def clearReceiveBuffer(self): self.receiveArea.clear() self.receiveCount = 0 self.sendCount = 0 self.receiveUpdateSignal.emit(None) return def MoveToCenter(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) return def errorHint(self, str): QMessageBox.information(self, str, str) return def closeEvent(self, event): reply = QMessageBox.question(self, 'Sure To Quit?', "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.com.close() self.receiveProgressStop = True self.programExitSaveParameters() event.accept() else: event.ignore() def findSerialPort(self): self.port_list = list(serial.tools.list_ports.comports()) return self.port_list def portChanged(self): self.serialPortCombobox.setCurrentIndex(0) self.serialPortCombobox.setToolTip(str(self.portList[0])) def detectSerialPort(self): if not self.isDetectSerialPort: self.isDetectSerialPort = True t = threading.Thread(target=mainWindow.detectSerialPortProcess) t.setDaemon(True) t.start() def detectSerialPortProcess(self): self.serialPortCombobox.clear() while (1): portList = self.findSerialPort() for i in portList: self.serialPortCombobox.addItem(str(i[0]) + " " + str(i[1])) if len(portList) > 0: self.serialPortCombobox.setCurrentIndex(0) self.serialPortCombobox.setToolTip(str(portList[0])) break time.sleep(1) self.isDetectSerialPort = False return def sendHistoryFindDelete(self, str): self.sendHistory.removeItem(self.sendHistory.findText(str)) return def test(self): print("test") return def asciiB2HexString(self, strB): strHex = binascii.b2a_hex(strB).upper() return re.sub(r"(?<=\w)(?=(?:\w\w)+$)", " ", strHex.decode()) + " " def hexStringB2Hex(self, hexString): dataList = hexString.split(" ") j = 0 for i in dataList: if len(i) > 2: return -1 elif len(i) == 1: dataList[j] = "0" + i j += 1 data = "".join(dataList) try: data = bytes.fromhex(data) except Exception: return -1 print(data) return data def programExitSaveParameters(self): paramObj = parameters.ParametersToSave() paramObj.baudRate = self.serailBaudrateCombobox.currentIndex() paramObj.dataBytes = self.serailBytesCombobox.currentIndex() paramObj.parity = self.serailParityCombobox.currentIndex() paramObj.stopBits = self.serailStopbitsCombobox.currentIndex() if self.receiveSettingsHex.isChecked(): paramObj.receiveAscii = False if not self.receiveSettingsAutoLinefeed.isChecked(): paramObj.receiveAutoLinefeed = False else: paramObj.receiveAutoLinefeed = True paramObj.receiveAutoLindefeedTime = self.receiveSettingsAutoLinefeedTime.text( ) if self.sendSettingsHex.isChecked(): paramObj.sendAscii = False if not self.sendSettingsScheduledCheckBox.isChecked(): paramObj.sendScheduled = False paramObj.sendScheduledTime = self.sendSettingsScheduled.text() if not self.sendSettingsCFLF.isChecked(): paramObj.useCRLF = False paramObj.sendHistoryList.clear() for i in range(0, self.sendHistory.count()): paramObj.sendHistoryList.append(self.sendHistory.itemText(i)) f = open("settings.config", "wb") f.truncate() pickle.dump(paramObj, f) pickle.dump(paramObj.sendHistoryList, f) f.close() return def programStartGetSavedParameters(self): paramObj = parameters.ParametersToSave() try: f = open("settings.config", "rb") paramObj = pickle.load(f) paramObj.sendHistoryList = pickle.load(f) f.close() except Exception as e: f = open("settings.config", "wb") f.close() self.serailBaudrateCombobox.setCurrentIndex(paramObj.baudRate) self.serailBytesCombobox.setCurrentIndex(paramObj.dataBytes) self.serailParityCombobox.setCurrentIndex(paramObj.parity) self.serailStopbitsCombobox.setCurrentIndex(paramObj.stopBits) if paramObj.receiveAscii == False: self.receiveSettingsHex.setChecked(True) if paramObj.receiveAutoLinefeed == False: self.receiveSettingsAutoLinefeed.setChecked(False) else: self.receiveSettingsAutoLinefeed.setChecked(True) self.receiveSettingsAutoLinefeedTime.setText( paramObj.receiveAutoLindefeedTime) if paramObj.sendAscii == False: self.sendSettingsHex.setChecked(True) if paramObj.sendScheduled == False: self.sendSettingsScheduledCheckBox.setChecked(False) else: self.sendSettingsScheduledCheckBox.setChecked(True) self.sendSettingsScheduled.setText(paramObj.sendScheduledTime) if paramObj.useCRLF == False: self.sendSettingsCFLF.setChecked(False) else: self.sendSettingsCFLF.setChecked(True) for i in range(0, len(paramObj.sendHistoryList)): str = paramObj.sendHistoryList[i] self.sendHistory.addItem(str) return def keyPressEvent(self, event): if event.key() == Qt.Key_Control: self.keyControlPressed = True elif event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter: if self.keyControlPressed: self.sendData() return def keyReleaseEvent(self, event): if event.key() == Qt.Key_Control: self.keyControlPressed = False return def functionAdd(self): QMessageBox.information(self, "On the way", "On the way") return def showSettings(self): QMessageBox.information(self, "Settings", "On the way") return def showAbout(self): QMessageBox.information( self, "About", "<h1 style='color:#f75a5a';margin=10px;>" + parameters.appName + '</h1><br><b style="color:#08c7a1;margin = 5px;">V' + str(helpAbout.versionMajor) + "." + str(helpAbout.versionMinor) + "</b><br><br>" + helpAbout.date + "<br><br>" + helpAbout.strAbout) return def autoUpdateDetect(self): auto = autoUpdate.AutoUpdate() if auto.detectNewVersion(): auto.OpenBrowser() def openDevManagement(self): os.system('echo aaaa') os.system('start devmgmt.msc')
class HistoryPredictionUI(QWidget): def __init__(self, ssq, title): super().__init__() self.ssq = ssq self.title = title self.initUI() def initUI(self): grid = QGridLayout() grid.setSpacing(10) self.periodCb = QComboBox() self.makeItem() grid.addWidget(self.periodCb, 0, 1) maxBt = QPushButton("最大概率预测") maxBt.clicked.connect(self.maxPrediction) grid.addWidget(maxBt, 1, 0) bestBt = QPushButton("最佳概率预测") bestBt.clicked.connect(self.bestPrediction) grid.addWidget(bestBt, 1, 1) alikeBt = QPushButton("相似概率预测") alikeBt.clicked.connect(self.alikePrediction) grid.addWidget(alikeBt, 1, 2) self.setLayout(grid) self.move(200, 400) self.setWindowTitle(self.title) def getItem(self): itemList = [] for key in self.ssq.record.keys(): itemList.append(str(key)) if len(itemList) == 50: break return itemList def makeItem(self): index = 0 itemList = self.getItem() for item in itemList: self.periodCb.insertItem(index, item) index += 1 def keyPressEvent(self, e): if e.key() == Qt.Key_Escape: self.close() def maxPrediction(self): period = int(self.periodCb.currentText()) - 1 balls = self.ssq.getMaxNumForPeriod(period) text = list2str(balls) self.MaxShowUI = ShowWindow(text, "最大概率预测") self.MaxShowUI.show() def bestPrediction(self): period = int(self.periodCb.currentText()) - 1 balls = self.ssq.getBestNumForPeriod(period) text = list2str(balls) self.BestShowUI = ShowWindow(text, "最佳概率预测") self.BestShowUI.show() def alikePrediction(self): period = int(self.periodCb.currentText()) - 1 balls, text = self.ssq.getALikeNumForPeriod(period) if text is None: text = list2str(balls) self.aLikeShowUI = ShowWindow(text, "相似概率预测") self.aLikeShowUI.show()
class ConsoleWindow(QMainWindow): global textEdit def __init__(self, parent=None): super(ConsoleWindow, self).__init__(parent) self.isConUrl = False # 上 self.searchButton = QLineEdit() self.searchButton.setPlaceholderText("搜索") self.searchButton.setMaximumWidth(300) self.searchButton.setMaximumHeight(32) self.searchButton.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum) self.combo = QComboBox(self) self.combo.insertItem(0, 'Error') self.combo.insertItem(1, 'Debug') self.combo.insertItem(2, 'Verbose') self.combo.insertItem(3, 'Warning') self.combo.setCurrentIndex(0) layout_top = QHBoxLayout() layout_top.setAlignment(Qt.AlignRight) layout_top.setSpacing(20) # layout_top.addWidget(self.combo) # layout_top.addWidget(self.searchButton) self.functionTabWiget = QWidget() self.functionTabWiget.setAutoFillBackground(True) self.functionTabWiget.setFixedHeight(20) self.functionTabWiget.setLayout(layout_top) # 左 self.clearButton = QPushButton(self) icon = QIcon(IconTool.buildQIcon('clear.png')) self.clearButton.setIcon(icon) self.clearButton.setFixedWidth(18) self.clearButton.setFixedHeight(20) self.clearButton.clicked.connect(self.clear) self.clearButton.setToolTip("Clear the logcat") self.setStyleSheet(''' QPushButton{ border: none; background-color: #0000 ; } QPushButton:hover { border: 1px solid #C0C0C0; background-color: yellow; border-style: inset; border-radius:2px; background-color:#C0C0C0; border-style: solid; } ''') self.layoutLeft = QVBoxLayout() self.layoutLeft.setAlignment(Qt.AlignTop) self.layoutLeft.setSpacing(1) self.layoutLeft.addWidget(self.clearButton) self.layoutLeft.setContentsMargins(4, 0, 0, 0) self.leftWiget = QWidget() self.leftWiget.setAutoFillBackground(True) self.leftWiget.setLayout(self.layoutLeft) self.leftWiget.setFixedWidth(22) # 右 self.textEdit = QTextBrowser() self.textEdit.setOpenLinks(True) self.textEdit.setOpenExternalLinks(True) self.textEdit.setReadOnly(True) self.rightWiget = QWidget() self.rightWiget.setAutoFillBackground(True) self.rightWiget.setFixedWidth(15) self.messageSplitter = QSplitter(Qt.Horizontal) self.messageSplitter.addWidget(self.leftWiget) self.messageSplitter.addWidget(self.textEdit) self.messageSplitter.addWidget(self.rightWiget) self.mainSplitter = QSplitter(Qt.Vertical) self.mainSplitter.addWidget(self.functionTabWiget) self.mainSplitter.addWidget(self.messageSplitter) self.setCentralWidget(self.mainSplitter) # 重定向输出 sys.stdout = ConsoleEmittor(textWritten=self.normalOutputWritten) sys.stderr = ConsoleEmittor(textWritten=self.normalOutputWritten) def normalOutputWritten(self, text): cursor = self.textEdit.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertHtml(text) self.textEdit.setTextCursor(cursor) self.textEdit.ensureCursorVisible() def initMenuBar(self): menuBar = self.menuBar() fileMenu = menuBar.addMenu('Logcat') showLogAction = QAction('Show Log', self) fileMenu.addAction(showLogAction) helpMenu = menuBar.addMenu('Setting') aboutAction = QAction(IconTool.buildQIcon('setting.png'), 'About', self) helpMenu.addAction(aboutAction) def clear(self): self.textEdit.clear() return
def init_options(self): if self.layout() is None: self.center() self.setWindowTitle('Options') # Grid for checkbox options pref_header = QLabel('Preferences') pref_header.setObjectName('preferences') # In order to customize style in stylesheet set_header = QLabel('Settings') set_header.setObjectName('settings') h_line = QFrame() h_line.setFrameShape(QFrame.HLine) set_dir = QLabel('Set Screenshot Directory:') set_album = QLabel('Set imgur Album:') cb_click_send = QCheckBox('Click Balloon to Copy Image Link', self) cb_click_send.setChecked(True) cb_no_copy = QCheckBox('Never Copy Image Link') cb_auto_open = QCheckBox('Open Image in Browser') cb_auto_send = QCheckBox('Automatically Copy Image Link') cb_launch_start = QCheckBox('Launch on Start up') cb_launch_start.setDisabled(True) cb_no_copy.setChecked(True) cb_no_copy.setDisabled(True) cb_click_send.stateChanged.connect(lambda: cb_no_copy.setChecked(not cb_no_copy.isChecked())) cb_click_send.stateChanged.connect(lambda: cb_auto_send.setDisabled(cb_auto_send.isEnabled())) cb_click_send.stateChanged.connect(lambda: cb_auto_send.setChecked(cb_auto_send.isChecked())) cb_click_send.stateChanged.connect(self.toggle_click) cb_click_send.stateChanged.emit(1) cb_auto_send.stateChanged.connect(lambda: cb_click_send.setDisabled(cb_click_send.isEnabled())) cb_auto_send.stateChanged.connect(lambda: cb_click_send.setChecked(cb_click_send.isChecked())) cb_auto_send.stateChanged.connect(lambda: cb_no_copy.setChecked(not cb_no_copy.isChecked())) cb_auto_send.stateChanged.connect(self.toggle_auto_upload) cb_auto_open.stateChanged.connect(self.toggle_auto_open) dir_field = QLineEdit() dir_field.insert(self.scan_dir) album_choice = QComboBox() album_list = [alb for alb in self.albums.keys() if alb != 'Main'] album_choice.addItems(album_list) album_choice.insertSeparator(len(album_list) + 1) album_choice.insertItem(len(album_list) + 2, 'Main') album_choice.setCurrentIndex(len(album_list) + 1) album_choice.activated[str].connect(self.set_album) set_dir_button = QPushButton("Set") set_dir_button.clicked.connect(lambda: self.select_dir(dir_field)) set_dir_button.setMaximumWidth(80) options_layout = QGridLayout() options_layout.addWidget(pref_header, 0, 0) options_layout.addWidget(cb_click_send, 1, 0) options_layout.addWidget(cb_auto_send, 2, 0) options_layout.addWidget(cb_no_copy, 3, 0) options_layout.addWidget(cb_auto_open, 4, 0) options_layout.addWidget(h_line, 5, 0) options_layout.addWidget(cb_launch_start, 6, 0) options_layout.addWidget(set_header, 7, 0) options_layout.addWidget(set_dir, 8, 0) options_layout.addWidget(dir_field, 9, 0) options_layout.addWidget(set_dir_button, 10, 0) options_layout.addWidget(set_album, 11, 0) options_layout.addWidget(album_choice, 12, 0) ok_button = QPushButton("Ok") ok_button.clicked.connect(self.close) # cancel_button = QPushButton("Cancel") # Window Layout hbox = QHBoxLayout() hbox.addWidget(ok_button) # hbox.addWidget(cancel_button) # Add this later hbox.addStretch(1) vbox = QVBoxLayout() vbox.addLayout(options_layout) vbox.addLayout(hbox) self.setLayout(vbox) self.setStyleSheet(""" QWidget { background-color: rgb(50,50,50); } QLineEdit { border-color: 1px white; border-radius: 3px; padding: 0 8px; selection-color: #85BF25; background-color: white; } QComboBox { color: black; background-color: white; selection-background-color: rgb(50,50,50); selection-color: #85BF25; border: 1px black; border-radius: 3px; padding: 1px 18px 1px 3px; min-width: 6em; } QComboBox QListView{ color: white; border: 1px black; border-radius: 3px; padding: 1px 18px 1px 3px; min-width: 6em; border-color: #85BF25; } QComboBox::drop-down { width: 15px; } QLabel#preferences { color: #85BF25; font: bold 14px; } QLabel#settings { color: #85BF25; font: bold 14px; } QLabel { color: white; } QLabel#set_header { color: white; font: bold 14px; } QCheckBox { color: white; } QListWidget { color: white; } QPushButton { background-color: rgb(50,50,50); border-color: solid black; border-width: 2px; color: rgb(255,255,255); font: bold 12px; } """) else: pass
class SettingsDialog(QDialog): def __init__(self, program_settings: ProgramSettings): super().__init__() self.all_micros_settings = list() self.combo_micros = QComboBox() self.combo_modes = QComboBox() self.edt_res_width = QSpinBox() self.edt_res_height = QSpinBox() self.edt_offset_left = QSpinBox() self.edt_offset_right = QSpinBox() self.edt_offset_top = QSpinBox() self.edt_offset_bottom = QSpinBox() self.edt_pixels_in_mm = QDoubleSpinBox() self.edt_work_height = QDoubleSpinBox() self.edt_focus = QLineEdit() self.edt_zoom_ratio = QLineEdit() self.init_ui() # Создание элементов формы def init_ui(self): self.setMinimumWidth(480) layout_main = QVBoxLayout() lbl_micros = QLabel("Камера") # lbl_micros.setAlignment(Qt.AlignHCenter) font_title = lbl_micros.font() font_title.setBold(True) font_title.setPixelSize(16) lbl_micros.setFont(font_title) layout_main.addWidget(lbl_micros) layout_micros = QHBoxLayout() self.combo_micros.currentIndexChanged.connect(self.combo_micros_changed) layout_micros.addWidget(self.combo_micros) btn_micros_add = QPushButton("Добавить") btn_micros_add.setMaximumWidth(80) btn_micros_add.clicked.connect(self.btn_micros_add_click) layout_micros.addWidget(btn_micros_add) btn_micros_edt = QPushButton("Изменить") btn_micros_edt.setMaximumWidth(80) btn_micros_edt.clicked.connect(self.btn_micros_edt_click) layout_micros.addWidget(btn_micros_edt) btn_micros_del = QPushButton("Удалить") btn_micros_del.setMaximumWidth(80) btn_micros_del.clicked.connect(self.btn_micros_del_click) layout_micros.addWidget(btn_micros_del) layout_main.addLayout(layout_micros) for edt_px in [self.edt_res_width, self.edt_res_height, self.edt_offset_left, self.edt_offset_right, self.edt_offset_top, self.edt_offset_bottom]: edt_px.setMinimum(0) edt_px.setMaximum(40000) edt_px.setSuffix(" px") edt_px.setButtonSymbols(QAbstractSpinBox.NoButtons) edt_px.setSingleStep(0) lbl_resolution = QLabel("Разрешение") lbl_resolution.setFont(font_title) layout_main.addWidget(lbl_resolution) layout_resolution = QHBoxLayout() layout_resolution.addWidget(QLabel("Ширина")) self.edt_res_width.setValue(1024) self.edt_res_width.setMinimum(20) layout_resolution.addWidget(self.edt_res_width) layout_resolution.addWidget(QLabel("Высота")) self.edt_res_height.setValue(768) self.edt_res_height.setMinimum(10) layout_resolution.addWidget(self.edt_res_height) layout_main.addLayout(layout_resolution) lbl_mode = QLabel("Режимы съемки") lbl_mode.setFont(font_title) layout_main.addWidget(lbl_mode) layout_modes_set = QHBoxLayout() self.combo_modes.currentIndexChanged.connect(self.combo_modes_changed) layout_modes_set.addWidget(self.combo_modes) btn_modes_set_add = QPushButton("Добавить") btn_modes_set_add.setMaximumWidth(80) btn_modes_set_add.clicked.connect(self.btn_modes_set_add_click) layout_modes_set.addWidget(btn_modes_set_add) btn_modes_set_edt = QPushButton("Изменить") btn_modes_set_edt.setMaximumWidth(80) btn_modes_set_edt.clicked.connect(self.btn_modes_set_edt_click) layout_modes_set.addWidget(btn_modes_set_edt) btn_modes_set_del = QPushButton("Удалить") btn_modes_set_del.setMaximumWidth(80) btn_modes_set_del.clicked.connect(self.btn_modes_set_del_click) layout_modes_set.addWidget(btn_modes_set_del) layout_main.addLayout(layout_modes_set) layout_offset = QFormLayout() layout_offset.addRow(QLabel("Размер отступа слева"), self.edt_offset_left) layout_offset.addRow(QLabel("Размер отступа справа"), self.edt_offset_right) layout_offset.addRow(QLabel("Размер отступа сверху"), self.edt_offset_top) layout_offset.addRow(QLabel("Размер отступа снизу"), self.edt_offset_bottom) self.edt_pixels_in_mm.setButtonSymbols(QAbstractSpinBox.NoButtons) self.edt_pixels_in_mm.setSingleStep(0) self.edt_pixels_in_mm.setMinimum(1.000) self.edt_pixels_in_mm.setMaximum(9999.999) self.edt_pixels_in_mm.setValue(1.0) self.edt_pixels_in_mm.setSingleStep(0.0) self.edt_pixels_in_mm.setDecimals(3) layout_offset.addRow(QLabel("Пикселей на мм"), self.edt_pixels_in_mm) self.edt_work_height.setButtonSymbols(QAbstractSpinBox.NoButtons) self.edt_work_height.setSingleStep(0) self.edt_work_height.setMinimum(1.000) self.edt_work_height.setMaximum(9999.999) self.edt_work_height.setValue(1.0) self.edt_work_height.setSingleStep(0.0) self.edt_work_height.setDecimals(3) layout_offset.addRow(QLabel("Высота работы камеры, мм"), self.edt_work_height) layout_offset.addRow(QLabel("Фокус"), self.edt_focus) layout_offset.addRow(QLabel("Увеличение"), self.edt_zoom_ratio) layout_main.addLayout(layout_offset) layout_main.addWidget(QPushButton("ОК")) self.setLayout(layout_main) def combo_micros_changed(self): print(self.combo_micros.currentText()) def combo_modes_changed(self): print(self.combo_set_micro.currentText()) def btn_micros_add_click(self): input_dialog = QInputDialog() text, ok = input_dialog.getText(self, "Добавление камеры", "Наименование", QLineEdit.Normal) if ok: self.combo_micros.addItem(text) self.combo_micros.setCurrentIndex(self.combo_micros.count() - 1) def btn_micros_edt_click(self): if self.combo_micros.count() == 0: return input_dialog = QInputDialog() text, ok = input_dialog.getText(self, "Переименование камеры", "Наименование", QLineEdit.Normal, self.combo_micros.currentText()) if ok and text: i = self.combo_micros.currentIndex() self.combo_micros.removeItem(self.combo_micros.currentIndex()) self.combo_micros.insertItem(i, text) self.combo_micros.setCurrentIndex(i) def btn_micros_del_click(self): if self.combo_micros.count() == 0: return dlg_result = QMessageBox.question(self, "Confirm Dialog", "Вы действительно хотите удалить выбранную камеру со всеми настройками?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if dlg_result == QMessageBox.Yes: input_dialog = QInputDialog() text, ok = input_dialog.getText(self, "Удаление камеры", "Для удаления напишите \"удалить\"", QLineEdit.Normal) if ok and str.lower(text) == "удалить": self.combo_micros.removeItem(self.combo_micros.currentIndex()) def btn_modes_set_add_click(self): input_dialog = QInputDialog() text, ok = input_dialog.getText(self, "Добавление настройки", "Наименование", QLineEdit.Normal) if ok: self.combo_set_micro.addItem(text) self.combo_set_micro.setCurrentIndex(self.combo_set_micro.count() - 1) def btn_modes_set_edt_click(self): if self.combo_set_micro.count() == 0: return input_dialog = QInputDialog() text, ok = input_dialog.getText(self, "Переименование настройки", "Наименование", QLineEdit.Normal, self.combo_set_micro.currentText()) if ok and text: i = self.combo_set_micro.currentIndex() self.combo_set_micro.removeItem(self.combo_set_micro.currentIndex()) self.combo_set_micro.insertItem(i, text) self.combo_set_micro.setCurrentIndex(i) def btn_modes_set_del_click(self): if self.combo_set_micro.count() == 0: return dlg_result = QMessageBox.question(self, "Confirm Dialog", "Вы действительно хотите удалить выбранную настройку полностью?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if dlg_result == QMessageBox.Yes: input_dialog = QInputDialog() text, ok = input_dialog.getText(self, "Удаление настройки", "Для удаления напишите \"удалить\"", QLineEdit.Normal) if ok and str.lower(text) == "удалить": self.combo_set_micro.removeItem(self.combo_set_micro.currentIndex())
class BacGui(QMainWindow): r"""The BAC GUI.""" # Create GUI setting defaults for the class gui_settings = GuiSettings() def __init__(self): # call super method super().__init__() # initialize the state data #self.initialize_state(filename, board, cur_move, cur_game, game_hist) # call init method to instantiate the GUI self.init() # GUI initialization def init(self): r"""Initializes the GUI.""" # initialize timer self.timer = QtCore.QTimer(self) # properties QToolTip.setFont(QtGui.QFont('SansSerif', 10)) # Central Widget self.gui_widget = QWidget(self) self.setCentralWidget(self.gui_widget) # Panels (group boxes) self.grp_profile = QGroupBox('Profile') self.grp_consump = QGroupBox('Consumption') self.grp_plotter = QWidget() # Layouts layout_gui = QHBoxLayout(self.gui_widget) layout_profile = QGridLayout(self.grp_profile) layout_consump = QFormLayout(self.grp_consump) layout_plotter = QVBoxLayout(self.grp_plotter) # Labels lbl_profile = QLabel('Profile:') lbl_height = QLabel('Height:') lbl_weight = QLabel('Weight:') lbl_age = QLabel('Age:') lbl_bmi = QLabel('BMI:') lbl_gender = QLabel('Gender:') lbl_hr1 = QLabel('Hour 1:') lbl_hr2 = QLabel('Hour 2:') lbl_hr3 = QLabel('Hour 3:') lbl_hr4 = QLabel('Hour 4:') lbl_hr5 = QLabel('Hour 5:') lbl_hr6 = QLabel('Hour 6:') lbl_drink = QLabel( 'One Drink is:\n1 oz of 100 proof\n5 oz of wine\n12 oz of regular beer' ) # Fields self.popup_profile = QComboBox() profiles = self.initialize_profiles() for this_profile in profiles: self.popup_profile.addItem(this_profile) self.popup_profile.setCurrentIndex(0) self.popup_profile.activated.connect(self.onActivated) self.lne_height = QLineEdit('') self.lne_weight = QLineEdit('') self.lne_age = QLineEdit('') self.lne_bmi = QLineEdit('') self.radio_gender = QWidget() layout_gender = QHBoxLayout(self.radio_gender) self.radio_fmal = QRadioButton('Female') self.radio_fmal.setChecked(True) self.radio_fmal.toggled.connect(self.radio_toggle) self.radio_male = QRadioButton('Male') self.radio_male.toggled.connect(self.radio_toggle) layout_gender.addWidget(self.radio_fmal) layout_gender.addWidget(self.radio_male) self.lne_hr1 = QLineEdit('') self.lne_hr2 = QLineEdit('') self.lne_hr3 = QLineEdit('') self.lne_hr4 = QLineEdit('') self.lne_hr5 = QLineEdit('') self.lne_hr6 = QLineEdit('') lnes = [ getattr(self, 'lne_' + field) for field in self.gui_settings.get_text_fields() ] for this_lne in lnes: this_lne.setAlignment(QtCore.Qt.AlignCenter) this_lne.editingFinished.connect(self.text_finished) # Buttons - Save Profile button self.btn_save = QPushButton('Save Profile') self.btn_save.setToolTip('Saves the current profile to disk.') self.btn_save.setMaximumWidth(120) self.btn_save.setStyleSheet( 'color: black; background-color: #00bfbf; font: bold;') self.btn_save.clicked.connect(self.btn_save_function) # Buttons - Plot button self.btn_plot = QPushButton('Plot') self.btn_plot.setToolTip( 'Plots the BAC over time with the given information.') self.btn_plot.setMaximumWidth(200) self.btn_plot.setStyleSheet( 'color: black; background-color: #009900; font: bold;') self.btn_plot.clicked.connect(self.btn_plot_function) # Populate widgets - profile layout_profile.addWidget(lbl_profile, 0, 0) layout_profile.addWidget(lbl_height, 1, 0) layout_profile.addWidget(lbl_weight, 2, 0) layout_profile.addWidget(lbl_age, 3, 0) layout_profile.addWidget(lbl_bmi, 4, 0) layout_profile.addWidget(lbl_gender, 5, 0) layout_profile.addWidget(self.popup_profile, 0, 1) layout_profile.addWidget(self.lne_height, 1, 1) layout_profile.addWidget(self.lne_weight, 2, 1) layout_profile.addWidget(self.lne_age, 3, 1) layout_profile.addWidget(self.lne_bmi, 4, 1) layout_profile.addWidget(self.radio_gender, 5, 1) layout_profile.addWidget(self.btn_save, 6, 0, 1, 2, QtCore.Qt.AlignCenter) # Populate widgets - consumption layout_consump.addRow(lbl_hr1, self.lne_hr1) layout_consump.addRow(lbl_hr2, self.lne_hr2) layout_consump.addRow(lbl_hr3, self.lne_hr3) layout_consump.addRow(lbl_hr4, self.lne_hr4) layout_consump.addRow(lbl_hr5, self.lne_hr5) layout_consump.addRow(lbl_hr6, self.lne_hr6) # Populate widgets - plotter layout_plotter.addWidget(lbl_drink) layout_plotter.addWidget(self.btn_plot) # Populate widgets - main GUI layout_gui.addWidget(self.grp_profile) layout_gui.addWidget(self.grp_consump) layout_gui.addWidget(self.grp_plotter) # Call wrapper to initialize GUI self.wrapper() # GUI final layout properties self.center() self.setWindowTitle('BAC GUI') self.setWindowIcon( QtGui.QIcon(os.path.join(get_root_dir(), 'bac_gui.png'))) self.show() #%% Other initializations def initialize_profiles(self): r"""Gets the list of all current profiles that exist in the folder.""" # Check to see if the Default profile exists, and if so load it, else create it folder = get_root_dir() filename = os.path.join(folder, 'Default.pkl') if os.path.isfile(filename): # pragma: no cover self.gui_settings = GuiSettings.load(filename) else: # pragma: no cover self.gui_settings.save(filename) # Find all the pickle files that exist, and make them into profiles profiles = glob.glob(os.path.join(folder, '*.pkl')) profiles = [ os.path.normpath(x).split(os.path.sep)[-1][:-4] for x in profiles ] profiles = set(profiles) ^ {'Default'} profiles = ['Default'] + sorted(profiles) + ['New+'] return profiles #%% wrapper def wrapper(self): r"""Acts as a wrapper to everything the GUI needs to do.""" # Note: nothing is done to update the profile field, it's assumed to correct already # loop through and update the text fields for field in self.gui_settings.get_text_fields(): this_value = getattr(self.gui_settings, field) this_lne = getattr(self, 'lne_' + field) if this_value == GUI_TOKEN: this_lne.setText('') else: this_lne.setText('{:g}'.format(this_value)) # update the gender button group if self.gui_settings.gender == Gender.female: if self.radio_male.isChecked(): self.radio_fmal.setChecked(True) elif self.gui_settings.gender == Gender.male: if self.radio_fmal.isChecked(): self.radio_male.setChecked(True) else: # pragma: no cover raise ValueError('Unexpected value for gender: "{}".'.format( self.gui_settings.gender)) #%% Other callbacks - closing def closeEvent(self, event): r"""Things in here happen on GUI closing.""" event.accept() #%% Other callbacks - center the GUI on the screen def center(self): r"""Makes the GUI centered on the active screen.""" frame_gm = self.frameGeometry() screen = QApplication.desktop().screenNumber( QApplication.desktop().cursor().pos()) center_point = QApplication.desktop().screenGeometry(screen).center() frame_gm.moveCenter(center_point) self.move(frame_gm.topLeft()) #%% Other callbacks - dislaying an error for invalid edit box entries def display_text_error(self, field): r"""Displays a temporary message for invalid characters within the line edit boxes.""" field.setStyleSheet('color: white; background-color: red; font: bold;') reset = lambda: field.setStyleSheet( 'color: black; background-color: white; font: normal;') self.timer.setInterval(300) self.timer.setSingleShot(True) self.timer.timeout.connect(reset) self.timer.start() self.wrapper() #%% Other callbacks - updating the selected profile name def onActivated(self, value): r"""Controls behavior when mode combobox is changed.""" # check if "New+" was selected if value == len(self.popup_profile) - 1: # get the current items items = [ self.popup_profile.itemText(i) for i in range(self.popup_profile.count()) ] # ask for a new profile text, ok = QtGui.QInputDialog.getText(self, 'Profile Name', 'Enter a new profile:') if not ok or not text: # put back to last choice ix = items.index(self.gui_settings.profile) self.popup_profile.setCurrentIndex(ix) else: if text in items: # if already an existing profile, then load the old one print('Profile "{}" already exists and is being loaded.'. format(text)) self.gui_settings = self.gui_settings.load( os.path.join(get_root_dir(), text + '.pkl')) else: # create the new profile gui_settings = GuiSettings() gui_settings.profile = text # if successful in saving, then update the working copy gui_settings.save( os.path.join(get_root_dir(), text + '.pkl')) self.gui_settings = gui_settings # find where to insert in GUI and insert i = 1 while i < len(items) - 1 and items[i] < text: i += 1 self.popup_profile.insertItem(i, text) self.popup_profile.setCurrentIndex(i) else: # changed to the desired existing profile text = self.popup_profile.currentText() if text != self.gui_settings.profile: self.gui_settings = self.gui_settings.load( os.path.join(get_root_dir(), text + '.pkl')) # update the GUI to reflect any new settings self.wrapper() #%% Other callbacks - update the line edit boxes def text_finished(self): r"""Updates gui_settings for LineEdit text changes that happen when you leave the box.""" sender = self.sender() fields = self.gui_settings.get_text_fields() senders = [getattr(self, 'lne_' + field) for field in fields] for ix in range(len(senders)): if sender == senders[ix]: text = sender.text() if text == '': setattr(self.gui_settings, fields[ix], GUI_TOKEN) break try: value = float(text) except ValueError: self.display_text_error(senders[ix]) break else: setattr(self.gui_settings, fields[ix], value) break else: # pragma: no cover raise ValueError('Unexpected field went into this method.') # check for conditions to update the BMI if sender == self.lne_height or sender == self.lne_weight: if self.gui_settings.height != GUI_TOKEN and self.gui_settings.weight != GUI_TOKEN: if self.gui_settings.bmi == GUI_TOKEN: self.gui_settings.bmi = calculate_bmi(self.gui_settings.height, self.gui_settings.weight, \ self.gui_settings.gender, BMI_CONV) # call the wrapper to update all the possible field changes self.wrapper() #%% Other callbacks - Updating the gender button group def radio_toggle(self): r"""Controls the gender radio button group.""" # assert that only one of the button group is checked assert self.radio_fmal.isChecked() ^ self.radio_male.isChecked( ), 'Only one button may be checked.' # determine which button is checked and update the settings accordingly if self.radio_fmal.isChecked(): self.gui_settings.gender = Gender.female elif self.radio_male.isChecked(): # pragma: no branch self.gui_settings.gender = Gender.male self.wrapper() #%% Other callbacks - Save button def btn_save_function(self): r"""Saves the current settings to the specified profile.""" # save the profile self.gui_settings.save( os.path.join(get_root_dir(), self.gui_settings.profile + '.pkl')) #%% Other callbacks - Plot button def btn_plot_function(self): r"""Plots the results and saves to a .png file.""" # call the plotting function fig = plot_bac(self.gui_settings, LEGAL_LIMIT) # save the figure filename = os.path.join(get_root_dir(), fig.canvas.manager.get_window_title() + '.png') fig.savefig(filename, dpi=160, bbox_inches='tight')
class AmountInput(QWidget): def __init__(self, parent, currency): super().__init__(parent) self.currency = currency info = currencyInfo[currency] layout = QHBoxLayout() layout.setContentsMargins(0,0,0,0) self.input = AmountLineEdit(self) self.validator = AmountValidator(self.input, currency, info.defaultUnit) self.input.setValidator(self.validator) self.input.setText('0') layout.addWidget(self.input, 1) units = [(k,v) for k,v in info.multipliers.items()] units.sort(key = lambda x: x[1]) units = [x[0] for x in units] self.unit = QComboBox(self) for i in range(len(units)): self.unit.insertItem(i, units[i]) self.unit.setCurrentIndex(units.index(info.defaultUnit)) self.unit.currentIndexChanged.connect(self.onUnitChange) layout.addWidget(self.unit, 0) self.setLayout(layout) def onUnitChange(self, event): newUnit = self.unit.currentText() self.validator.unit = newUnit self.input.setText('0' + self.input.text()) #Trigger the validator def getValue(self): return formatting.unformatAmountWithoutUnit( self.input.text(), self.currency, self.unit.currentText())