def __addSinglesLine(self): """ Private slot to add a line of entry widgets for single characters. """ hbox = QWidget(self.singlesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) cb1.addItems(self.comboItems) cb1.addItems(self.singleComboItems) hboxLayout.addWidget(cb1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) cb2 = QComboBox(hbox) cb2.setEditable(False) cb2.addItems(self.comboItems) cb2.addItems(self.singleComboItems) hboxLayout.addWidget(cb2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.singlesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__singlesCharTypeSelected) cb2.activated[int].connect(self.__singlesCharTypeSelected) hbox.show() self.singlesItemsBox.adjustSize() self.singlesEntries.append([cb1, le1]) self.singlesEntries.append([cb2, le2])
class ShortcutWindow(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setWindowTitle('Shortcut') self.setWindowIcon(QIcon(os.path.join(os.curdir, 'icons/Shortcut.ico'))) self.resize(300, 400) screenRect = QDesktopWidget().screenGeometry() self.move((screenRect.width() - self.width()) / 2, (screenRect.height() - self.height()) / 2) self.mainWidget = QWidget() self.gridlayout = QGridLayout() self.mainWidget.setLayout(self.gridlayout) self.setCentralWidget(self.mainWidget) try: configloader = ConfigLoader() except ConfigError as e: QMessageBox.about(self, 'Config Error', str(e)) return for i, (title, action) in enumerate(configloader.config.items()): if 'open' in action[0]: button = OpenButton(title, action[1]) elif 'edit' in action[0]: button = EditButton(title, action[1], action[2]) elif 'cmd' in action[0]: button = CmdButton(title, action[1]) else: continue colnum = 2 self.gridlayout.addWidget(button, i / colnum, i % colnum)
def __init__(self): QWidget.__init__(self) self.win_list=windows() self.setFixedSize(900, 600) self.setWindowIcon(QIcon(os.path.join(get_image_file_path(),"doping.png"))) self.setWindowTitle(_("Doping profile editor (www.gpvdm.com)")) self.win_list.set_window(self,"doping") self.main_vbox=QVBoxLayout() toolbar=QToolBar() toolbar.setIconSize(QSize(48, 48)) self.save = QAction(QIcon(os.path.join(get_image_file_path(),"save.png")), _("Save"), self) self.save.triggered.connect(self.callback_save) toolbar.addAction(self.save) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(spacer) self.help = QAction(QIcon(os.path.join(get_image_file_path(),"help.png")), _("Help"), self) self.help.triggered.connect(self.callback_help) toolbar.addAction(self.help) self.main_vbox.addWidget(toolbar) self.fig = Figure(figsize=(5,4), dpi=100) self.ax1=None self.show_key=True canvas = FigureCanvas(self.fig) #canvas.set_background('white') #canvas.set_facecolor('white') canvas.figure.patch.set_facecolor('white') canvas.show() self.main_vbox.addWidget(canvas) self.tab = QTableWidget() self.tab.resizeColumnsToContents() self.tab.verticalHeader().setVisible(False) self.tab.clear() self.tab.setColumnCount(4) self.tab.setSelectionBehavior(QAbstractItemView.SelectRows) self.load() self.build_mesh() self.tab.cellChanged.connect(self.tab_changed) self.main_vbox.addWidget(self.tab) self.draw_graph() self.setLayout(self.main_vbox) return
def __init__(self, parent, centerOnParent=True, disableParentWhenSpinning=False, modality=Qt.NonModal): # super().__init__(parent) QWidget.__init__(self, parent) self._centerOnParent = centerOnParent self._disableParentWhenSpinning = disableParentWhenSpinning # WAS IN initialize() self._color = QColor(Qt.black) self._roundness = 100.0 self._minimumTrailOpacity = 3.14159265358979323846 self._trailFadePercentage = 80.0 self._revolutionsPerSecond = 1.57079632679489661923 self._numberOfLines = 20 self._lineLength = 10 self._lineWidth = 2 self._innerRadius = 10 self._currentCounter = 0 self._isSpinning = False self._timer = QTimer(self) self._timer.timeout.connect(self.rotate) self.updateSize() self.updateTimer() self.hide() # END initialize() self.setWindowModality(modality) self.setAttribute(Qt.WA_TranslucentBackground)
def __init__(self, parentWidget): QWidget.__init__(self, parentWidget) self.editorWidget = parentWidget.editorWidget # TODO: Review class structure self.searching = False self.ui = Ui_SearchWidget() self.ui.setupUi(self) self.resultListModel = QStandardItemModel(self.ui.resultList) self.ui.resultWidget.setCurrentIndex(0) self.ui.resultList.setModel(self.resultListModel) self.ui.resultList.selectionModel().selectionChanged.connect(self.doResultSelected) self.startIcon = QIcon(':/icons/search-global-start.png') self.stopIcon = QIcon(':/icons/search-global-stop.png') self.ui.startStopButton.setIcon(self.startIcon) self.ui.searchInput.returnPressed.connect(self.doReturnKey) self.ui.startStopButton.clicked.connect(self.doStartStopButton) self.workerThread = QThread() self.worker = SearchWorker() self.worker.moveToThread(self.workerThread) self.startWork.connect(self.worker.startSearch) self.worker.searchDone.connect(self.searchDone) self.worker.addMatch.connect(self.addMatch) # self.stopWork.connect(self.worker.stopSearch) self.workerThread.start()
def createTreeView(self): dockWidget = QDockWidget() dockWidget.setAllowedAreas(Qt.LeftDockWidgetArea) dockWidget.setFeatures(QDockWidget.NoDockWidgetFeatures) dockWidget.setTitleBarWidget(QWidget()) self.treeView = QTreeView() self.treeView.clicked.connect(self.treeItemClicked) self.treeModel = TreeModel() self.treeView.setModel(self.treeModel) self.logo = QLabel() logoPixmap = QPixmap(CMAKE_INSTALL_PREFIX + '/share/jderobot/resources/jderobot.png') self.logo.setPixmap(logoPixmap) self.upButton = QPushButton() self.upButton.setText('Up') self.upButton.clicked.connect(self.upButtonClicked) leftContainer = QWidget() leftLayout = QVBoxLayout() leftLayout.addWidget(self.treeView) leftLayout.addWidget(self.upButton) leftLayout.addWidget(self.logo) leftContainer.setLayout(leftLayout) dockWidget.setWidget(leftContainer) self.addDockWidget(Qt.LeftDockWidgetArea, dockWidget)
def __make_cell(self, c, name, col_type, col_type_def): cell = QWidget(self.inner) rbtn = QRadioButton('', cell) rbtn.toggled.connect(lambda: self.rbtn_clicked(name + '_' + str(c))) hbl = QHBoxLayout(cell) hbl.addWidget(rbtn) hbl.setContentsMargins(0, 0, 0, 0) hbl.setAlignment(Qt.AlignCenter) cell.setLayout(hbl) if name == 'cat': if col_type == 'object': rbtn.setChecked(True) self.lst_cat.append(rbtn) elif name == 'num': if col_type != 'object': rbtn.setChecked(True) if col_type_def == 'object': rbtn.setEnabled(False) self.lst_num.append(rbtn) elif name == 'obj': if col_type == 'object' and self.params.task == 'Regression': rbtn.setEnabled(False) elif col_type != 'object' and self.params.task == 'Classification': rbtn.setEnabled(False) if self.params.columns[c] == self.params.objective: rbtn.setChecked(True) self.lst_obj.append(rbtn) return cell
def mouseMoveEvent(self, event): # マウスをクリックして動かしたときにウィジェットを動かす # ローカル座標が(0, 0)になってしまうので、mousePressEventで取得した # ローカル座標を使って補正する self.move(event.screenPos().x() - self.clickedPosx, event.screenPos().y() - self.clickedPosy) QWidget.mouseMoveEvent(self, event)
def mouseReleaseEvent(self, event): self.select[2] = event.screenPos().x() self.select[3] = event.screenPos().y() if self.rubberband.isVisible(): self.rubberband.hide() rect = self.rubberband.geometry() # ポインタ座標を左上→右下に揃える if self.select[0] > self.select[2]: tmp = self.select[0] self.select[0] = self.select[2] self.select[2] = tmp if self.select[1] > self.select[3]: tmp = self.select[1] self.select[1] = self.select[3] self.select[3] = tmp # 選択した面積がゼロの場合は何もしないで関数を終わる if self.select[0]==self.select[2] or self.select[1]==self.select[3]: QWidget.mouseReleaseEvent(self, event) self.close() return # ポインタ座標をメインウインドウに設定する area = '' for point in self.select: area = area + str(int(point)) + ',' main_window.lineEdit.setText(area[0:-1]) self.close() QWidget.mouseReleaseEvent(self, event)
def __init__(self, parentWidget, markerFmt, editWidget): QWidget.__init__(self, parentWidget) self.markerFormat = markerFmt self.textEdit = editWidget self.startPos = 0 self.endPos = 0 self.pattern = '' layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.searchPattern = CancelAwareLineEdit(self) self.searchPattern.setPlaceholderText('Start typing to find in page') self.searchPattern.editingFinished.connect(self.hideWidget) self.searchPattern.textEdited.connect(self.doSearch) upAction = QAction(QIcon(':/icons/find-up.png'), "Find backwards (Shift-F3)", self) upAction.setShortcut(Qt.SHIFT + Qt.Key_F3); upAction.triggered.connect(self.findUpwards) self.upButton = QToolButton(self) self.upButton.setDefaultAction(upAction) downAction = QAction(QIcon(':/icons/find-down.png'), "Find next (F3)", self) downAction.setShortcut(Qt.Key_F3); downAction.triggered.connect(self.findDownwards) self.downButton = QToolButton(self) self.downButton.setDefaultAction(downAction) layout.addWidget(self.searchPattern) layout.addWidget(self.upButton) layout.addWidget(self.downButton)
def __init__(self, url, color): QWidget.__init__(self) self.setStyleSheet("background-color: black") self.file_name_font = QFont() self.file_name_font.setPointSize(24) self.file_name_label = QLabel(self) self.file_name_label.setText(url) self.file_name_label.setFont(self.file_name_font) self.file_name_label.setAlignment(Qt.AlignCenter) self.file_name_label.setStyleSheet("color: #eee") self.qrcode_label = QLabel(self) self.notify_font = QFont() self.notify_font.setPointSize(12) self.notify_label = QLabel(self) self.notify_label.setText("Scan above QR to copy information") self.notify_label.setFont(self.notify_font) self.notify_label.setAlignment(Qt.AlignCenter) self.notify_label.setStyleSheet("color: #eee") layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.addStretch() layout.addWidget(self.qrcode_label, 0, Qt.AlignCenter) layout.addSpacing(20) layout.addWidget(self.file_name_label, 0, Qt.AlignCenter) layout.addSpacing(40) layout.addWidget(self.notify_label, 0, Qt.AlignCenter) layout.addStretch() self.qrcode_label.setPixmap(qrcode.make(url, image_factory=Image).pixmap())
def add_widget_item(self, widget_item): self.layout.addWidget(widget_item) widget_item.show() widget = QWidget() widget.setLayout(self.layout) self.scroll.setWidget(widget)
def __init__(self, project, settings): QWidget.__init__(self) self.ui = Ui_ProjectWidget() self.ui.setupUi(self) self.project = project self.project.filesChanged.connect(self.refresh) self.toolbar = QToolBar() import_image = lambda: ImportImage.pick(lambda f: self.import_image.emit(f[0]), settings) self.toolbar.addAction(ImportImage.icon(), ImportImage.ACTION_TEXT, import_image) self.ui.import_image.clicked.connect(import_image) self.raw_spectra_model = QStandardItemModel() self.calibrated_spectra_model = QStandardItemModel() self.finished_spectra_model = QStandardItemModel() def button_action(button, signal, widget, model): button.clicked.connect(lambda: signal.emit(model.item(widget.selectionModel().selectedRows()[0].row()).data() ) ) widget.selectionModel().selectionChanged.connect(lambda sel, unsel: button.setEnabled(len(sel.indexes())>0)) for model, widget in [(self.raw_spectra_model, self.ui.raw_spectra), (self.calibrated_spectra_model, self.ui.calibrated_spectra), (self.finished_spectra_model, self.ui.finished_spectra)]: widget.setModel(model) widget.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) button_action(self.ui.calibrate, self.calibrate, self.ui.raw_spectra, self.raw_spectra_model) button_action(self.ui.math, self.math, self.ui.calibrated_spectra, self.calibrated_spectra_model) button_action(self.ui.finish, self.finish, self.ui.calibrated_spectra, self.calibrated_spectra_model) button_action(self.ui.open_finished, self.finish, self.ui.finished_spectra, self.finished_spectra_model) open_finished_menu = QMenu() self.ui.open_finished_dirs.setMenu(open_finished_menu) open_finished_menu.addAction(QIcon(':/image_20'), 'Exported Images folder', lambda: QDesktopServices.openUrl(QUrl.fromLocalFile(project.directory_path(Project.EXPORTED_IMAGES)))) open_finished_menu.addAction(QIcon(':/done_20'), 'Finished Spectra folder', lambda: QDesktopServices.openUrl(QUrl.fromLocalFile(project.directory_path(Project.FINISHED_PROFILES)))) self.refresh()
def __init__(self, win): QWidget.__init__(self) self.win = win self.setWindowTitle('Electrum - '+_('Payment Request')) self.setMinimumSize(800, 250) self.address = '' self.label = '' self.amount = 0 self.setFocusPolicy(QtCore.Qt.NoFocus) main_box = QHBoxLayout() self.qrw = QRCodeWidget() main_box.addWidget(self.qrw, 1) vbox = QVBoxLayout() main_box.addLayout(vbox) self.address_label = QLabel("") #self.address_label.setFont(QFont(MONOSPACE_FONT)) vbox.addWidget(self.address_label) self.label_label = QLabel("") vbox.addWidget(self.label_label) self.amount_label = QLabel("") vbox.addWidget(self.amount_label) vbox.addStretch(1) self.setLayout(main_box)
def __init__(self): QMainWindow.__init__(self) self.src = self.queue = self.scale = self.sink = self.bus = self.pipeline = None container = QWidget(self) self.setCentralWidget(container) self.winId = container.winId() self.resize(800, 450) self.pipeline = Gst.Pipeline() # Create GStreamer elements self.src = Gst.ElementFactory.make('ximagesrc', None) self.src.set_property('startx', 0) # Hardcoded for the moment. Monitors on nvidia seems to be merge together into a huge one :/ self.src.set_property('endx', 1920) self.src.set_property('use-damage', 0) self.queue = Gst.ElementFactory.make('queue', None) self.scale = Gst.ElementFactory.make('videoscale', None) self.sink = Gst.ElementFactory.make('ximagesink', None) # Add elements to the pipeline self.pipeline.add(self.src) self.pipeline.add(self.queue) self.pipeline.add(self.scale) self.pipeline.add(self.sink) # Link elements self.src.link(self.queue) self.queue.link(self.scale) self.scale.link(self.sink) # Create bus to get events from GStreamer pipeline self.bus = self.pipeline.get_bus() self.bus.add_signal_watch() self.bus.enable_sync_message_emission() self.bus.connect('sync-message::element', self.on_sync_message)
class Bool(SimpleBlackbox): author = "DrLuke" name = "Bool" modulename = "drluke.builtin.bool" Category = ["Builtin"] placeable = True implementation = BoolImplementation def __init__(self, *args, **kwargs): super(Bool, self).__init__(*args, **kwargs) self.propertiesWidget = QWidget() self.vlayout = QVBoxLayout() self.toggle = QCheckBox("Output") self.toggle.toggled.connect(self.toggleTrueFalse) self.vlayout.addWidget(self.toggle) self.vlayout.addItem(QSpacerItem(40, 20, QSizePolicy.Minimum, QSizePolicy.Expanding)) self.propertiesWidget.setLayout(self.vlayout) def toggleTrueFalse(self, bool): self.sendDataToImplementations(bool) def getPropertiesWidget(self): return self.propertiesWidget def defineIO(self): self.addOutput(bool, "boolout", "Bool out")
def __init__(self, parent): QWidget.__init__(self, parent) self.setMinimumHeight(gui_scale() * 80) self.setMaximumHeight(gui_scale() * 80) self.setMinimumWidth(1) self.setMaximumWidth(1) self.setLayout(QHBoxLayout())
def initUI(self): self.setWindowTitle('Twitter Client') self.setWindowIcon(QIcon("twitter.svg")) QIcon.setThemeName("Adwaita") lay = QVBoxLayout(self) scr = QScrollArea(self) scr.setWidgetResizable(True) scr.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) lay2 = QVBoxLayout() self.setLayout(lay) placehold = QWidget() lay.addWidget(scr) scr.setWidget(placehold) placehold.setLayout(lay2) self.lay = lay2 lay2.setSpacing(0) lay.setSpacing(0) lay.setContentsMargins(0, 0, 0, 0) but = QPushButton("Refresh") lay.addWidget(but) but.pressed.connect(self.fetch_tweets) self.show()
def __init__(self, pubsub_gateway, player_kwargs=None): CliApp.__init__(self, pubsub_gateway, player_kwargs=player_kwargs) QWidget.__init__(self) self.request = Request(self) self.tips_manager = TipsManager(self) self.hotkey_manager = Hotkey(self) #: collections manager self.coll_mgr = CollectionManager(self) self.img_ctl = ImgController(self) self.playlists = PlaylistsModel(parent=self) self.histories = HistoriesModel(parent=self) self.providers = ProvidersModel(parent=self) self.my_music = MyMusicModel(parent=self) self.collections = CollectionsModel(parent=self) self.ui = Ui(self) self.player_pixmap = None self.show_msg = self.ui.magicbox.show_msg self.resize(1000, 618) self.setObjectName('app') QApplication.setWindowIcon(QIcon(APP_ICON)) self.bind_signal()
def display_model(self): """ Clear widget and display items. """ utils.clear_layout(self.layout) self.columns = [] j = 0 columns = [c.name for c in self.model.__table__.columns] + ['report'] for c in columns: if c not in self._columns_to_display: continue self.columns.append(c) l = QLabel(_(c)) l.setObjectName('header') l.setAlignment(Qt.AlignCenter) self.header_layout.addWidget(l, 0, j) j += 1 for i, item in enumerate(self.items[self.current_items_index:self.current_items_index + self.ITEMS_PER_PAGE], 0): self._add_row(i, item) empty = QWidget() empty.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) self.layout.addWidget(empty, self.layout.rowCount(), 0)
def _new_panel(): """Returns a tuple (QWidget, QGridLayout) """ panel = QWidget() panel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) layout = QGridLayout(panel) return panel, layout
def __init__(self, parent = None, plugin = None): QWidget.__init__(self, parent) self.plugin = plugin self.ui = Ui_Form() self.ui.setupUi(self) self.ui.input.sigExecuteCmd.connect(self.runCmd) self.ui.output.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.ui.output.customContextMenuRequested.connect(self.showContextMenu) self.ui.output.setStyleSheet("background-color: black") self.ui.input.setStyleSheet("background-color: black; color: green;") self.ui.input.setContentsMargins(0,0,0,0) self.ui.output.setContentsMargins(0,0,0,0) font = QtGui.QFont("Monospace"); font.setStyleHint(QtGui.QFont.TypeWriter); self.ui.output.setFont(font) self.ui.input.setFont(font) scrollbar = self.ui.output.verticalScrollBar() scrollbar.setStyleSheet("background-color: green") self.setStyleSheet("background-color: black") self.write("<div style='background-color: #000'>",html=True)
def showEvent(self, event): #Show Event QWidget.showEvent(self, event) #Avoid recalculate the panel sizes if they are already loaded if self._splitterArea.count() == 2: return #Rearrange widgets on Window self._splitterArea.insertWidget(0, self._splitterMain) if not event.spontaneous(): self.change_misc_visibility() if bin(settings.UI_LAYOUT)[-1] == '1': self.splitter_central_rotate() if bin(settings.UI_LAYOUT >> 1)[-1] == '1': self.splitter_misc_rotate() if bin(settings.UI_LAYOUT >> 2)[-1] == '1': self.splitter_central_orientation() qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) #Lists of sizes as list of QVariant- heightList = [QVariant, QVariant] heightList = list(qsettings.value("window/central/mainSize", [(self.height() / 3) * 2, self.height() / 3])) widthList = list(qsettings.value("window/central/areaSize", [(self.width() / 6) * 5, self.width() / 6])) self._splitterMainSizes = [int(heightList[0]), int(heightList[1])] self._splitterAreaSizes = [int(widthList[0]), int(widthList[1])] #Set the sizes to splitters #self._splitterMain.setSizes(self._splitterMainSizes) self._splitterMain.setSizes(self._splitterMainSizes) self._splitterArea.setSizes(self._splitterAreaSizes) self.misc.setVisible( qsettings.value("window/show_misc", False, type=bool))
class PreviewWidget(QScrollArea): def __init__(self, parent=None): super(PreviewWidget, self).__init__(parent) self.setWidgetResizable(True) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.widget = QWidget() self.layout = QHBoxLayout() self.layout.addStretch(1) self.layout.setContentsMargins(0, 0, 0, 0) self.widget.setLayout(self.layout) self.setWidget(self.widget) def removeLast(self): item = self.layout.takeAt(0) if item: item.widget().deleteLater() def resizeEvent(self, event): self.widget.setFixedHeight(self.viewport().height()) super(PreviewWidget, self).resizeEvent(event) def addPixmap(self, pixmap): label = ImageLabel(pixmap, self) self.layout.insertWidget(0, label)
def _get_control_layout(self): """ Create static layout. """ widget = QWidget() vbox = QVBoxLayout() widget.setLayout(vbox) vbox.setContentsMargins(0, 0, 0, 0) self.template_combo_box = QComboBox() self.template_combo_box.currentIndexChanged.connect(self._item_selected) vbox.addWidget(self.template_combo_box) scrollable_vbox = utils.get_scrollable(self.controls_layout) vbox.addWidget(scrollable_vbox, stretch=80) buttons_layout = QHBoxLayout() vbox.addLayout(buttons_layout, stretch=20) b = QPushButton("Назад") b.setObjectName("controls") b.clicked.connect(self._close) buttons_layout.addWidget(b) widget.setGraphicsEffect(utils.get_shadow()) return widget
def __init__(self): super().__init__() # 사용한 위젯들을 생성 lbl1 = QLabel('This is') #<---- 1 lbl2 = QLabel('Layout Example') okButton = QPushButton("OK") cancelButton = QPushButton("Cancel") hbox = QHBoxLayout() #<---- 2 hbox.addStretch(1) #<---- 3 hbox.addWidget(okButton) #<---- 4 hbox.addWidget(cancelButton) #<---- 5 vbox = QVBoxLayout() #<---- 6 vbox.addWidget(lbl1) #<---- 7 vbox.addWidget(lbl2) #<---- 8 vbox.addLayout(hbox) #<---- 9 window = QWidget() #<---- 10 window.setLayout(vbox) #<---- 11 self.setCentralWidget(window) #<---- 12 self.setGeometry(300, 300, 300, 150) self.setWindowTitle('Layout Example') self.show()
def update(self): for _ in range(self.layout().count()): self.layout().itemAt(0).widget().close() self.layout().takeAt(0) qsa = QScrollArea() scroll_area_widget = QWidget() layout = QVBoxLayout() scroll_area_widget.setLayout(layout) model = self.result.model cycles_per_ms = model.cycles_per_ms for proc in model.processors: proc_r = self.result.processors[proc] gb = QGroupBox(proc.name) gb_layout = QVBoxLayout() gb.setLayout(gb_layout) gb_layout.addWidget(QLabel( "Cxt Save count: {}".format(proc_r.context_save_count))) gb_layout.addWidget(QLabel( "Cxt Load count: {}".format(proc_r.context_load_count))) gb_layout.addWidget(QLabel( "Cxt Save overhead: {0:.4f}ms ({1:.0f} cycles)".format( float(proc_r.context_save_overhead) / cycles_per_ms, proc_r.context_save_overhead))) gb_layout.addWidget(QLabel( "Cxt Load overhead: {0:.4f}ms ({1:.0f} cycles)".format( float(proc_r.context_load_overhead) / cycles_per_ms, proc_r.context_load_overhead))) layout.addWidget(gb) qsa.setWidget(scroll_area_widget) self.layout().addWidget(qsa)
def __initUI__(self): # ---- Toolbar ---- toolbar_widget = QWidget() self.btn_apply = btn_apply = QPushButton('Apply') btn_apply.clicked.connect(self.btn_apply_isClicked) self.btn_cancel = btn_cancel = QPushButton('Cancel') btn_cancel.clicked.connect(self.close) self.btn_OK = btn_OK = QPushButton('OK') btn_OK.clicked.connect(self.btn_OK_isClicked) toolbar_layout = QGridLayout() toolbar_layout.addWidget(btn_OK, 0, 1) toolbar_layout.addWidget(btn_cancel, 0, 2) toolbar_layout.addWidget(btn_apply, 0, 3) toolbar_layout.setColumnStretch(0, 100) toolbar_widget.setLayout(toolbar_layout) # ---- Main Layout main_layout = QGridLayout() main_layout.addWidget(self._setup_figure_layout_grpbox(), 0, 0) main_layout.addWidget(self._setup_element_visibility_grpbox(), 1, 0) main_layout.setRowStretch(2, 100) main_layout.setRowMinimumHeight(2, 15) main_layout.addWidget(toolbar_widget, 3, 0) self.setLayout(main_layout)
def _createWidget(self): widget = QWidget(self) uic.loadUi(os.path.join(os.path.dirname(__file__), 'Preview.ui'), widget) widget.webView.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) widget.webView.page().linkClicked.connect(self._onLinkClicked) # Disconnected. # Fix preview palette. See https://github.com/bjones1/enki/issues/34 webViewPalette = widget.webView.palette() webViewPalette.setColor(QPalette.Inactive, QPalette.HighlightedText, webViewPalette.color(QPalette.Text)) widget.webView.setPalette(webViewPalette) widget.webView.page().mainFrame().titleChanged.connect( self._updateTitle) # Disconnected. widget.cbEnableJavascript.clicked.connect( self._onJavaScriptEnabledCheckbox) # Disconnected. widget.webView.installEventFilter(self) self.setWidget(widget) self.setFocusProxy(widget.webView) widget.tbSave.clicked.connect(self.onPreviewSave) # Disconnected. # Add an attribute to ``widget`` denoting the splitter location. # This value will be overwritten when the user changes splitter location. widget.splitterErrorStateSize = (199, 50) widget.splitterNormStateSize = (1, 0) widget.splitterNormState = True widget.splitter.setSizes(widget.splitterNormStateSize) widget.splitter.splitterMoved.connect(self.on_splitterMoved) # Disconnected. return widget
def __addRangesLine(self): """ Private slot to add a line of entry widgets for character ranges. """ hbox = QWidget(self.rangesItemsBox) hboxLayout = QHBoxLayout(hbox) hboxLayout.setContentsMargins(0, 0, 0, 0) hboxLayout.setSpacing(6) hbox.setLayout(hboxLayout) cb1 = QComboBox(hbox) cb1.setEditable(False) cb1.addItems(self.comboItems) hboxLayout.addWidget(cb1) l1 = QLabel(self.tr("Between:"), hbox) hboxLayout.addWidget(l1) le1 = QLineEdit(hbox) le1.setValidator(self.charValidator) hboxLayout.addWidget(le1) l2 = QLabel(self.tr("And:"), hbox) hboxLayout.addWidget(l2) le2 = QLineEdit(hbox) le2.setValidator(self.charValidator) hboxLayout.addWidget(le2) self.rangesItemsBoxLayout.addWidget(hbox) cb1.activated[int].connect(self.__rangesCharTypeSelected) hbox.show() self.rangesItemsBox.adjustSize() self.rangesEntries.append([cb1, le1, le2])
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Sat Mar 3 18:39:41 2018 @author: diasaur """ import sys from PyQt5.QtWidgets import QApplication, QWidget if 1: app = QApplication(sys.argv) w = QWidget() w.resize(250, 150) w.move(300, 300) w.setWindowTitle('Test') w.show sys.exit(app.exec_())
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.config = config() self.tabs = [] self.initializeUI() # noinspection PyUnresolvedReferences def initializeUI(self): self.setWindowTitle(translate('rule_setting')) self.central_widget = QWidget() self.setCentralWidget(self.central_widget) self.main_win_layout = QGridLayout() self.central_widget.setLayout(self.main_win_layout) self.setup_tab() self.add_tab_pages() self.setup_global_settings() self.set_rules() # self.add_rule_button() # self.remove_rule_button() self.setup_buttons() self.create_menu() self.show() def setup_tab(self): self.tab_widget = QTabWidget() self.tab_container_layout = QGridLayout() self.main_win_layout.addWidget(self.tab_widget) def add_tab_pages(self): for user in self.config: self.add_a_tab_page(user) def add_a_tab_page(self, tab_name): container = QWidget() container.setObjectName(tab_name) self.tabs.append(container) container.setLayout(QGridLayout()) self.tab_widget.addTab(container, tab_name) def setup_global_settings(self): for n, user in enumerate(self.config): # setup global setting groupbox tab_container = self.tabs[n] groupbox = QGroupBox() layout = QGridLayout() groupbox.setLayout(layout) groupbox.setTitle(translate('global_setting')) groupbox.setObjectName('global') tab_container.layout().addWidget(groupbox) groupbox_layout = groupbox.layout() # setup global setting widgets widgets = [] sequence = ['mix', 'pages', 'show_date', 'qty', 'quiz_dir'] for key in sequence: label, widget = self.add_widget(key, self.config[user]['global'][key]) if widget.objectName() == 'quiz_dir': widget.setDisabled(True) widgets.extend([label, widget]) for row in range(3): for col in range(4): index = row * 4 + col if index < len(widgets): widget = widgets[index] if widget.objectName() == 'quiz_dir': groupbox_layout.addWidget(widget, row, col, 1, 2) else: groupbox_layout.addWidget(widget, row, col) def set_rules(self): # quiz rule setting for n, tab in enumerate(self.tabs): self.set_rules_for_a_tab(tab) def set_rules_for_a_tab(self, tab): rule_tab_widget = QTabWidget() rule_tab_layout = QGridLayout() rule_tab_widget.setLayout(rule_tab_layout) tab.rule_tab_widget = rule_tab_widget tab.layout().addWidget(rule_tab_widget) tab.rule_containers = [] user = tab.objectName() for n, rule in enumerate(self.config[user]['rules']): # build tab pages self.set_a_rule(tab, rule, n) def set_a_rule(self, tab, rule, n): # build a rule tab page for a user tab container = QWidget() tab.rule_containers.append(container) rule_container_layout = QGridLayout() container.setLayout(rule_container_layout) tab.rule_tab_widget.addTab(container, f"{translate('rule')}{n + 1}") container.setObjectName(f"rule {n}") widgets = [] example_label = QLabel(translate('example')) example_content_label = QLabel(quiz_gen(rule)) example_content_label.setObjectName('example') widgets.append(example_label) widgets.append(example_content_label) refresh_button = QPushButton(translate('refresh')) rule_container_layout.addWidget(refresh_button, 0, 3) refresh_button.clicked.connect(self.onRefresh) widgets.append(refresh_button) # build rule widgets and put them into correct positions widgets.extend(self.build_rule_widgets(rule)) # add buttons to add and delete steps add_step_button = QPushButton(translate('add_step')) add_step_button.clicked.connect(self.on_add_step) rm_step_button = QPushButton(translate('rm_step')) rm_step_button.clicked.connect(self.on_rm_step) widgets.append(add_step_button) widgets.append(rm_step_button) container.widgets = widgets self.lay_rule_widgets(rule_container_layout, widgets) def add_rule_button(self): # add rule button for tab in self.tabs: add_rule_button = QPushButton(translate('add_rule')) add_rule_button.clicked.connect(lambda: self.on_add_rule()) tab.layout().addWidget(add_rule_button) def remove_rule_button(self): # remove rule button for tab in self.tabs: remove_rule_button = QPushButton(translate('remove_rule')) remove_rule_button.clicked.connect(lambda: self.on_remove_rule()) tab.layout().addWidget(remove_rule_button) def lay_rule_widgets(self, layout, widgets): layout.addWidget(widgets[0], 0, 0) layout.addWidget(widgets[1], 0, 1, 1, 2) layout.addWidget(widgets[2], 0, 3) row, col = 1, 0 for widget in widgets[3:-2]: span = 1 one_line_items = ['weight', 'operators', 'show_answer'] for item in one_line_items: if widget.objectName().endswith(item): span = 3 layout.addWidget(widget, row, col, 1, span) col += span if widget.objectName().endswith('remainder'): sep = self.setup_separator() row += 1 col = 0 span = 4 layout.addWidget(sep, row, col, 1, span) row += 1 if col == 4: col = 0 row += 1 layout.addWidget(widgets[-2], row, 0) layout.addWidget(widgets[-1], row, 1) def add_widget(self, key, value): """ :param key: a string for a label widget :param value: a string for the text of a combobox or lineedit :return: a label and a widget (combobox or lineedit) """ name_of_label = translate(key.split()[-1]) label = QLabel(name_of_label) label.setObjectName(key + ' label') if isinstance(value, bool): widget = QComboBox() widget.setObjectName(key) self.setup_combo_and_default(widget, translate(str(value))) widget.currentIndexChanged.connect(self.on_change) else: value = str(translate(value)) widget = QLineEdit() widget.setObjectName(key) widget.setText(value) widget.textChanged.connect(self.on_change) return label, widget def build_rule_widgets(self, rule): widgets = [] sequence = ['weight', 'show_answer', {'first_number': ['range', 'display']}, {'steps': ['operators', 'number', 'limits']}] for key in sequence: if isinstance(key, dict): if 'first_number' in key: for value in key['first_number']: first_number_key = value content = rule['first_number'][value] label, widget = self.add_widget('first_number ' + first_number_key, content) widgets.extend([label, widget]) if 'steps' in key: for n, step in enumerate(rule['steps']): step_widgets = self.setup_step_widgets(step, n) widgets.extend(step_widgets) else: label, widget = self.add_widget(key, rule[key]) widgets.extend([label, widget]) return widgets @staticmethod def setup_combo_and_default(combobox, default): combobox.addItems([translate('True'), translate('False')]) if translate(default): combobox.setCurrentIndex(0) else: combobox.setCurrentIndex(1) def setup_separator(self): sep = QFrame() sep.setFrameShape(QFrame.HLine) sep.setFrameShadow(QFrame.Sunken) sep.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) return sep def setup_buttons(self): gen_button = QPushButton(translate('gen_quiz')) gen_button.clicked.connect(lambda: gen_pdf_quiz(self.config)) self.main_win_layout.addWidget(gen_button) def on_change(self): sender = self.sender() if sender.parent().objectName() == 'global': user = sender.parent().parent().objectName() if isinstance(sender, QLineEdit): if sender.text().isdigit(): self.config[user]['global'][sender.objectName()] = eval(sender.text()) if isinstance(sender, QComboBox): self.config[user]['global'][sender.objectName()] = translate(sender.currentText()) else: user = sender.parent().parent().parent().parent().objectName() rule_index = int(sender.parent().objectName().split()[1]) rule = self.config[user]['rules'][rule_index] if isinstance(sender, QLineEdit): try: value = int(sender.text()) except ValueError: try: value = float(sender.text()) except ValueError: value = translate(sender.text()) else: value = translate(sender.currentText()) target = f'rule' for item in sender.objectName().split(): if item.isdigit(): target += f'[{item}]' else: target += f'["{item}"]' exec(target + '= value') if self.validator(sender): write_cfg(self.config) self.onRefresh() def onRefresh(self): sender = self.sender() user = self.tab_widget.currentWidget().objectName() rule_index = self.tab_widget.currentWidget().rule_tab_widget.currentIndex() rule = self.config[user]['rules'][rule_index] quiz = quiz_gen(rule) for widget in sender.parent().children(): if widget.objectName() == 'example': widget.setText(quiz) @staticmethod def validator(widget): if isinstance(widget, QLineEdit): text = widget.text() if widget.objectName().endswith('range'): if re.search(r'^\d+$', text): if eval(text) == 0: widget.setText('1') return True elif re.search(r'^=\d+$', text): return True elif re.search(r'^\d+, *\d+', text): return True else: return False if widget.objectName().endswith('ceiling') or widget.objectName().endswith('floor'): # noinspection PyComparisonWithNone if re.search(r'\d+', text) or text == '' or translate(text) == None: return True else: return False if widget.objectName().endswith('weight'): if re.search(r"^[-+]?\d*\.\d+$|^\d+$", text): if 0 <= eval(text) <= 1: return True else: return False else: return False if widget.objectName().endswith('operators'): if text: for c in text: if c not in '+-*/': return False return True else: return False else: return True def setup_step_widgets(self, step, n): widgets = [] sequence = ['operators', 'number', 'limits'] for key in sequence: if key == 'limits': for limit in step['limits']: content = step['limits'][limit] label, widget = self.add_widget(f'steps {n} limits {limit}', content) widgets.extend([label, widget]) elif key == 'number': for number_key in ['range', 'display']: content = step['number'][number_key] label, widget = self.add_widget(f'steps {n} number {number_key}', content) widgets.extend([label, widget]) else: content = step[key] label, widget = self.add_widget(f'steps {n} {key}', content) widgets.extend([label, widget]) return widgets def on_add_step(self): sender = self.sender() user = sender.parent().parent().parent().parent().objectName() rule_index = int(sender.parent().objectName().split()[1]) rule = self.config[user]['rules'][rule_index] widgets = sender.parent().widgets step = add_step(rule) write_cfg(self.config) step_widgets = self.setup_step_widgets(step, len(rule['steps']) - 1) widgets = widgets[:-2] + step_widgets + widgets[-2:] sender.parent().widgets = widgets self.lay_rule_widgets(sender.parent().layout(), widgets) self.onRefresh() def on_rm_step(self): sender = self.sender() user = sender.parent().parent().parent().parent().objectName() rule_index = int(sender.parent().objectName().split()[1]) rule = self.config[user]['rules'][rule_index] widgets = sender.parent().widgets layout = sender.parent().layout() widgets = widgets[:-20] + widgets[-2:] sender.parent().widgets = widgets if rm_step(rule): write_cfg(self.config) for i in reversed(range(layout.count())): widgetToRemove = layout.itemAt(i).widget() # remove it from the layout list # layout.removeWidget(widgetToRemove) # remove it from the gui widgetToRemove.setParent(None) self.lay_rule_widgets(layout, widgets) self.onRefresh() def on_add_rule(self): tab = self.tab_widget.currentWidget() user = tab.objectName() cfg = self.config[user] new_rule = add_rule(cfg) write_cfg(self.config) rules_amount = len(self.config[user]['rules']) self.set_a_rule(tab, new_rule, rules_amount - 1) def on_remove_rule(self): tab = self.tab_widget.currentWidget() user = tab.objectName() cfg = self.config[user] current_index_of_rule = tab.rule_tab_widget.currentIndex() delete_rule(self.config[user], current_index_of_rule) tab.rule_tab_widget.removeTab(current_index_of_rule) write_cfg(self.config) def create_menu(self): menu_bar = self.menuBar() file_menu = menu_bar.addMenu('File') exit_action = QAction('Quit', self) exit_action.setShortcut('Ctrl+Q') exit_action.triggered.connect(self.close) file_menu.addAction(exit_action) tool_menu = menu_bar.addMenu('Tools') add_rule_action = QAction('add_rule', self) add_rule_action.triggered.connect(self.on_add_rule) tool_menu.addAction(add_rule_action) rm_rule_action = QAction('remove_rule', self) rm_rule_action.triggered.connect(self.on_remove_rule) tool_menu.addAction(rm_rule_action) for action in menu_bar.actions(): text = action.text() action.setText(translate(text)) for act in action.menu().actions(): act_text = act.text() act.setText(translate(act_text))
def keyPressEvent(self, event): if not event.isAutoRepeat(): qKey = str(event.key()) if qKey in kMidiKeyboard2KeyMap.keys(): self.sendNoteOn(kMidiKeyboard2KeyMap.get(qKey)) QWidget.keyPressEvent(self, event)
def __init__(self, parent=None): """Constructor.""" QWidget.__init__(self, parent=parent) self.last_size = QSize()
def resizeEvent(self, event): """Overriden resize event.""" self.last_size = event.oldSize() QWidget.resizeEvent(self, event)
def closeEvent(self, event): """Overriden close event.""" self.save_window_state() QWidget.closeEvent(self, event)
def add_a_tab_page(self, tab_name): container = QWidget() container.setObjectName(tab_name) self.tabs.append(container) container.setLayout(QGridLayout()) self.tab_widget.addTab(container, tab_name)
class MainWindow(QMainWindow): receiveUpdateSignal = pyqtSignal(str) errorSignal = pyqtSignal(str) showSerialComboboxSignal = pyqtSignal() setDisableSettingsSignal = pyqtSignal(bool) isDetectSerialPort = False receiveCount = 0 sendCount = 0 isScheduledSending = False DataPath = "./" isHideSettings = False isHideFunctinal = True app = None isWaveOpen = False def __init__(self, app): super().__init__() self.app = app pathDirList = sys.argv[0].replace("\\", "/").split("/") pathDirList.pop() self.DataPath = os.path.abspath("/".join(str(i) for i in pathDirList)) if not os.path.exists(self.DataPath + "/" + parameters.strDataDirName): pathDirList.pop() self.DataPath = os.path.abspath("/".join( str(i) for i in pathDirList)) self.DataPath = (self.DataPath + "/" + parameters.strDataDirName).replace("\\", "/") self.initWindow() self.initTool() self.initEvent() self.programStartGetSavedParameters() def __del__(self): pass def initTool(self): self.com = serial.Serial() def initWindow(self): QToolTip.setFont(QFont('SansSerif', 10)) # main layout frameWidget = QWidget() mainWidget = QSplitter(Qt.Horizontal) frameLayout = QVBoxLayout() self.settingWidget = QWidget() self.settingWidget.setProperty("class", "settingWidget") self.receiveSendWidget = QSplitter(Qt.Vertical) self.functionalWiget = QWidget() settingLayout = QVBoxLayout() sendReceiveLayout = QVBoxLayout() sendFunctionalLayout = QVBoxLayout() mainLayout = QHBoxLayout() self.settingWidget.setLayout(settingLayout) self.receiveSendWidget.setLayout(sendReceiveLayout) self.functionalWiget.setLayout(sendFunctionalLayout) mainLayout.addWidget(self.settingWidget) mainLayout.addWidget(self.receiveSendWidget) mainLayout.addWidget(self.functionalWiget) mainLayout.setStretch(0, 2) mainLayout.setStretch(1, 6) mainLayout.setStretch(2, 2) menuLayout = QHBoxLayout() mainWidget.setLayout(mainLayout) frameLayout.addLayout(menuLayout) frameLayout.addWidget(mainWidget) frameWidget.setLayout(frameLayout) self.setCentralWidget(frameWidget) # option layout self.settingsButton = QPushButton() self.skinButton = QPushButton("") # self.waveButton = QPushButton("") self.aboutButton = QPushButton() self.functionalButton = QPushButton() self.encodingCombobox = ComboBox() self.encodingCombobox.addItem("ASCII") self.encodingCombobox.addItem("UTF-8") self.encodingCombobox.addItem("UTF-16") self.encodingCombobox.addItem("GBK") self.encodingCombobox.addItem("GB2312") self.encodingCombobox.addItem("GB18030") self.settingsButton.setProperty("class", "menuItem1") self.skinButton.setProperty("class", "menuItem2") self.aboutButton.setProperty("class", "menuItem3") self.functionalButton.setProperty("class", "menuItem4") # self.waveButton.setProperty("class", "menuItem5") self.settingsButton.setObjectName("menuItem") self.skinButton.setObjectName("menuItem") self.aboutButton.setObjectName("menuItem") self.functionalButton.setObjectName("menuItem") # self.waveButton.setObjectName("menuItem") menuLayout.addWidget(self.settingsButton) menuLayout.addWidget(self.skinButton) # menuLayout.addWidget(self.waveButton) menuLayout.addWidget(self.aboutButton) menuLayout.addStretch(0) menuLayout.addWidget(self.encodingCombobox) menuLayout.addWidget(self.functionalButton) # widgets receive and send area self.receiveArea = QTextEdit() self.sendArea = QTextEdit() self.clearReceiveButtion = QPushButton(parameters.strClearReceive) self.sendButtion = QPushButton(parameters.strSend) self.sendHistory = ComboBox() sendWidget = QWidget() sendAreaWidgetsLayout = QHBoxLayout() sendWidget.setLayout(sendAreaWidgetsLayout) 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.addWidget(sendWidget) 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() self.serailBaudrateCombobox = ComboBox() 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 = ComboBox() self.serailBytesCombobox.addItem("5") self.serailBytesCombobox.addItem("6") self.serailBytesCombobox.addItem("7") self.serailBytesCombobox.addItem("8") self.serailBytesCombobox.setCurrentIndex(3) self.serailParityCombobox = ComboBox() 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 = ComboBox() self.serailStopbitsCombobox.addItem("1") self.serailStopbitsCombobox.addItem("1.5") self.serailStopbitsCombobox.addItem("2") self.serailStopbitsCombobox.setCurrentIndex(0) self.checkBoxRts = QCheckBox("rts") self.checkBoxDtr = QCheckBox("dtr") 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.checkBoxRts, 5, 0, 1, 1) serialSettingsLayout.addWidget(self.checkBoxDtr, 5, 1, 1, 1) serialSettingsLayout.addWidget(self.serialOpenCloseButton, 6, 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.filePathWidget = QLineEdit() self.openFileButton = QPushButton("Open File") self.sendFileButton = QPushButton("Send File") self.clearHistoryButton = QPushButton("Clear History") self.addButton = QPushButton(parameters.strAdd) fileSendGroupBox = QGroupBox(parameters.strSendFile) fileSendGridLayout = QGridLayout() fileSendGridLayout.addWidget(self.filePathWidget, 0, 0, 1, 1) fileSendGridLayout.addWidget(self.openFileButton, 0, 1, 1, 1) fileSendGridLayout.addWidget(self.sendFileButton, 1, 0, 1, 2) fileSendGroupBox.setLayout(fileSendGridLayout) sendFunctionalLayout.addWidget(fileSendGroupBox) sendFunctionalLayout.addWidget(self.clearHistoryButton) sendFunctionalLayout.addWidget(self.addButton) sendFunctionalLayout.addStretch(1) self.isHideFunctinal = True self.hideFunctional() # 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)) icon = QIcon() print("icon path:" + self.DataPath + "/" + parameters.appIcon) icon.addPixmap(QPixmap(self.DataPath + "/" + parameters.appIcon), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) if sys.platform == "win32": ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID( "comtool") self.show() print("config file path:", os.getcwd() + "/comtool.settings.config") 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.showSerialComboboxSignal.connect(self.showCombobox) # self.showBaudComboboxSignal.connect(self.showBaudCombobox) self.setDisableSettingsSignal.connect(self.setDisableSettings) self.sendHistory.currentIndexChanged.connect( self.sendHistoryIndexChanged) self.settingsButton.clicked.connect(self.showHideSettings) self.skinButton.clicked.connect(self.skinChange) self.aboutButton.clicked.connect(self.showAbout) self.openFileButton.clicked.connect(self.selectFile) self.sendFileButton.clicked.connect(self.sendFile) self.clearHistoryButton.clicked.connect(self.clearHistory) self.addButton.clicked.connect(self.functionAdd) self.functionalButton.clicked.connect(self.showHideFunctional) self.sendArea.currentCharFormatChanged.connect( self.sendAreaFontChanged) # self.waveButton.clicked.connect(self.openWaveDisplay) self.checkBoxRts.clicked.connect(self.rtsChanged) self.checkBoxDtr.clicked.connect(self.dtrChanged) self.myObject = MyClass(self) slotLambda = lambda: self.indexChanged_lambda(self.myObject) self.serialPortCombobox.currentIndexChanged.connect(slotLambda) # @QtCore.pyqtSlot(str) def indexChanged_lambda(self, obj): mainObj = obj.arg # print("item changed:",mainObj.serialPortCombobox.currentText()) self.serialPortCombobox.setToolTip( mainObj.serialPortCombobox.currentText()) def openCloseSerialProcess(self): try: if self.com.is_open: self.receiveProgressStop = True self.com.close() self.setDisableSettingsSignal.emit(False) 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 if self.checkBoxRts.isChecked(): self.com.rts = False else: self.com.rts = True if self.checkBoxDtr.isChecked(): self.com.dtr = False else: self.com.dtr = True self.com.open() # print("open success") # print(self.com) self.setDisableSettingsSignal.emit(True) self.receiveProcess = threading.Thread( target=self.receiveData) self.receiveProcess.setDaemon(True) self.receiveProcess.start() except Exception as e: self.com.close() self.receiveProgressStop = True self.errorSignal.emit(parameters.strOpenFailed + "\n" + str(e)) self.setDisableSettingsSignal.emit(False) except Exception as e: print(e) def setDisableSettings(self, disable): if disable: 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) self.serialOpenCloseButton.setDisabled(False) else: self.serialOpenCloseButton.setText(parameters.strOpen) self.statusBarStauts.setText("<font color=%s>%s</font>" % ("#f31414", parameters.strClosed)) self.serialPortCombobox.setDisabled(False) self.serailBaudrateCombobox.setDisabled(False) self.serailParityCombobox.setDisabled(False) self.serailStopbitsCombobox.setDisabled(False) self.serailBytesCombobox.setDisabled(False) self.programExitSaveParameters() def openCloseSerial(self): t = threading.Thread(target=self.openCloseSerialProcess) t.setDaemon(True) t.start() def rtsChanged(self): if self.checkBoxRts.isChecked(): self.com.setRTS(False) else: self.com.setRTS(True) def dtrChanged(self): if self.checkBoxDtr.isChecked(): self.com.setDTR(False) else: self.com.setDTR(True) def portComboboxClicked(self): self.detectSerialPort() 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.errorSignal.emit(parameters.strWriteFormatError) return -1 else: data = data.encode(self.encodingCombobox.currentText(), "ignore") return data def sendData(self): try: if self.com.is_open: data = self.getSendData() if data == -1: return # print(self.sendArea.toPlainText()) # print("send:",data) self.sendCount += len(data) self.com.write(data) data = self.sendArea.toPlainText() self.sendHistoryFindDelete(data) self.sendHistory.insertItem(0, data) self.sendHistory.setCurrentIndex(0) self.receiveUpdateSignal.emit("") # 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.errorSignal.emit(parameters.strWriteError) # print(e) def scheduledSend(self): self.isScheduledSending = True while self.sendSettingsScheduledCheckBox.isChecked(): self.sendData() try: time.sleep( int(self.sendSettingsScheduled.text().strip()) / 1000) except Exception: self.errorSignal.emit(parameters.strTimeFormatError) self.isScheduledSending = False def receiveData(self): self.receiveProgressStop = False self.timeLastReceive = 0 while (not self.receiveProgressStop): try: # length = self.com.in_waiting length = max(1, min(2048, self.com.in_waiting)) bytes = self.com.read(length) if bytes != None: # if self.isWaveOpen: # self.wave.displayData(bytes) self.receiveCount += len(bytes) 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() if self.receiveSettingsHex.isChecked(): strReceived = self.asciiB2HexString(bytes) self.receiveUpdateSignal.emit(strReceived) else: self.receiveUpdateSignal.emit( bytes.decode(self.encodingCombobox.currentText(), "ignore")) except Exception as e: # print("receiveData error") # if self.com.is_open and not self.serialPortCombobox.isEnabled(): # self.openCloseSerial() # self.serialPortCombobox.clear() # self.detectSerialPort() if 'multiple access' in str(e): self.errorSignal.emit( "device disconnected or multiple access on port?") break # time.sleep(0.009) def updateReceivedDataDisplay(self, str): if str != "": 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)) def onSendSettingsHexClicked(self): data = self.sendArea.toPlainText().replace("\n", "\r\n") data = self.asciiB2HexString(data.encode()) self.sendArea.clear() self.sendArea.insertPlainText(data) def onSendSettingsAsciiClicked(self): try: data = self.sendArea.toPlainText().replace("\n", " ").strip() self.sendArea.clear() if data != "": data = self.hexStringB2Hex(data).decode( self.encodingCombobox.currentText(), 'ignore') self.sendArea.insertPlainText(data) except Exception as e: # QMessageBox.information(self,parameters.strWriteFormatError,parameters.strWriteFormatError) print("format error") def sendHistoryIndexChanged(self): self.sendArea.clear() self.sendArea.insertPlainText(self.sendHistory.currentText()) def clearReceiveBuffer(self): self.receiveArea.clear() self.receiveCount = 0 self.sendCount = 0 self.receiveUpdateSignal.emit(None) def MoveToCenter(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def errorHint(self, str): QMessageBox.information(self, str, str) 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=self.detectSerialPortProcess) t.setDaemon(True) t.start() def showCombobox(self): self.serialPortCombobox.showPopup() def detectSerialPortProcess(self): while (1): portList = self.findSerialPort() if len(portList) > 0: currText = self.serialPortCombobox.currentText() self.serialPortCombobox.clear() for i in portList: showStr = str(i[0]) + " " + str(i[1]) self.serialPortCombobox.addItem(showStr) index = self.serialPortCombobox.findText(currText) if index >= 0: self.serialPortCombobox.setCurrentIndex(index) else: self.serialPortCombobox.setCurrentIndex(0) break time.sleep(1) self.showSerialComboboxSignal.emit() self.isDetectSerialPort = False def sendHistoryFindDelete(self, str): self.sendHistory.removeItem(self.sendHistory.findText(str)) 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() paramObj.skin = self.param.skin 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)) if self.checkBoxRts.isChecked(): paramObj.rts = 1 else: paramObj.rts = 0 if self.checkBoxDtr.isChecked(): paramObj.dtr = 1 else: paramObj.dtr = 0 paramObj.encodingIndex = self.encodingCombobox.currentIndex() f = open("comtool.settings.config", "wb") f.truncate() pickle.dump(paramObj, f) pickle.dump(paramObj.sendHistoryList, f) f.close() def programStartGetSavedParameters(self): paramObj = parameters.ParametersToSave() try: f = open("comtool.settings.config", "rb") paramObj = pickle.load(f) paramObj.sendHistoryList = pickle.load(f) f.close() except Exception as e: f = open("comtool.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) if paramObj.rts == 0: self.checkBoxRts.setChecked(False) else: self.checkBoxRts.setChecked(True) if paramObj.dtr == 0: self.checkBoxDtr.setChecked(False) else: self.checkBoxDtr.setChecked(True) self.encodingCombobox.setCurrentIndex(paramObj.encodingIndex) self.param = paramObj 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() elif event.key() == Qt.Key_L: if self.keyControlPressed: self.sendArea.clear() elif event.key() == Qt.Key_K: if self.keyControlPressed: self.receiveArea.clear() def keyReleaseEvent(self, event): if event.key() == Qt.Key_Control: self.keyControlPressed = False def sendAreaFontChanged(self, font): print("font changed") def functionAdd(self): QMessageBox.information(self, "On the way", "On the way") def showHideSettings(self): if self.isHideSettings: self.showSettings() self.isHideSettings = False else: self.hideSettings() self.isHideSettings = True def showSettings(self): self.settingWidget.show() self.settingsButton.setStyleSheet( parameters.strStyleShowHideButtonLeft.replace( "$DataPath", self.DataPath)) def hideSettings(self): self.settingWidget.hide() self.settingsButton.setStyleSheet( parameters.strStyleShowHideButtonRight.replace( "$DataPath", self.DataPath)) def showHideFunctional(self): if self.isHideFunctinal: self.showFunctional() self.isHideFunctinal = False else: self.hideFunctional() self.isHideFunctinal = True def showFunctional(self): self.functionalWiget.show() self.functionalButton.setStyleSheet( parameters.strStyleShowHideButtonRight.replace( "$DataPath", self.DataPath)) def hideFunctional(self): self.functionalWiget.hide() self.functionalButton.setStyleSheet( parameters.strStyleShowHideButtonLeft.replace( "$DataPath", self.DataPath)) def skinChange(self): if self.param.skin == 1: # light file = open(self.DataPath + '/assets/qss/style-dark.qss', "r") self.param.skin = 2 else: # elif self.param.skin == 2: # dark file = open(self.DataPath + '/assets/qss/style.qss', "r") self.param.skin = 1 self.app.setStyleSheet(file.read().replace("$DataPath", self.DataPath)) 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) + "." + str(helpAbout.versionDev) + "</b><br><br>" + helpAbout.date + "<br><br>" + helpAbout.strAbout()) def selectFile(self): oldPath = self.filePathWidget.text() if oldPath == "": oldPath = os.getcwd() fileName_choose, filetype = QFileDialog.getOpenFileName( self, "SelectFile", oldPath, "All Files (*);;") if fileName_choose == "": return self.filePathWidget.setText(fileName_choose) def sendFile(self): filename = self.filePathWidget.text() if not os.path.exists(filename): self.errorSignal.emit("File path error\npath:%s" % (filename)) return try: f = open(filename, "rb") except Exception as e: self.errorSignal.emit("Open file %s failed! \n %s" % (filename, str(e))) return self.com.write(f.read()) #TODO: optimize send in new thread f.close() def clearHistory(self): self.param.sendHistoryList.clear() self.sendHistory.clear() self.errorSignal.emit("History cleared!") def autoUpdateDetect(self): auto = autoUpdate.AutoUpdate() if auto.detectNewVersion(): auto.OpenBrowser() def openDevManagement(self): os.system('start devmgmt.msc')
class project(QDialog): def __init__(self): super(project, self).__init__() loadUi('projectl.ui', self) self.setWindowTitle('ProjectOne') self.pushButton1.clicked.connect(self.on_pushButton1_clicked) self.pushButton2.clicked.connect(self.on_pushButton2_clicked) self.pushButton3.clicked.connect(self.on_pushButton3_clicked) humidity, temperature = Adafruit_DHT.read(22, 4) if humidity == None: #if the sensor is not connected the console prints an error message self.label_Hum1.setText("Not Connected") self.label_Temp1.setText("Not Connected") self.average_hum() self.average_temp() self.main_widget = QWidget(self) self.main_widget1 = QWidget(self) l = QVBoxLayout(self.main_widget) self.main_widget.setGeometry(QtCore.QRect(50, 450, 200, 150)) dc = MyDynamicMplCanvas(self.main_widget, width=5, height=4, dpi=100) l.addWidget(dc) t = QVBoxLayout(self.main_widget1) self.main_widget1.setGeometry(QtCore.QRect(250, 450, 200, 150)) sc = MyDynamicMplCanvas1(self.main_widget1, width=5, height=4, dpi=100) t.addWidget(sc) self.lineEdit.setText("0") self.lineEdit1.setText("0") @pyqtSlot() #date1=format(today) #self.label_Time.setText(str(date)) #function to derive the average of humidity and display the average after every two seconds. #the values are automatically displayed on the graphic userinterface #the average values is stored in a global varaible and is also dislayed on graph def average_hum(self): try: self.label_Time.setText(str(date)) self.label_2.setText(cal1) #print(cal1) global average1 #global array_average1[] humidity, temperature = Adafruit_DHT.read(22, 4) if humidity == None: #if the sensor is not connected the console prints an error message self.label_Hum1.setText("Not Connected") else: #print('Humidity ={0:0.1f}%'.format(humidity)) hum = humidity listA.append(hum) sum1 = sum(listA) #print(sum1) #print('Timestamp : {:%H:%M:%S}'.format(datetime.datetime.now())) #print('Date :{:%Y-%m-%d}'.format(datetime.datetime.now())) length1 = len(listA) average1 = (sum1 / length1) array_average1.append(average1) #print('Hum_average is') #print(array_average1) self.label_AveA1.setText(str(average1)) a = 1 count1.append(a) counter1 = sum(count1) #print('count is ') #print( counter1) if counter1 == 10: listA.clear() #print('yaha') count1.clear() finally: QtCore.QTimer.singleShot( 2000, self.average_hum ) #the average function for humidity is called after every 2 sec #function to calculate the average temperture values automatically after every 2.5 seconds #the avergae function is used also to feed the graph to display the values every 10 seconds def average_temp(self): try: global average2 humidity, temperature = Adafruit_DHT.read(22, 4) #print('yasir') if temperature == None: #if the sensor is not connected, an error message is displayed on UI self.label_Temp1.setText("Not Connected") else: #print('Temperature ={0:0.f}*'.format(temperature)) temp = temperature listB.append(temp) sum2 = sum(listB) #print(sum2) length2 = len(listB) average2 = (sum2 / length2) array_average2.append(average2) #print('Temp_average') #print(average2) self.label_AveB1.setText(str(average2)) b = 1 count2.append(b) counter2 = sum(count2) #print(counter2) #after ten entries the array is cleared if counter2 == 10: listB.clear() #print('waha') count2.clear() finally: #this function is called to display average temperature every 2.5 seconds QtCore.QTimer.singleShot(2500, self.average_temp) #function defined at clicking pushbutton1(Refresh) to display current temperature #in celsuis, farenheut and kelvin.The curent temp is displayed with a timestamp def on_pushButton1_clicked(self): timer_temp = (datetime.datetime.now().strftime('%H:%M:%S')) self.label_Time2.setText(str(timer_temp)) humidity, temperature = Adafruit_DHT.read(22, 4) #farenhiet=((temperature *9)/5 + 32) #for temperature conversion to farenhiet if temperature == None: #if sensor is not connected, an error message is displayed self.label_Temp1.setText("Not Connected") else: #print('Temp ={0:0.1f}*'.format(temperature)) self.label_Temp1.setText(str(temperature)) comp2 = self.lineEdit1.text() #print(comp2) if comp2 == None: self.label_AlertA.setText('Set Threshold') else: compare2 = int(comp2) if compare2 > temperature: self.label_AlertB.setText('Alert!') else: self.label_AlertB.setText('Normal!') temp = temperature listB.append(temp) #function defined at pushbutton clicked(Refresh) to display the current humidity.The humidity #is displayed with current timestamp def on_pushButton2_clicked(self): #displaying time stamp timer_hum = (datetime.datetime.now().strftime('%H:%M:%S')) self.label_Time1.setText(str(timer_hum)) humidity, temperature = Adafruit_DHT.read(22, 4) if humidity == None: #if the humidty sensor is not connected an error is displayed as not connected self.label_Hum1.setText("Not Connected") else: self.label_Hum1.setText(str(humidity)) #print('Humidity ={0:0.1f}%'.format(humidity)) hum = humidity listA.append(hum) comp1 = self.lineEdit.text() #print(comp1) #compare1 = int(comp1) if comp1 == None: self.label_AlertA.setText('Set Threshold') else: compare1 = int(comp1) if compare1 > humidity: self.label_AlertA.setText('Alert!') else: self.label_AlertA.setText('Normal!') #pushbutton 3 is used to display the current temperature in farenheit def on_pushButton3_clicked(self): humidity, temperature = Adafruit_DHT.read(22, 4) if temperature == None: self.label_Temp1.setText("Not Connected") else: farenhiet = ((temperature * 9) / 5 + 32) self.label_Temp1.setText(str(farenhiet)) #pushbutton 4 is used to display the current temperature in kelvin def on_pushButton4_clicked(self): humidity, temperature = Adafruit_DHT.read(22, 4) if temperature == None: self.label_Temp1.setText("Not Connected") else: kelvin = temperature + 273 self.label_Temp1.setText(str(kelvin)) #pushbutton 5 is clicked to display temperature in celsius def on_pushButton5_clicked(self): humidity, temperature = Adafruit_DHT.read(22, 4) if temperature == None: self.label_Temp1.setText("Not Connected") else: self.label_Temp1.setText(str(temperature))
def initWindow(self): QToolTip.setFont(QFont('SansSerif', 10)) # main layout frameWidget = QWidget() mainWidget = QSplitter(Qt.Horizontal) frameLayout = QVBoxLayout() self.settingWidget = QWidget() self.settingWidget.setProperty("class", "settingWidget") self.receiveSendWidget = QSplitter(Qt.Vertical) self.functionalWiget = QWidget() settingLayout = QVBoxLayout() sendReceiveLayout = QVBoxLayout() sendFunctionalLayout = QVBoxLayout() mainLayout = QHBoxLayout() self.settingWidget.setLayout(settingLayout) self.receiveSendWidget.setLayout(sendReceiveLayout) self.functionalWiget.setLayout(sendFunctionalLayout) mainLayout.addWidget(self.settingWidget) mainLayout.addWidget(self.receiveSendWidget) mainLayout.addWidget(self.functionalWiget) mainLayout.setStretch(0, 2) mainLayout.setStretch(1, 6) mainLayout.setStretch(2, 2) menuLayout = QHBoxLayout() mainWidget.setLayout(mainLayout) frameLayout.addLayout(menuLayout) frameLayout.addWidget(mainWidget) frameWidget.setLayout(frameLayout) self.setCentralWidget(frameWidget) # option layout self.settingsButton = QPushButton() self.skinButton = QPushButton("") # self.waveButton = QPushButton("") self.aboutButton = QPushButton() self.functionalButton = QPushButton() self.encodingCombobox = ComboBox() self.encodingCombobox.addItem("ASCII") self.encodingCombobox.addItem("UTF-8") self.encodingCombobox.addItem("UTF-16") self.encodingCombobox.addItem("GBK") self.encodingCombobox.addItem("GB2312") self.encodingCombobox.addItem("GB18030") self.settingsButton.setProperty("class", "menuItem1") self.skinButton.setProperty("class", "menuItem2") self.aboutButton.setProperty("class", "menuItem3") self.functionalButton.setProperty("class", "menuItem4") # self.waveButton.setProperty("class", "menuItem5") self.settingsButton.setObjectName("menuItem") self.skinButton.setObjectName("menuItem") self.aboutButton.setObjectName("menuItem") self.functionalButton.setObjectName("menuItem") # self.waveButton.setObjectName("menuItem") menuLayout.addWidget(self.settingsButton) menuLayout.addWidget(self.skinButton) # menuLayout.addWidget(self.waveButton) menuLayout.addWidget(self.aboutButton) menuLayout.addStretch(0) menuLayout.addWidget(self.encodingCombobox) menuLayout.addWidget(self.functionalButton) # widgets receive and send area self.receiveArea = QTextEdit() self.sendArea = QTextEdit() self.clearReceiveButtion = QPushButton(parameters.strClearReceive) self.sendButtion = QPushButton(parameters.strSend) self.sendHistory = ComboBox() sendWidget = QWidget() sendAreaWidgetsLayout = QHBoxLayout() sendWidget.setLayout(sendAreaWidgetsLayout) 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.addWidget(sendWidget) 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() self.serailBaudrateCombobox = ComboBox() 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 = ComboBox() self.serailBytesCombobox.addItem("5") self.serailBytesCombobox.addItem("6") self.serailBytesCombobox.addItem("7") self.serailBytesCombobox.addItem("8") self.serailBytesCombobox.setCurrentIndex(3) self.serailParityCombobox = ComboBox() 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 = ComboBox() self.serailStopbitsCombobox.addItem("1") self.serailStopbitsCombobox.addItem("1.5") self.serailStopbitsCombobox.addItem("2") self.serailStopbitsCombobox.setCurrentIndex(0) self.checkBoxRts = QCheckBox("rts") self.checkBoxDtr = QCheckBox("dtr") 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.checkBoxRts, 5, 0, 1, 1) serialSettingsLayout.addWidget(self.checkBoxDtr, 5, 1, 1, 1) serialSettingsLayout.addWidget(self.serialOpenCloseButton, 6, 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.filePathWidget = QLineEdit() self.openFileButton = QPushButton("Open File") self.sendFileButton = QPushButton("Send File") self.clearHistoryButton = QPushButton("Clear History") self.addButton = QPushButton(parameters.strAdd) fileSendGroupBox = QGroupBox(parameters.strSendFile) fileSendGridLayout = QGridLayout() fileSendGridLayout.addWidget(self.filePathWidget, 0, 0, 1, 1) fileSendGridLayout.addWidget(self.openFileButton, 0, 1, 1, 1) fileSendGridLayout.addWidget(self.sendFileButton, 1, 0, 1, 2) fileSendGroupBox.setLayout(fileSendGridLayout) sendFunctionalLayout.addWidget(fileSendGroupBox) sendFunctionalLayout.addWidget(self.clearHistoryButton) sendFunctionalLayout.addWidget(self.addButton) sendFunctionalLayout.addStretch(1) self.isHideFunctinal = True self.hideFunctional() # 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)) icon = QIcon() print("icon path:" + self.DataPath + "/" + parameters.appIcon) icon.addPixmap(QPixmap(self.DataPath + "/" + parameters.appIcon), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) if sys.platform == "win32": ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID( "comtool") self.show() print("config file path:", os.getcwd() + "/comtool.settings.config")
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.commandslist = [] self.tracker = 0 os.chdir(os.path.expanduser("~")) # print(os.getcwd()) self.name = (str(getpass.getuser()) + "@" + str(socket.gethostname()) + ":" + str(os.getcwd()) + "$ ") self.setWindowTitle('PyQt5Terminal') self.setWindowIcon(QIcon.fromTheme("terminal-emulator")) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) self.process.readyRead.connect(self.dataReady) self.process.readyReadStandardError.connect( self.onReadyReadStandardError) self.process.readyReadStandardOutput.connect( self.onReadyReadStandardOutput) self.process.finished.connect(self.isFinished) self.process.setWorkingDirectory(os.getcwd()) self.createStatusBar() self.commandfield = QPlainTextEdit() self.commandfield.setLineWrapMode(QPlainTextEdit.NoWrap) self.commandfield.setFixedHeight(44) self.commandfield.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.commandfield.setAcceptDrops(True) self.cursor = self.commandfield.textCursor() self.textWindow = QPlainTextEdit(self) self.setStyleSheet(mystylesheet(self)) self.textWindow.setReadOnly(True) layout = QVBoxLayout() layout.addWidget(self.textWindow) layout.addWidget(self.commandfield) self.wid = QWidget() self.wid.setLayout(layout) self.setCentralWidget(self.wid) self.setGeometry(0, 0, 600, 500) self.commandfield.setPlainText(self.name) self.cursorEnd() self.commandfield.setFocus() self.copySelectedTextAction = QAction(QIcon.fromTheme("edit-copy"), "Copy", shortcut="Shift+Ctrl+c", triggered=self.copyText) self.textWindow.addAction(self.copySelectedTextAction) self.pasteTextAction = QAction(QIcon.fromTheme("edit-paste"), "Copy", shortcut="Shift+Ctrl+v", triggered=self.pasteText) self.commandfield.addAction(self.pasteTextAction) # self.cancelAction = QAction("Cancel", shortcut="Ctrl+c", triggered=self.killProcess) self.textWindow.addAction(self.cancelAction) self.commandfield.installEventFilter(self) # self.textWindow.installEventFilter(self) QApplication.setCursorFlashTime(1000) self.cursorEnd() print(self.process.workingDirectory()) self.settings = QSettings("QTerminal", "QTerminal") self.readSettings() def closeEvent(self, e): self.writeSettings() def cursorEnd(self): self.name = (str(getpass.getuser()) + "@" + str(socket.gethostname()) + ":" + str(os.getcwd()) + "$ ") self.commandfield.setPlainText(self.name) cursor = self.commandfield.textCursor() cursor.movePosition(11, 0) self.commandfield.setTextCursor(cursor) self.commandfield.setFocus() def eventFilter(self, source, event): if source == self.commandfield: if (event.type() == QEvent.DragEnter): event.accept() return True elif (event.type() == QEvent.Drop): print('Drop') self.setDropEvent(event) return True elif (event.type() == QEvent.KeyPress): cursor = self.commandfield.textCursor() # print('key press:', (event.key(), event.text())) if event.key() == Qt.Key_Backspace: if cursor.positionInBlock() <= len(self.name): return True else: return False elif event.key() == Qt.Key_Return: self.run() return True elif event.key() == Qt.Key_Left: if cursor.positionInBlock() <= len(self.name): return True else: return False elif event.key() == Qt.Key_Delete: if cursor.positionInBlock() <= len(self.name) - 1: return True else: return False elif event.modifiers() == Qt.ControlModifier and event.key( ) == Qt.Key_C: self.killProcess() return True elif event.key() == Qt.Key_Up: try: if self.tracker != 0: cursor.select(QTextCursor.BlockUnderCursor) cursor.removeSelectedText() self.commandfield.appendPlainText(self.name) self.commandfield.insertPlainText( self.commandslist[self.tracker]) self.tracker -= 1 except IndexError: self.tracker = 0 return True elif event.key() == Qt.Key_Down: try: if self.tracker != 0: cursor.select(QTextCursor.BlockUnderCursor) cursor.removeSelectedText() self.commandfield.appendPlainText(self.name) self.commandfield.insertPlainText( self.commandslist[self.tracker]) self.tracker += 1 except IndexError: self.tracker = 0 return True else: return False else: return False else: return False def copyText(self): self.textWindow.copy() def pasteText(self): self.commandfield.paste() def killProcess(self): print("cancelled") self.process.kill() self.textWindow.appendPlainText("cancelled") self.cursorEnd() def createStatusBar(self): sysinfo = QSysInfo() myMachine = "current CPU Architecture: " + sysinfo.currentCpuArchitecture( ) + " *** " + sysinfo.prettyProductName( ) + " *** " + sysinfo.kernelType() + " " + sysinfo.kernelVersion() self.statusBar().showMessage(myMachine, 0) def setDropEvent(self, event): self.commandfield.setFocus() if event.mimeData().hasUrls(): f = str(event.mimeData().urls()[0].toLocalFile()) print("is file:", f) if " " in f: self.commandfield.insertPlainText("'{}'".format(f)) else: self.commandfield.insertPlainText(f) event.accept() elif event.mimeData().hasText(): ft = event.mimeData().text() print("is text:", ft) if " " in ft: self.commandfield.insertPlainText("'{}'".format(ft)) else: self.commandfield.insertPlainText(ft) else: event.ignore() def run(self): print("started") cli = [] cmd = "" t = "" self.textWindow.setFocus() self.textWindow.appendPlainText(self.commandfield.toPlainText()) cli = shlex.split(self.commandfield.toPlainText().replace( self.name, '').replace("'", '"'), posix=False) cmd = str(cli[0]) ### is the executable if cmd == "exit": quit() elif cmd == "cd": del cli[0] path = " ".join(cli) os.chdir(os.path.abspath(path)) self.process.setWorkingDirectory(os.getcwd()) print("workingDirectory:", self.process.workingDirectory()) self.cursorEnd() else: self.process.setWorkingDirectory(os.getcwd()) print("workingDirectory", self.process.workingDirectory()) del cli[0] if (QStandardPaths.findExecutable(cmd)): self.commandslist.append( self.commandfield.toPlainText().replace(self.name, "")) print("command", cmd, "found") t = " ".join(cli) if self.process.state() != 2: self.process.waitForStarted() self.process.waitForFinished() if "|" in t or ">" in t or "<" in t: print("special characters") self.process.start('sh -c "' + cmd + ' ' + t + '"') print("running", ('sh -c "' + cmd + ' ' + t + '"')) else: self.process.start(cmd + " " + t) print("running", (cmd + " " + t)) else: print("command not found ...") self.textWindow.appendPlainText("command not found ...") self.cursorEnd() def dataReady(self): out = "" try: out = str(self.process.readAll(), encoding='utf8').rstrip() except TypeError: out = str(self.process.readAll()).rstrip() self.textWindow.moveCursor(self.cursor.Start) ### changed self.textWindow.appendPlainText(out) def onReadyReadStandardError(self): self.error = self.process.readAllStandardError().data().decode() self.textWindow.appendPlainText(self.error.strip('\n')) self.cursorEnd() def onReadyReadStandardOutput(self): self.result = self.process.readAllStandardOutput().data().decode() self.textWindow.appendPlainText(self.result.strip('\n')) self.cursorEnd() self.state = self.process.state() def isFinished(self): print("finished") self.name = (str(getpass.getuser()) + "@" + str(socket.gethostname()) + ":" + str(os.getcwd()) + "$ ") self.commandfield.setPlainText(self.name) self.cursorEnd() def readSettings(self): if self.settings.contains("commands"): self.commandslist = self.settings.value("commands") if self.settings.contains("pos"): pos = self.settings.value("pos", QPoint(200, 200)) self.move(pos) if self.settings.contains("size"): size = self.settings.value("size", QSize(400, 400)) self.resize(size) def writeSettings(self): self.settings.setValue("commands", self.commandslist) self.settings.setValue("pos", self.pos()) self.settings.setValue("size", self.size())
class MainWindow(QMainWindow): def __init__(self): super().__init__() self.widget = QWidget(self) self.layout = QVBoxLayout() self.bottom_layout = QHBoxLayout() self.video_widget = QVideoWidget(self) self.media_player = QMediaPlayer() self.search_button = QPushButton("Buscar", self) self.play_button = QPushButton("Iniciar Vídeo", self) self.stop_button = QPushButton("Volver al principio", self) self.title_label = QLabel("", self) self.title_label.setStyleSheet( 'QLabel {background-color: black; color: green;}') #self.title_label.setFixedWidth(150) self.volume_label = QLabel("VOLUMEN:", self) self.play_button.setEnabled(False) self.stop_button.setEnabled(False) self.seek_slider = QSlider(Qt.Horizontal) self.volume_slider = QSlider(Qt.Horizontal) self.volume_slider.setRange(0, 100) self.volume_slider.setValue(self.media_player.volume()) self.seek_slider.sliderMoved.connect(self.media_player.setPosition) self.volume_slider.sliderMoved.connect(self.media_player.setVolume) self.media_player.positionChanged.connect(self.seek_slider.setValue) self.media_player.durationChanged.connect( partial(self.seek_slider.setRange, 0)) self.layout.addWidget(self.video_widget) self.layout.addLayout(self.bottom_layout) self.bottom_layout.addWidget(self.search_button) self.bottom_layout.addWidget(self.title_label) self.bottom_layout.addWidget(self.play_button) self.bottom_layout.addWidget(self.stop_button) self.bottom_layout.addWidget(self.volume_label) self.bottom_layout.addWidget(self.volume_slider) self.layout.addWidget(self.seek_slider) self.search_button.clicked.connect(self.openFile) self.play_button.clicked.connect(self.play_clicked) self.stop_button.clicked.connect(self.stop_clicked) self.media_player.stateChanged.connect(self.state_changed) self.video_widget.installEventFilter(self) self.setWindowTitle("Reproductor de video") self.resize(800, 600) self.layout.setContentsMargins(0, 0, 0, 0) self.bottom_layout.setContentsMargins(0, 0, 0, 0) self.widget.setLayout(self.layout) self.setCentralWidget(self.widget) self.active_timer = False def move_text(self): if self.text != "": lista = list(self.text) dele = lista.pop(0) lista.append(dele) tf = "".join(lista) self.title_label.setText(tf) self.text = tf def play_clicked(self): if (self.media_player.state() in (QMediaPlayer.PausedState, QMediaPlayer.StoppedState)): self.media_player.play() else: self.media_player.pause() def stop_clicked(self): self.media_player.stop() def state_changed(self, newstate): states = { QMediaPlayer.PausedState: "Continuar", QMediaPlayer.PlayingState: "Pausa", QMediaPlayer.StoppedState: "Reproducir" } self.play_button.setText(states[newstate]) self.stop_button.setEnabled(newstate != QMediaPlayer.StoppedState) def eventFilter(self, obj, event): if event.type() == QEvent.MouseButtonDblClick: obj.setFullScreen(not obj.isFullScreen()) return False def openFile(self): fileName, _ = QFileDialog.getOpenFileName(self, "Archivo de video", '/home') if fileName != '': timer = QTimer(self) self.videoName = fileName.split("/")[-1] self.text = "-" + self.videoName + "-" if self.active_timer == False: timer.timeout.connect(self.move_text) self.active_timer = True timer.start(650) VIDEO_PATH = fileName self.media_player.setMedia( QMediaContent(QUrl.fromLocalFile(VIDEO_PATH))) self.media_player.setVideoOutput(self.video_widget) self.play_button.setEnabled(True) self.stop_button.setEnabled(True)
class InstallWizard(QDialog, MessageBoxMixin, BaseWizard): accept_signal = pyqtSignal() def __init__(self, config: 'SimpleConfig', app: QApplication, plugins: 'Plugins', *, gui_object: 'ElectrumGui'): QDialog.__init__(self, None) BaseWizard.__init__(self, config, plugins) self.setWindowTitle('Electrum - ' + _('Install Wizard')) self.app = app self.config = config self.gui_thread = gui_object.gui_thread self.setMinimumSize(600, 400) self.accept_signal.connect(self.accept) self.title = QLabel() self.main_widget = QWidget() self.back_button = QPushButton(_("Back"), self) self.back_button.setText(_('Back') if self.can_go_back() else _('Cancel')) self.next_button = QPushButton(_("Next"), self) self.next_button.setDefault(True) self.logo = QLabel() self.please_wait = QLabel(_("Please wait...")) self.please_wait.setAlignment(Qt.AlignCenter) self.icon_filename = None self.loop = QEventLoop() self.rejected.connect(lambda: self.loop.exit(0)) self.back_button.clicked.connect(lambda: self.loop.exit(1)) self.next_button.clicked.connect(lambda: self.loop.exit(2)) outer_vbox = QVBoxLayout(self) inner_vbox = QVBoxLayout() inner_vbox.addWidget(self.title) inner_vbox.addWidget(self.main_widget) inner_vbox.addStretch(1) inner_vbox.addWidget(self.please_wait) inner_vbox.addStretch(1) scroll_widget = QWidget() scroll_widget.setLayout(inner_vbox) scroll = QScrollArea() scroll.setWidget(scroll_widget) scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) scroll.setWidgetResizable(True) icon_vbox = QVBoxLayout() icon_vbox.addWidget(self.logo) icon_vbox.addStretch(1) hbox = QHBoxLayout() hbox.addLayout(icon_vbox) hbox.addSpacing(5) hbox.addWidget(scroll) hbox.setStretchFactor(scroll, 1) outer_vbox.addLayout(hbox) outer_vbox.addLayout(Buttons(self.back_button, self.next_button)) self.set_icon('electrum.png') self.show() self.raise_() self.refresh_gui() # Need for QT on MacOSX. Lame. def select_storage(self, path, get_wallet_from_daemon) -> Tuple[str, Optional[WalletStorage]]: vbox = QVBoxLayout() hbox = QHBoxLayout() hbox.addWidget(QLabel(_('Wallet') + ':')) name_e = QLineEdit() hbox.addWidget(name_e) button = QPushButton(_('Choose...')) hbox.addWidget(button) vbox.addLayout(hbox) msg_label = WWLabel('') vbox.addWidget(msg_label) hbox2 = QHBoxLayout() pw_e = PasswordLineEdit('', self) pw_e.setFixedWidth(17 * char_width_in_lineedit()) pw_label = QLabel(_('Password') + ':') hbox2.addWidget(pw_label) hbox2.addWidget(pw_e) hbox2.addStretch() vbox.addLayout(hbox2) vbox.addSpacing(50) vbox_create_new = QVBoxLayout() vbox_create_new.addWidget(QLabel(_('Alternatively') + ':'), alignment=Qt.AlignLeft) button_create_new = QPushButton(_('Create New Wallet')) button_create_new.setMinimumWidth(120) vbox_create_new.addWidget(button_create_new, alignment=Qt.AlignLeft) widget_create_new = QWidget() widget_create_new.setLayout(vbox_create_new) vbox_create_new.setContentsMargins(0, 0, 0, 0) vbox.addWidget(widget_create_new) self.set_layout(vbox, title=_('Electrum wallet')) temp_storage = None # type: Optional[WalletStorage] wallet_folder = os.path.dirname(path) def on_choose(): path, __ = QFileDialog.getOpenFileName(self, "Select your wallet file", wallet_folder) if path: name_e.setText(path) def on_filename(filename): # FIXME? "filename" might contain ".." (etc) and hence sketchy path traversals are possible nonlocal temp_storage temp_storage = None msg = None path = os.path.join(wallet_folder, filename) wallet_from_memory = get_wallet_from_daemon(path) try: if wallet_from_memory: temp_storage = wallet_from_memory.storage # type: Optional[WalletStorage] else: temp_storage = WalletStorage(path) except (StorageReadWriteError, WalletFileException) as e: msg = _('Cannot read file') + f'\n{repr(e)}' except Exception as e: self.logger.exception('') msg = _('Cannot read file') + f'\n{repr(e)}' self.next_button.setEnabled(temp_storage is not None) user_needs_to_enter_password = False if temp_storage: if not temp_storage.file_exists(): msg =_("This file does not exist.") + '\n' \ + _("Press 'Next' to create this wallet, or choose another file.") elif not wallet_from_memory: if temp_storage.is_encrypted_with_user_pw(): msg = _("This file is encrypted with a password.") + '\n' \ + _('Enter your password or choose another file.') user_needs_to_enter_password = True elif temp_storage.is_encrypted_with_hw_device(): msg = _("This file is encrypted using a hardware device.") + '\n' \ + _("Press 'Next' to choose device to decrypt.") else: msg = _("Press 'Next' to open this wallet.") else: msg = _("This file is already open in memory.") + "\n" \ + _("Press 'Next' to create/focus window.") if msg is None: msg = _('Cannot read file') msg_label.setText(msg) widget_create_new.setVisible(bool(temp_storage and temp_storage.file_exists())) if user_needs_to_enter_password: pw_label.show() pw_e.show() pw_e.setFocus() else: pw_label.hide() pw_e.hide() button.clicked.connect(on_choose) button_create_new.clicked.connect( partial( name_e.setText, get_new_wallet_name(wallet_folder))) name_e.textChanged.connect(on_filename) name_e.setText(os.path.basename(path)) def run_user_interaction_loop(): while True: if self.loop.exec_() != 2: # 2 = next raise UserCancelled() assert temp_storage if temp_storage.file_exists() and not temp_storage.is_encrypted(): break if not temp_storage.file_exists(): break wallet_from_memory = get_wallet_from_daemon(temp_storage.path) if wallet_from_memory: raise WalletAlreadyOpenInMemory(wallet_from_memory) if temp_storage.file_exists() and temp_storage.is_encrypted(): if temp_storage.is_encrypted_with_user_pw(): password = pw_e.text() try: temp_storage.decrypt(password) break except InvalidPassword as e: self.show_message(title=_('Error'), msg=str(e)) continue except BaseException as e: self.logger.exception('') self.show_message(title=_('Error'), msg=repr(e)) raise UserCancelled() elif temp_storage.is_encrypted_with_hw_device(): try: self.run('choose_hw_device', HWD_SETUP_DECRYPT_WALLET, storage=temp_storage) except InvalidPassword as e: self.show_message(title=_('Error'), msg=_('Failed to decrypt using this hardware device.') + '\n' + _('If you use a passphrase, make sure it is correct.')) self.reset_stack() return self.select_storage(path, get_wallet_from_daemon) except (UserCancelled, GoBack): raise except BaseException as e: self.logger.exception('') self.show_message(title=_('Error'), msg=repr(e)) raise UserCancelled() if temp_storage.is_past_initial_decryption(): break else: raise UserCancelled() else: raise Exception('Unexpected encryption version') try: run_user_interaction_loop() finally: try: pw_e.clear() except RuntimeError: # wrapped C/C++ object has been deleted. pass # happens when decrypting with hw device return temp_storage.path, (temp_storage if temp_storage.file_exists() else None) def run_upgrades(self, storage: WalletStorage, db: 'WalletDB') -> None: path = storage.path if db.requires_split(): self.hide() msg = _("The wallet '{}' contains multiple accounts, which are no longer supported since Electrum 2.7.\n\n" "Do you want to split your wallet into multiple files?").format(path) if not self.question(msg): return file_list = db.split_accounts(path) msg = _('Your accounts have been moved to') + ':\n' + '\n'.join(file_list) + '\n\n'+ _('Do you want to delete the old file') + ':\n' + path if self.question(msg): os.remove(path) self.show_warning(_('The file was removed')) # raise now, to avoid having the old storage opened raise UserCancelled() action = db.get_action() if action and db.requires_upgrade(): raise WalletFileException('Incomplete wallet files cannot be upgraded.') if action: self.hide() msg = _("The file '{}' contains an incompletely created wallet.\n" "Do you want to complete its creation now?").format(path) if not self.question(msg): if self.question(_("Do you want to delete '{}'?").format(path)): os.remove(path) self.show_warning(_('The file was removed')) return self.show() self.data = json.loads(storage.read()) self.run(action) for k, v in self.data.items(): db.put(k, v) db.write(storage) return if db.requires_upgrade(): self.upgrade_db(storage, db) def on_error(self, exc_info): if not isinstance(exc_info[1], UserCancelled): self.logger.error("on_error", exc_info=exc_info) self.show_error(str(exc_info[1])) def set_icon(self, filename): prior_filename, self.icon_filename = self.icon_filename, filename self.logo.setPixmap(QPixmap(icon_path(filename)) .scaledToWidth(60, mode=Qt.SmoothTransformation)) return prior_filename def set_layout(self, layout, title=None, next_enabled=True): self.title.setText("<b>%s</b>"%title if title else "") self.title.setVisible(bool(title)) # Get rid of any prior layout by assigning it to a temporary widget prior_layout = self.main_widget.layout() if prior_layout: QWidget().setLayout(prior_layout) self.main_widget.setLayout(layout) self.back_button.setEnabled(True) self.next_button.setEnabled(next_enabled) if next_enabled: self.next_button.setFocus() self.main_widget.setVisible(True) self.please_wait.setVisible(False) def exec_layout(self, layout, title=None, raise_on_cancel=True, next_enabled=True): self.set_layout(layout, title, next_enabled) result = self.loop.exec_() if not result and raise_on_cancel: raise UserCancelled() if result == 1: raise GoBack from None self.title.setVisible(False) self.back_button.setEnabled(False) self.next_button.setEnabled(False) self.main_widget.setVisible(False) self.please_wait.setVisible(True) self.refresh_gui() return result def refresh_gui(self): # For some reason, to refresh the GUI this needs to be called twice self.app.processEvents() self.app.processEvents() def remove_from_recently_open(self, filename): self.config.remove_from_recently_open(filename) def text_input(self, title, message, is_valid, allow_multi=False): slayout = KeysLayout(parent=self, header_layout=message, is_valid=is_valid, allow_multi=allow_multi, config=self.config) self.exec_layout(slayout, title, next_enabled=False) return slayout.get_text() def seed_input(self, title, message, is_seed, options): slayout = SeedLayout( title=message, is_seed=is_seed, options=options, parent=self, config=self.config, ) self.exec_layout(slayout, title, next_enabled=False) return slayout.get_seed(), slayout.is_bip39, slayout.is_ext @wizard_dialog def add_xpub_dialog(self, title, message, is_valid, run_next, allow_multi=False, show_wif_help=False): header_layout = QHBoxLayout() label = WWLabel(message) label.setMinimumWidth(400) header_layout.addWidget(label) if show_wif_help: header_layout.addWidget(InfoButton(WIF_HELP_TEXT), alignment=Qt.AlignRight) return self.text_input(title, header_layout, is_valid, allow_multi) @wizard_dialog def add_cosigner_dialog(self, run_next, index, is_valid): title = _("Add Cosigner") + " %d"%index message = ' '.join([ _('Please enter the master public key (xpub) of your cosigner.'), _('Enter their master private key (xprv) if you want to be able to sign for them.') ]) return self.text_input(title, message, is_valid) @wizard_dialog def restore_seed_dialog(self, run_next, test): options = [] if self.opt_ext: options.append('ext') if self.opt_bip39: options.append('bip39') title = _('Enter Seed') message = _('Please enter your seed phrase in order to restore your wallet.') return self.seed_input(title, message, test, options) @wizard_dialog def confirm_seed_dialog(self, run_next, seed, test): self.app.clipboard().clear() title = _('Confirm Seed') message = ' '.join([ _('Your seed is important!'), _('If you lose your seed, your money will be permanently lost.'), _('To make sure that you have properly saved your seed, please retype it here.') ]) seed, is_bip39, is_ext = self.seed_input(title, message, test, None) return seed @wizard_dialog def show_seed_dialog(self, run_next, seed_text): title = _("Your wallet generation seed is:") slayout = SeedLayout( seed=seed_text, title=title, msg=True, options=['ext'], config=self.config, ) self.exec_layout(slayout) return slayout.is_ext def pw_layout(self, msg, kind, force_disable_encrypt_cb): playout = PasswordLayout(msg=msg, kind=kind, OK_button=self.next_button, force_disable_encrypt_cb=force_disable_encrypt_cb) playout.encrypt_cb.setChecked(True) try: self.exec_layout(playout.layout()) return playout.new_password(), playout.encrypt_cb.isChecked() finally: playout.clear_password_fields() @wizard_dialog def request_password(self, run_next, force_disable_encrypt_cb=False): """Request the user enter a new password and confirm it. Return the password or None for no password.""" return self.pw_layout(MSG_ENTER_PASSWORD, PW_NEW, force_disable_encrypt_cb) @wizard_dialog def request_storage_encryption(self, run_next): playout = PasswordLayoutForHW(MSG_HW_STORAGE_ENCRYPTION) playout.encrypt_cb.setChecked(True) self.exec_layout(playout.layout()) return playout.encrypt_cb.isChecked() @wizard_dialog def confirm_dialog(self, title, message, run_next): self.confirm(message, title) def confirm(self, message, title): label = WWLabel(message) vbox = QVBoxLayout() vbox.addWidget(label) self.exec_layout(vbox, title) @wizard_dialog def action_dialog(self, action, run_next): self.run(action) def terminate(self, **kwargs): self.accept_signal.emit() def waiting_dialog(self, task, msg, on_finished=None): label = WWLabel(msg) vbox = QVBoxLayout() vbox.addSpacing(100) label.setMinimumWidth(300) label.setAlignment(Qt.AlignCenter) vbox.addWidget(label) self.set_layout(vbox, next_enabled=False) self.back_button.setEnabled(False) t = threading.Thread(target=task) t.start() while True: t.join(1.0/60) if t.is_alive(): self.refresh_gui() else: break if on_finished: on_finished() def run_task_without_blocking_gui(self, task, *, msg=None): assert self.gui_thread == threading.current_thread(), 'must be called from GUI thread' if msg is None: msg = _("Please wait...") exc = None # type: Optional[Exception] res = None def task_wrapper(): nonlocal exc nonlocal res try: res = task() except Exception as e: exc = e self.waiting_dialog(task_wrapper, msg=msg) if exc is None: return res else: raise exc @wizard_dialog def choice_dialog(self, title, message, choices, run_next): c_values = [x[0] for x in choices] c_titles = [x[1] for x in choices] clayout = ChoicesLayout(message, c_titles) vbox = QVBoxLayout() vbox.addLayout(clayout.layout()) self.exec_layout(vbox, title) action = c_values[clayout.selected_index()] return action def query_choice(self, msg, choices): """called by hardware wallets""" clayout = ChoicesLayout(msg, choices) vbox = QVBoxLayout() vbox.addLayout(clayout.layout()) self.exec_layout(vbox, '') return clayout.selected_index() @wizard_dialog def derivation_and_script_type_gui_specific_dialog( self, *, title: str, message1: str, choices: List[Tuple[str, str, str]], hide_choices: bool = False, message2: str, test_text: Callable[[str], int], run_next, default_choice_idx: int = 0, get_account_xpub=None, ) -> Tuple[str, str]: vbox = QVBoxLayout() if get_account_xpub: button = QPushButton(_("Detect Existing Accounts")) def on_account_select(account): script_type = account["script_type"] if script_type == "p2pkh": script_type = "standard" button_index = c_values.index(script_type) button = clayout.group.buttons()[button_index] button.setChecked(True) line.setText(account["derivation_path"]) button.clicked.connect(lambda: Bip39RecoveryDialog(self, get_account_xpub, on_account_select)) vbox.addWidget(button, alignment=Qt.AlignLeft) vbox.addWidget(QLabel(_("Or"))) c_values = [x[0] for x in choices] c_titles = [x[1] for x in choices] c_default_text = [x[2] for x in choices] def on_choice_click(clayout): idx = clayout.selected_index() line.setText(c_default_text[idx]) clayout = ChoicesLayout(message1, c_titles, on_choice_click, checked_index=default_choice_idx) if not hide_choices: vbox.addLayout(clayout.layout()) vbox.addWidget(WWLabel(message2)) line = QLineEdit() def on_text_change(text): self.next_button.setEnabled(test_text(text)) line.textEdited.connect(on_text_change) on_choice_click(clayout) # set default text for "line" vbox.addWidget(line) self.exec_layout(vbox, title) choice = c_values[clayout.selected_index()] return str(line.text()), choice @wizard_dialog def line_dialog(self, run_next, title, message, default, test, warning='', presets=(), warn_issue4566=False): vbox = QVBoxLayout() vbox.addWidget(WWLabel(message)) line = QLineEdit() line.setText(default) def f(text): self.next_button.setEnabled(test(text)) if warn_issue4566: text_whitespace_normalised = ' '.join(text.split()) warn_issue4566_label.setVisible(text != text_whitespace_normalised) line.textEdited.connect(f) vbox.addWidget(line) vbox.addWidget(WWLabel(warning)) warn_issue4566_label = WWLabel(MSG_PASSPHRASE_WARN_ISSUE4566) warn_issue4566_label.setVisible(False) vbox.addWidget(warn_issue4566_label) for preset in presets: button = QPushButton(preset[0]) button.clicked.connect(lambda __, text=preset[1]: line.setText(text)) button.setMinimumWidth(150) hbox = QHBoxLayout() hbox.addWidget(button, alignment=Qt.AlignCenter) vbox.addLayout(hbox) self.exec_layout(vbox, title, next_enabled=test(default)) return line.text() @wizard_dialog def show_xpub_dialog(self, xpub, run_next): msg = ' '.join([ _("Here is your master public key."), _("Please share it with your cosigners.") ]) vbox = QVBoxLayout() layout = SeedLayout( xpub, title=msg, icon=False, for_seed_words=False, config=self.config, ) vbox.addLayout(layout.layout()) self.exec_layout(vbox, _('Master Public Key')) return None def init_network(self, network: 'Network'): message = _("Electrum communicates with remote servers to get " "information about your transactions and addresses. The " "servers all fulfill the same purpose only differing in " "hardware. In most cases you simply want to let Electrum " "pick one at random. However if you prefer feel free to " "select a server manually.") choices = [_("Auto connect"), _("Select server manually")] title = _("How do you want to connect to a server? ") clayout = ChoicesLayout(message, choices) self.back_button.setText(_('Cancel')) self.exec_layout(clayout.layout(), title) r = clayout.selected_index() if r == 1: nlayout = NetworkChoiceLayout(network, self.config, wizard=True) if self.exec_layout(nlayout.layout()): nlayout.accept() self.config.set_key('auto_connect', network.auto_connect, True) else: network.auto_connect = True self.config.set_key('auto_connect', True, True) @wizard_dialog def multisig_dialog(self, run_next): cw = CosignWidget(2, 2) m_edit = QSlider(Qt.Horizontal, self) n_edit = QSlider(Qt.Horizontal, self) n_edit.setMinimum(2) n_edit.setMaximum(15) m_edit.setMinimum(1) m_edit.setMaximum(2) n_edit.setValue(2) m_edit.setValue(2) n_label = QLabel() m_label = QLabel() grid = QGridLayout() grid.addWidget(n_label, 0, 0) grid.addWidget(n_edit, 0, 1) grid.addWidget(m_label, 1, 0) grid.addWidget(m_edit, 1, 1) def on_m(m): m_label.setText(_('Require {0} signatures').format(m)) cw.set_m(m) backup_warning_label.setVisible(cw.m != cw.n) def on_n(n): n_label.setText(_('From {0} cosigners').format(n)) cw.set_n(n) m_edit.setMaximum(n) backup_warning_label.setVisible(cw.m != cw.n) n_edit.valueChanged.connect(on_n) m_edit.valueChanged.connect(on_m) vbox = QVBoxLayout() vbox.addWidget(cw) vbox.addWidget(WWLabel(_("Choose the number of signatures needed to unlock funds in your wallet:"))) vbox.addLayout(grid) vbox.addSpacing(2 * char_width_in_lineedit()) backup_warning_label = WWLabel(_("Warning: to be able to restore a multisig wallet, " "you should include the master public key for each cosigner " "in all of your backups.")) vbox.addWidget(backup_warning_label) on_n(2) on_m(2) self.exec_layout(vbox, _("Multi-Signature Wallet")) m = int(m_edit.value()) n = int(n_edit.value()) return (m, n)
def __init__(self): super(MainWindow, self).__init__() self.commandslist = [] self.tracker = 0 os.chdir(os.path.expanduser("~")) # print(os.getcwd()) self.name = (str(getpass.getuser()) + "@" + str(socket.gethostname()) + ":" + str(os.getcwd()) + "$ ") self.setWindowTitle('PyQt5Terminal') self.setWindowIcon(QIcon.fromTheme("terminal-emulator")) self.process = QProcess(self) self.process.setProcessChannelMode(QProcess.MergedChannels) self.process.readyRead.connect(self.dataReady) self.process.readyReadStandardError.connect( self.onReadyReadStandardError) self.process.readyReadStandardOutput.connect( self.onReadyReadStandardOutput) self.process.finished.connect(self.isFinished) self.process.setWorkingDirectory(os.getcwd()) self.createStatusBar() self.commandfield = QPlainTextEdit() self.commandfield.setLineWrapMode(QPlainTextEdit.NoWrap) self.commandfield.setFixedHeight(44) self.commandfield.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.commandfield.setAcceptDrops(True) self.cursor = self.commandfield.textCursor() self.textWindow = QPlainTextEdit(self) self.setStyleSheet(mystylesheet(self)) self.textWindow.setReadOnly(True) layout = QVBoxLayout() layout.addWidget(self.textWindow) layout.addWidget(self.commandfield) self.wid = QWidget() self.wid.setLayout(layout) self.setCentralWidget(self.wid) self.setGeometry(0, 0, 600, 500) self.commandfield.setPlainText(self.name) self.cursorEnd() self.commandfield.setFocus() self.copySelectedTextAction = QAction(QIcon.fromTheme("edit-copy"), "Copy", shortcut="Shift+Ctrl+c", triggered=self.copyText) self.textWindow.addAction(self.copySelectedTextAction) self.pasteTextAction = QAction(QIcon.fromTheme("edit-paste"), "Copy", shortcut="Shift+Ctrl+v", triggered=self.pasteText) self.commandfield.addAction(self.pasteTextAction) # self.cancelAction = QAction("Cancel", shortcut="Ctrl+c", triggered=self.killProcess) self.textWindow.addAction(self.cancelAction) self.commandfield.installEventFilter(self) # self.textWindow.installEventFilter(self) QApplication.setCursorFlashTime(1000) self.cursorEnd() print(self.process.workingDirectory()) self.settings = QSettings("QTerminal", "QTerminal") self.readSettings()
class ResultHandler(QDialog): def __init__(self, parent=None): super(ResultHandler, self).__init__() self.setWindowTitle('Dash results') self.control_label = QLabel() self.rendered_label = QLabel() self.diff_label = QLabel() self.mask_label = QLabel() self.new_mask_label = QLabel() self.scrollArea = QScrollArea() self.widget = QWidget() self.test_name_label = QLabel() grid = QGridLayout() grid.addWidget(self.test_name_label, 0, 0) grid.addWidget(QLabel('Control'), 1, 0) grid.addWidget(QLabel('Rendered'), 1, 1) grid.addWidget(QLabel('Difference'), 1, 2) grid.addWidget(self.control_label, 2, 0) grid.addWidget(self.rendered_label, 2, 1) grid.addWidget(self.diff_label, 2, 2) grid.addWidget(QLabel('Current Mask'), 3, 0) grid.addWidget(QLabel('New Mask'), 3, 1) grid.addWidget(self.mask_label, 4, 0) grid.addWidget(self.new_mask_label, 4, 1) self.widget.setLayout(grid) self.scrollArea.setWidget(self.widget) v_layout = QVBoxLayout() v_layout.addWidget(self.scrollArea, 1) next_image_button = QPushButton() next_image_button.setText('Skip') next_image_button.pressed.connect(self.load_next) self.overload_spin = QDoubleSpinBox() self.overload_spin.setMinimum(1) self.overload_spin.setMaximum(255) self.overload_spin.setValue(1) self.overload_spin.valueChanged.connect( lambda: save_mask_button.setEnabled(False)) preview_mask_button = QPushButton() preview_mask_button.setText('Preview New Mask') preview_mask_button.pressed.connect(self.preview_mask) preview_mask_button.pressed.connect( lambda: save_mask_button.setEnabled(True)) save_mask_button = QPushButton() save_mask_button.setText('Save New Mask') save_mask_button.pressed.connect(self.save_mask) button_layout = QHBoxLayout() button_layout.addWidget(next_image_button) button_layout.addWidget(QLabel('Mask diff multiplier:')) button_layout.addWidget(self.overload_spin) button_layout.addWidget(preview_mask_button) button_layout.addWidget(save_mask_button) button_layout.addStretch() v_layout.addLayout(button_layout) self.setLayout(v_layout) def closeEvent(self, event): self.reject() def parse_url(self, url): print('Fetching dash results from: {}'.format(url)) page = urllib.request.urlopen(url) soup = BeautifulSoup(page, "lxml") # build up list of rendered images measurement_img = [ img for img in soup.find_all('img') if img.get('alt') and img.get('alt').startswith('Rendered Image') ] images = {} for img in measurement_img: m = re.search('Rendered Image (.*?)(\s|$)', img.get('alt')) test_name = m.group(1) rendered_image = img.get('src') images[test_name] = '{}/{}'.format(dash_url, rendered_image) if images: print('found images:\n{}'.format(images)) else: print('no images found\n') self.images = images self.load_next() def load_next(self): if not self.images: # all done self.accept() exit(0) test_name, rendered_image = self.images.popitem() self.test_name_label.setText(test_name) control_image = self.get_control_image_path(test_name) if not control_image: self.load_next() return self.mask_image_path = control_image[:-4] + '_mask.png' self.load_images(control_image, rendered_image, self.mask_image_path) def load_images(self, control_image_path, rendered_image_path, mask_image_path): self.control_image = imageFromPath(control_image_path) if not self.control_image: error('Could not read control image {}'.format(control_image_path)) self.rendered_image = imageFromPath(rendered_image_path) if not self.rendered_image: error( 'Could not read rendered image {}'.format(rendered_image_path)) if not self.rendered_image.width() == self.control_image.width( ) or not self.rendered_image.height() == self.control_image.height(): print( 'Size mismatch - control image is {}x{}, rendered image is {}x{}' .format(self.control_image.width(), self.control_image.height(), self.rendered_image.width(), self.rendered_image.height())) max_width = min(self.rendered_image.width(), self.control_image.width()) max_height = min(self.rendered_image.height(), self.control_image.height()) # read current mask, if it exist self.mask_image = imageFromPath(mask_image_path) if self.mask_image.isNull(): print('Mask image does not exist, creating {}'.format( mask_image_path)) self.mask_image = QImage(self.control_image.width(), self.control_image.height(), QImage.Format_ARGB32) self.mask_image.fill(QColor(0, 0, 0)) self.diff_image = self.create_diff_image(self.control_image, self.rendered_image, self.mask_image) if not self.diff_image: self.load_next() return self.control_label.setPixmap(QPixmap.fromImage(self.control_image)) self.rendered_label.setPixmap(QPixmap.fromImage(self.rendered_image)) self.mask_label.setPixmap(QPixmap.fromImage(self.mask_image)) self.diff_label.setPixmap(QPixmap.fromImage(self.diff_image)) self.preview_mask() def preview_mask(self): self.new_mask_image = self.create_mask(self.control_image, self.rendered_image, self.mask_image, self.overload_spin.value()) self.new_mask_label.setPixmap(QPixmap.fromImage(self.new_mask_image)) def save_mask(self): self.new_mask_image.save(self.mask_image_path, "png") self.load_next() def create_mask(self, control_image, rendered_image, mask_image, overload=1): max_width = min(rendered_image.width(), control_image.width()) max_height = min(rendered_image.height(), control_image.height()) new_mask_image = QImage(control_image.width(), control_image.height(), QImage.Format_ARGB32) new_mask_image.fill(QColor(0, 0, 0)) # loop through pixels in rendered image and compare mismatch_count = 0 linebytes = max_width * 4 for y in range(max_height): control_scanline = control_image.constScanLine(y).asstring( linebytes) rendered_scanline = rendered_image.constScanLine(y).asstring( linebytes) mask_scanline = mask_image.scanLine(y).asstring(linebytes) for x in range(max_width): currentTolerance = qRed( struct.unpack('I', mask_scanline[x * 4:x * 4 + 4])[0]) if currentTolerance == 255: # ignore pixel new_mask_image.setPixel( x, y, qRgb(currentTolerance, currentTolerance, currentTolerance)) continue expected_rgb = struct.unpack( 'I', control_scanline[x * 4:x * 4 + 4])[0] rendered_rgb = struct.unpack( 'I', rendered_scanline[x * 4:x * 4 + 4])[0] difference = min( 255, colorDiff(expected_rgb, rendered_rgb) * overload) if difference > currentTolerance: # update mask image new_mask_image.setPixel( x, y, qRgb(difference, difference, difference)) mismatch_count += 1 else: new_mask_image.setPixel( x, y, qRgb(currentTolerance, currentTolerance, currentTolerance)) return new_mask_image def get_control_image_path(self, test_name): if os.path.isfile(test_name): return path # else try and find matching test image script_folder = os.path.dirname(os.path.realpath(sys.argv[0])) control_images_folder = os.path.join( script_folder, '../tests/testdata/control_images') matching_control_images = [ x[0] for x in os.walk(control_images_folder) if test_name in x[0] ] if len(matching_control_images) > 1: QMessageBox.warning( self, 'Result', 'Found multiple matching control images for {}'.format( test_name)) return None elif len(matching_control_images) == 0: QMessageBox.warning( self, 'Result', 'No matching control images found for {}'.format(test_name)) return None found_control_image_path = matching_control_images[0] # check for a single matching expected image images = glob.glob(os.path.join(found_control_image_path, '*.png')) filtered_images = [i for i in images if not i[-9:] == '_mask.png'] if len(filtered_images) > 1: error('Found multiple matching control images for {}'.format( test_name)) elif len(filtered_images) == 0: error('No matching control images found for {}'.format(test_name)) found_image = filtered_images[0] print('Found matching control image: {}'.format(found_image)) return found_image def create_diff_image(self, control_image, rendered_image, mask_image): # loop through pixels in rendered image and compare mismatch_count = 0 max_width = min(rendered_image.width(), control_image.width()) max_height = min(rendered_image.height(), control_image.height()) linebytes = max_width * 4 diff_image = QImage(control_image.width(), control_image.height(), QImage.Format_ARGB32) diff_image.fill(QColor(152, 219, 249)) for y in range(max_height): control_scanline = control_image.constScanLine(y).asstring( linebytes) rendered_scanline = rendered_image.constScanLine(y).asstring( linebytes) mask_scanline = mask_image.scanLine(y).asstring(linebytes) for x in range(max_width): currentTolerance = qRed( struct.unpack('I', mask_scanline[x * 4:x * 4 + 4])[0]) if currentTolerance == 255: # ignore pixel continue expected_rgb = struct.unpack( 'I', control_scanline[x * 4:x * 4 + 4])[0] rendered_rgb = struct.unpack( 'I', rendered_scanline[x * 4:x * 4 + 4])[0] difference = colorDiff(expected_rgb, rendered_rgb) if difference > currentTolerance: # update mask image diff_image.setPixel(x, y, qRgb(255, 0, 0)) mismatch_count += 1 if mismatch_count: return diff_image else: print('No mismatches') return None
def select_storage(self, path, get_wallet_from_daemon) -> Tuple[str, Optional[WalletStorage]]: vbox = QVBoxLayout() hbox = QHBoxLayout() hbox.addWidget(QLabel(_('Wallet') + ':')) name_e = QLineEdit() hbox.addWidget(name_e) button = QPushButton(_('Choose...')) hbox.addWidget(button) vbox.addLayout(hbox) msg_label = WWLabel('') vbox.addWidget(msg_label) hbox2 = QHBoxLayout() pw_e = PasswordLineEdit('', self) pw_e.setFixedWidth(17 * char_width_in_lineedit()) pw_label = QLabel(_('Password') + ':') hbox2.addWidget(pw_label) hbox2.addWidget(pw_e) hbox2.addStretch() vbox.addLayout(hbox2) vbox.addSpacing(50) vbox_create_new = QVBoxLayout() vbox_create_new.addWidget(QLabel(_('Alternatively') + ':'), alignment=Qt.AlignLeft) button_create_new = QPushButton(_('Create New Wallet')) button_create_new.setMinimumWidth(120) vbox_create_new.addWidget(button_create_new, alignment=Qt.AlignLeft) widget_create_new = QWidget() widget_create_new.setLayout(vbox_create_new) vbox_create_new.setContentsMargins(0, 0, 0, 0) vbox.addWidget(widget_create_new) self.set_layout(vbox, title=_('Electrum wallet')) temp_storage = None # type: Optional[WalletStorage] wallet_folder = os.path.dirname(path) def on_choose(): path, __ = QFileDialog.getOpenFileName(self, "Select your wallet file", wallet_folder) if path: name_e.setText(path) def on_filename(filename): # FIXME? "filename" might contain ".." (etc) and hence sketchy path traversals are possible nonlocal temp_storage temp_storage = None msg = None path = os.path.join(wallet_folder, filename) wallet_from_memory = get_wallet_from_daemon(path) try: if wallet_from_memory: temp_storage = wallet_from_memory.storage # type: Optional[WalletStorage] else: temp_storage = WalletStorage(path) except (StorageReadWriteError, WalletFileException) as e: msg = _('Cannot read file') + f'\n{repr(e)}' except Exception as e: self.logger.exception('') msg = _('Cannot read file') + f'\n{repr(e)}' self.next_button.setEnabled(temp_storage is not None) user_needs_to_enter_password = False if temp_storage: if not temp_storage.file_exists(): msg =_("This file does not exist.") + '\n' \ + _("Press 'Next' to create this wallet, or choose another file.") elif not wallet_from_memory: if temp_storage.is_encrypted_with_user_pw(): msg = _("This file is encrypted with a password.") + '\n' \ + _('Enter your password or choose another file.') user_needs_to_enter_password = True elif temp_storage.is_encrypted_with_hw_device(): msg = _("This file is encrypted using a hardware device.") + '\n' \ + _("Press 'Next' to choose device to decrypt.") else: msg = _("Press 'Next' to open this wallet.") else: msg = _("This file is already open in memory.") + "\n" \ + _("Press 'Next' to create/focus window.") if msg is None: msg = _('Cannot read file') msg_label.setText(msg) widget_create_new.setVisible(bool(temp_storage and temp_storage.file_exists())) if user_needs_to_enter_password: pw_label.show() pw_e.show() pw_e.setFocus() else: pw_label.hide() pw_e.hide() button.clicked.connect(on_choose) button_create_new.clicked.connect( partial( name_e.setText, get_new_wallet_name(wallet_folder))) name_e.textChanged.connect(on_filename) name_e.setText(os.path.basename(path)) def run_user_interaction_loop(): while True: if self.loop.exec_() != 2: # 2 = next raise UserCancelled() assert temp_storage if temp_storage.file_exists() and not temp_storage.is_encrypted(): break if not temp_storage.file_exists(): break wallet_from_memory = get_wallet_from_daemon(temp_storage.path) if wallet_from_memory: raise WalletAlreadyOpenInMemory(wallet_from_memory) if temp_storage.file_exists() and temp_storage.is_encrypted(): if temp_storage.is_encrypted_with_user_pw(): password = pw_e.text() try: temp_storage.decrypt(password) break except InvalidPassword as e: self.show_message(title=_('Error'), msg=str(e)) continue except BaseException as e: self.logger.exception('') self.show_message(title=_('Error'), msg=repr(e)) raise UserCancelled() elif temp_storage.is_encrypted_with_hw_device(): try: self.run('choose_hw_device', HWD_SETUP_DECRYPT_WALLET, storage=temp_storage) except InvalidPassword as e: self.show_message(title=_('Error'), msg=_('Failed to decrypt using this hardware device.') + '\n' + _('If you use a passphrase, make sure it is correct.')) self.reset_stack() return self.select_storage(path, get_wallet_from_daemon) except (UserCancelled, GoBack): raise except BaseException as e: self.logger.exception('') self.show_message(title=_('Error'), msg=repr(e)) raise UserCancelled() if temp_storage.is_past_initial_decryption(): break else: raise UserCancelled() else: raise Exception('Unexpected encryption version') try: run_user_interaction_loop() finally: try: pw_e.clear() except RuntimeError: # wrapped C/C++ object has been deleted. pass # happens when decrypting with hw device return temp_storage.path, (temp_storage if temp_storage.file_exists() else None)
from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QWidget, QRadioButton, QLabel, QVBoxLayout, QHBoxLayout, QMessageBox app = QApplication([]) my_win = QWidget() a = QLabel("В каком году канал получил золотую кнопку от You Тube?") c = QRadioButton('2005') d = QRadioButton('2010') e = QRadioButton('2015') x = QRadioButton('2020') h = QHBoxLayout() h.addWidget(a, alignment=Qt.AlignCenter) m = QHBoxLayout() m.addWidget(c, alignment=Qt.AlignCenter) m.addWidget(d, alignment=Qt.AlignCenter) v = QHBoxLayout() v.addWidget(e, alignment=Qt.AlignCenter) v.addWidget(x, alignment=Qt.AlignCenter) q = QVBoxLayout() q.addLayout(h) q.addLayout(m) q.addLayout(v) def showwin(): g = QMessageBox() g.setText("Вы выиграли") g.exec_() def joc(): wow = QMessageBox()
def __init__(self, parent=None): super(ResultHandler, self).__init__() self.setWindowTitle('Dash results') self.control_label = QLabel() self.rendered_label = QLabel() self.diff_label = QLabel() self.mask_label = QLabel() self.new_mask_label = QLabel() self.scrollArea = QScrollArea() self.widget = QWidget() self.test_name_label = QLabel() grid = QGridLayout() grid.addWidget(self.test_name_label, 0, 0) grid.addWidget(QLabel('Control'), 1, 0) grid.addWidget(QLabel('Rendered'), 1, 1) grid.addWidget(QLabel('Difference'), 1, 2) grid.addWidget(self.control_label, 2, 0) grid.addWidget(self.rendered_label, 2, 1) grid.addWidget(self.diff_label, 2, 2) grid.addWidget(QLabel('Current Mask'), 3, 0) grid.addWidget(QLabel('New Mask'), 3, 1) grid.addWidget(self.mask_label, 4, 0) grid.addWidget(self.new_mask_label, 4, 1) self.widget.setLayout(grid) self.scrollArea.setWidget(self.widget) v_layout = QVBoxLayout() v_layout.addWidget(self.scrollArea, 1) next_image_button = QPushButton() next_image_button.setText('Skip') next_image_button.pressed.connect(self.load_next) self.overload_spin = QDoubleSpinBox() self.overload_spin.setMinimum(1) self.overload_spin.setMaximum(255) self.overload_spin.setValue(1) self.overload_spin.valueChanged.connect( lambda: save_mask_button.setEnabled(False)) preview_mask_button = QPushButton() preview_mask_button.setText('Preview New Mask') preview_mask_button.pressed.connect(self.preview_mask) preview_mask_button.pressed.connect( lambda: save_mask_button.setEnabled(True)) save_mask_button = QPushButton() save_mask_button.setText('Save New Mask') save_mask_button.pressed.connect(self.save_mask) button_layout = QHBoxLayout() button_layout.addWidget(next_image_button) button_layout.addWidget(QLabel('Mask diff multiplier:')) button_layout.addWidget(self.overload_spin) button_layout.addWidget(preview_mask_button) button_layout.addWidget(save_mask_button) button_layout.addStretch() v_layout.addLayout(button_layout) self.setLayout(v_layout)
class UiControl: def __init__(self, systemState): self.systemState = systemState self.currXmlId = [-1, -1, -1, -1] self.afterPauseTask = TASK_NONE self.iconPause = QtGui.QIcon("./images/pause.png") self.iconActivate = QtGui.QIcon("./images/play.png") self.iconWait = QtGui.QIcon("./images/wait.png") self.mainWindow = QWidget() self.mainUi = Ui_MainScreen() self.mainUi.setupUi(self.mainWindow) self.pauseChangeDialog = QDialog() self.pauseChangeDialog.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowStaysOnTopHint) self.pauseChangeDialogUi = Ui_PauseChangeDialog() self.pauseChangeDialogUi.setupUi(self.pauseChangeDialog) self.pauseChangeGif = QtGui.QMovie("./images/waiting.gif") self.pauseChangeGif.setScaledSize(QtCore.QSize(140, 140)) self.pauseChangeDialogUi.labelGIF.setMovie(self.pauseChangeGif) self.pauseChangeThread = PauseChangeThread(self.systemState) self.showWhenPauseDone = None self.dropdownRefreshThread = DropdownRefreshThread(self.systemState) self.doRefresh = -1 self.statusRefreshThread1 = StatusRefreshThread() self.statusRefreshThread2 = StatusRefreshThread() self.statuRefreshThreadSelect = False self.delTypeId = -1 self.confirmDialog = QDialog() self.confirmDialog.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint) self.confirmDialogUi = Ui_ConfirmDialog() self.confirmDialogUi.setupUi(self.confirmDialog) self.dialogs = [] for i in range(NUM_DIALOGS): dialog = QDialog() dialog.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint) self.dialogs.append(dialog) self.dialogUis = [] self.dialogUis.append(Ui_WearableDialog()) self.dialogUis.append(Ui_ZoneDialog()) self.dialogUis.append(Ui_DeviceDialog()) self.dialogUis.append(Ui_ConfigDialog()) for i in range(NUM_DIALOGS): self.dialogUis[i].setupUi(self.dialogs[i]) self.tables = [ self.mainUi.tableWearable, self.mainUi.tableZone, self.mainUi.tableDevice, self.mainUi.tableConfig ] self.zoTable = self.mainUi.tableZoneOccupation self.dsTable = self.mainUi.tableDeviceState self.buttonGroups = [] self.buttonGroups.append([ self.mainUi.buttonEditWearable, self.mainUi.buttonDeleteWearable, self.mainUi.buttonNewWearable ]) self.buttonGroups.append([ self.mainUi.buttonEditZone, self.mainUi.buttonDeleteZone, self.mainUi.buttonNewZone ]) self.buttonGroups.append([ self.mainUi.buttonEditDevice, self.mainUi.buttonDeleteDevice, self.mainUi.buttonNewDevice ]) self.buttonGroups.append( [self.mainUi.buttonEditConfig, self.mainUi.buttonClearConfig]) self.connectUiElements() # populate tables with current system info self.populateHardwareTables() self.createZoneOccupationTable() self.createDeviceStateTable() # populate device type dropdown dropdown = self.dialogUis[TID_D].dropdownType for deviceType in DEVICE_TYPES.keys(): dropdown.addItem(DEVICE_TYPES[deviceType], deviceType) # set initial button enabled/disabled state, etc for i in range(4): self.selectionUpdate(i) # initially, system should be unpaused self.mainUi.labelPauseStatus.setText("<b>System Active<b>") self.mainUi.buttonPause.setIcon(self.iconPause) self.manuallyPaused = False # now that everything is set up, let the other threads start doing their thing self.systemState.setSystemPause(RESUME) # since we start in the status tab, we want to make sure it's updating when we begin self.statusRefresh() # let's go! self.mainWindow.show() def connectUiElements(self): # "New" buttons self.mainUi.buttonNewWearable.clicked.connect( lambda: self.editWearable(True)) self.mainUi.buttonNewZone.clicked.connect(lambda: self.editZone(True)) self.mainUi.buttonNewDevice.clicked.connect( lambda: self.editDevice(True)) # "Edit" buttons self.mainUi.buttonEditWearable.clicked.connect( lambda: self.editWearable(False)) self.mainUi.buttonEditZone.clicked.connect( lambda: self.editZone(False)) self.mainUi.buttonEditDevice.clicked.connect( lambda: self.editDevice(False)) self.mainUi.buttonEditConfig.clicked.connect(lambda: self.editConfig()) # "Delete" buttons self.mainUi.buttonDeleteWearable.clicked.connect( lambda: self.confirmDeletion(TID_W)) self.mainUi.buttonDeleteZone.clicked.connect( lambda: self.confirmDeletion(TID_Z)) self.mainUi.buttonDeleteDevice.clicked.connect( lambda: self.confirmDeletion(TID_D)) self.mainUi.buttonClearConfig.clicked.connect( lambda: self.beginTaskWithPause(TASK_CLEAR_CONFIG)) # deletion confirmation buttons self.confirmDialogUi.buttonNo.clicked.connect( lambda: self.confirmDialog.hide()) self.confirmDialogUi.buttonYes.clicked.connect( lambda: self.beginTaskWithPause(TASK_DELETE_TABLE_ENTRY)) # dialog "Cancel" buttons self.dialogUis[TID_W].buttonCancel.clicked.connect( lambda: self.cancelHardwareDialog(TID_W)) self.dialogUis[TID_Z].buttonCancel.clicked.connect( lambda: self.cancelHardwareDialog(TID_Z)) self.dialogUis[TID_D].buttonCancel.clicked.connect( lambda: self.cancelHardwareDialog(TID_D)) self.dialogUis[TID_C].buttonCancel.clicked.connect( lambda: self.cancelHardwareDialog(TID_C)) # dialog "Save" buttons self.dialogUis[TID_W].buttonSave.clicked.connect( lambda: self.saveWearable()) self.dialogUis[TID_Z].buttonSave.clicked.connect( lambda: self.saveZone()) self.dialogUis[TID_D].buttonSave.clicked.connect( lambda: self.saveDevice()) self.dialogUis[TID_C].buttonSave.clicked.connect( lambda: self.saveConfig()) # dialog "Refresh List" buttons self.dialogUis[TID_W].buttonRefresh.clicked.connect( lambda: self.refreshWearableDropdown()) self.dialogUis[TID_Z].buttonRefresh.clicked.connect( lambda: self.initiateDropdownRefresh(TID_Z)) self.dialogUis[TID_D].buttonRefresh.clicked.connect( lambda: self.initiateDropdownRefresh(TID_D)) # enable/disable buttons when table selection changes, etc self.tables[TID_W].itemSelectionChanged.connect( lambda: self.selectionUpdate(TID_W)) self.tables[TID_Z].itemSelectionChanged.connect( lambda: self.selectionUpdate(TID_Z)) self.tables[TID_D].itemSelectionChanged.connect( lambda: self.selectionUpdate(TID_D)) self.tables[TID_C].itemSelectionChanged.connect( lambda: self.selectionUpdate(TID_C)) # manual system pause/resume button self.mainUi.buttonPause.clicked.connect(lambda: self.beginPauseChange( (not self.systemState.systemIsPaused), True)) self.pauseChangeThread.doneSignal.connect( lambda: self.finishPauseChange()) self.dropdownRefreshThread.doneSignal.connect( lambda: self.finishDropdownRefresh()) self.statusRefreshThread1.refreshSignal.connect( lambda: self.statusRefresh()) self.statusRefreshThread2.refreshSignal.connect( lambda: self.statusRefresh()) # link values of zone threshold slider & spinner spinner = self.dialogUis[TID_Z].spinnerThreshold slider = self.dialogUis[TID_Z].sliderThreshold spinner.valueChanged.connect(lambda: slider.setValue(spinner.value())) slider.valueChanged.connect(lambda: spinner.setValue(slider.value())) # tabs = self.mainUi.tabWidget tabs.currentChanged.connect( lambda: self.tabChange(tabs.currentIndex())) def tabChange(self, tabNum): if (tabNum == TAB_STAT): self.statusRefresh() elif (tabNum == TAB_SYS): self.createConfigTable() # other cases -> do nothing def beginPauseChange(self, desiredAction, isManualChange): if (desiredAction == self.systemState.systemIsPaused): return False # system is already in the desired state # manual changes are initiated by pressing the pause/resume button # automatic changes are initiated when editing any part of the system if (isManualChange): self.manuallyPaused = (desiredAction == PAUSE) if (desiredAction == PAUSE): waitText = "Pausing System..." else: waitText = "Resuming System... " self.mainUi.labelPauseStatus.setText(waitText) self.mainUi.buttonPause.setIcon(self.iconWait) self.pauseChangeDialog.setWindowTitle(waitText) self.pauseChangeGif.start() self.pauseChangeDialog.show() self.pauseChangeThread.setAction(desiredAction) self.pauseChangeThread.start() return True def finishPauseChange(self): if (self.systemState.systemIsPaused): doneText = "<b>System Paused</b>" newIcon = self.iconActivate else: doneText = "<b>System Active<b>" newIcon = self.iconPause self.mainUi.buttonPause.setIcon(newIcon) self.mainUi.labelPauseStatus.setText(doneText) self.pauseChangeGif.stop() self.pauseChangeDialog.hide() if (self.showWhenPauseDone != None): self.showWhenPauseDone.show() self.showWhenPauseDone = None if (self.doRefresh != -1): self.initiateDropdownRefresh(self.doRefresh) self.doRefresh = -1 self.executeTask() def statusRefresh(self): # update each row (zone) in zone occupation table for row in range(self.zoTable.rowCount()): items = [self.zoTable.item(row, 0), self.zoTable.item(row, 1)] zone = self.systemState.getHardwareObjectByXmlId( TID_Z, items[0].data(5)) self.updateZoneOccupationTableRow(zone, items) # update each row (zone) in zone occupation table for row in range(self.dsTable.rowCount()): items = [self.dsTable.item(row, 0), self.dsTable.item(row, 1)] device = self.systemState.getHardwareObjectByXmlId( TID_D, items[0].data(5)) self.updateDeviceStateTableRow(device, items) # if still in status tab, need to keep refreshing if (self.mainUi.tabWidget.currentIndex() == TAB_STAT): # alternate between two refresh threads so signal emits don't "overlap" if (self.statuRefreshThreadSelect): self.statusRefreshThread1.start() else: self.statusRefreshThread2.start() self.statuRefreshThreadSelect = (not self.statuRefreshThreadSelect) def editWearable(self, isNew, isAfterPause=False): self.showWhenPauseDone = self.dialogs[TID_W] self.beginPauseChange(PAUSE, False) self.dialogUis[TID_W].labelInvalidName.setVisible(False) self.dialogUis[TID_W].labelInvalidWearable.setVisible(False) self.newFlag = isNew if (isNew): wearable = self.systemState.newWearable() self.currXmlId[TID_W] = wearable.xmlId else: wearable = self.systemState.getHardwareObjectByXmlId( TID_W, self.currXmlId[TID_W]) self.dialogUis[TID_W].inputName.setText(wearable.name) self.refreshWearableDropdown() def editZone(self, isNew): self.showWhenPauseDone = self.dialogs[TID_Z] self.doRefresh = TID_Z pauseNeeded = self.beginPauseChange(PAUSE, False) if (not pauseNeeded): self.doRefresh = -1 self.initiateDropdownRefresh(TID_Z) self.dialogUis[TID_Z].labelInvalidName.setVisible(False) self.dialogUis[TID_Z].labelInvalidModule.setVisible(False) self.newFlag = isNew if (isNew): zone = self.systemState.newZone() self.currXmlId[TID_Z] = zone.xmlId else: zone = self.systemState.getHardwareObjectByXmlId( TID_Z, self.currXmlId[TID_Z]) self.dialogUis[TID_Z].inputName.setText(zone.name) self.dialogUis[TID_Z].spinnerThreshold.setValue(zone.threshold) if (not pauseNeeded): self.dialogs[TID_Z].show() def editDevice(self, isNew): self.showWhenPauseDone = self.dialogs[TID_D] self.doRefresh = TID_D pauseNeeded = self.beginPauseChange(PAUSE, False) if (not pauseNeeded): self.doRefresh = -1 self.initiateDropdownRefresh(TID_D) self.dialogUis[TID_D].labelInvalidName.setVisible(False) self.dialogUis[TID_D].labelInvalidDevice.setVisible(False) self.newFlag = isNew if (isNew): device = self.systemState.newDevice() self.currXmlId[TID_D] = device.xmlId else: device = self.systemState.getHardwareObjectByXmlId( TID_D, self.currXmlId[TID_D]) self.dialogUis[TID_D].inputName.setText(device.name) if (not pauseNeeded): self.dialogs[TID_D].show() def editConfig(self): self.showWhenPauseDone = self.dialogs[TID_C] self.beginPauseChange(PAUSE, False) self.dialogUis[TID_C].labelInvalidZone.setVisible(False) device = self.systemState.getHardwareObjectByXmlId( TID_D, self.currXmlId[TID_C]) self.dialogUis[TID_C].labelConfig.setText("Configuration for \"" + device.name + "\"") self.populateConfigDropdowns(device) def cancelHardwareDialog(self, typeId): if (typeId != TID_C): if (self.newFlag): self.systemState.deleteHardwareObject(typeId, self.currXmlId[typeId]) self.selectionUpdate(typeId) if (not self.manuallyPaused): self.beginPauseChange(RESUME, False) self.dialogs[typeId].hide() def saveWearable(self): givenName = (self.dialogUis[TID_W].inputName.text()).strip() if (self.systemState.nameInUse(TID_W, givenName, self.currXmlId[TID_W])): self.dialogUis[TID_W].labelInvalidName.setVisible(True) return else: self.dialogUis[TID_W].labelInvalidName.setVisible(False) selectedHwId = self.dialogUis[TID_W].dropdownWearable.currentData() if (selectedHwId == -1): self.dialogUis[TID_W].labelInvalidWearable.setVisible(True) return else: self.dialogUis[TID_W].labelInvalidWearable.setVisible(False) wearable = self.systemState.getHardwareObjectByXmlId( TID_W, self.currXmlId[TID_W]) wearable.name = givenName wearable.hwId = selectedHwId self.updateWearableTable(wearable, self.newFlag) self.selectionUpdate(TID_W) if (not self.manuallyPaused): self.beginPauseChange(RESUME, False) self.dialogs[TID_W].hide() def saveZone(self): # disallow duplicate names givenName = (self.dialogUis[TID_Z].inputName.text()).strip() if (self.systemState.nameInUse(TID_Z, givenName, self.currXmlId[TID_Z])): self.dialogUis[TID_Z].labelInvalidName.setVisible(True) return else: self.dialogUis[TID_Z].labelInvalidName.setVisible(False) # disallow invalid hardware IDs selectedHwId = self.dialogUis[TID_Z].dropdownModule.currentData() if (selectedHwId == -1): self.dialogUis[TID_Z].labelInvalidModule.setVisible(True) return else: self.dialogUis[TID_Z].labelInvalidModule.setVisible(False) # input validated -- do the save operation zone = self.systemState.getHardwareObjectByXmlId( TID_Z, self.currXmlId[TID_Z]) zone.name = givenName zone.hwId = selectedHwId zone.threshold = self.dialogUis[TID_Z].spinnerThreshold.value() self.updateZoneTable(zone, self.newFlag) self.selectionUpdate(TID_Z) # update zone occupation table in status tab if (self.newFlag): self.updateZoneOccupationTableRow(zone) else: for row in range(self.zoTable.rowCount()): if (self.zoTable.item(row, 0).data(5) == zone.xmlId): items = [ self.zoTable.item(row, 0), self.zoTable.item(row, 1) ] self.updateZoneOccupationTableRow(zone, items) break self.updateDeviceStateTableRow if (not self.manuallyPaused): self.beginPauseChange(RESUME, False) self.dialogs[TID_Z].hide() def saveDevice(self): # disallow duplicate names givenName = (self.dialogUis[TID_D].inputName.text()).strip() if (self.systemState.nameInUse(TID_D, givenName, self.currXmlId[TID_D])): self.dialogUis[TID_D].labelInvalidName.setVisible(True) return else: self.dialogUis[TID_D].labelInvalidName.setVisible(False) # disallow invalid hardware IDs (selectedHwId, selectedListName ) = self.dialogUis[TID_D].dropdownDevice.currentData() if (selectedHwId == 'INVALID'): self.dialogUis[TID_D].labelInvalidDevice.setVisible(True) return else: self.dialogUis[TID_D].labelInvalidDevice.setVisible(False) # input validated -- do the save operation device = self.systemState.getHardwareObjectByXmlId( TID_D, self.currXmlId[TID_D]) device.name = givenName device.hwId = selectedHwId device.listName = selectedListName device.devType = self.dialogUis[TID_D].dropdownType.currentData() self.updateDeviceTable(device, self.newFlag) self.selectionUpdate(TID_D) # update device state table in status tab if (self.newFlag): self.updateDeviceStateTableRow(device) else: for row in range(self.dsTable.rowCount()): if (self.dsTable.item(row, 0).data(5) == device.xmlId): items = [ self.dsTable.item(row, 0), self.dsTable.item(row, 1) ] self.updateDeviceStateTableRow(device, items) break if (not self.manuallyPaused): self.beginPauseChange(RESUME, False) self.dialogs[TID_D].hide() def saveConfig(self): configUi = self.dialogUis[TID_C] selectedZone = configUi.dropdownZone.currentData() if (selectedZone == -1): self.dialogUis[TID_C].labelInvalidZone.setVisible(True) return else: self.dialogUis[TID_C].labelInvalidZone.setVisible(False) device = self.systemState.getHardwareObjectByXmlId( TID_D, self.currXmlId[TID_C]) device.zone = selectedZone device.enter = configUi.dropdownEntryAction.currentData() device.exit = configUi.dropdownExitAction.currentData() self.updateConfigTableEntry(device) self.selectionUpdate(TID_C) if (not self.manuallyPaused): self.beginPauseChange(RESUME, False) self.dialogs[TID_C].hide() def confirmDeletion(self, typeId): self.delTypeId = typeId hwObj = self.systemState.getHardwareObjectByXmlId( typeId, self.currXmlId[typeId]) text = DEL_STR + HW_STR_DICT[typeId] + " \"" + hwObj.name + "\"?" self.confirmDialogUi.labelAreYouSure.setText(text) self.confirmDialogUi.labelWarning.setVisible(typeId == TID_Z) self.confirmDialog.show() def beginTaskWithPause(self, taskId): self.afterPauseTask = taskId ret = self.beginPauseChange(PAUSE, False) if (not ret): self.executeTask() def executeTask(self): task = self.afterPauseTask self.afterPauseTask = TASK_NONE if (task == TASK_NONE): return elif (task == TASK_CLEAR_CONFIG): self.clearConfig() elif (task == TASK_DELETE_TABLE_ENTRY): self.deleteTableEntry(self.delTypeId) def deleteTableEntry(self, typeId): xmlId = self.currXmlId[typeId] self.systemState.deleteHardwareObject(typeId, xmlId) self.tables[typeId].removeRow(self.tables[typeId].currentRow()) self.removeFromStatusTable(typeId, xmlId) if (not self.manuallyPaused): self.beginPauseChange(RESUME, False) self.confirmDialog.hide() def clearConfig(self): device = self.systemState.getHardwareObjectByXmlId( TID_D, self.currXmlId[TID_C]) device.zone = -1 device.enter = 0 device.exit = 0 self.updateConfigTableEntry(device) if (not self.manuallyPaused): self.beginPauseChange(RESUME, False) def selectionUpdate(self, tableIdx): items = self.tables[tableIdx].selectedItems() if (len(items) > 0): self.currXmlId[tableIdx] = items[0].data(5) else: self.currXmlId[tableIdx] = -1 shouldEnable = (len(self.tables[tableIdx].selectedIndexes()) != 0) buttons = self.buttonGroups[tableIdx] for i in range(2): # only update edit & delete buttons buttons[i].setEnabled(shouldEnable) def refreshWearableDropdown(self): hwIdList = self.systemState.discoverHardware(TID_W) dropdown = self.dialogUis[TID_W].dropdownWearable dropdown.clear() for hwId in hwIdList: dropdown.addItem(str(hwId), hwId) if (not self.newFlag ): # add and select current hwId if editing existing wearable wearable = self.systemState.getHardwareObjectByXmlId( TID_W, self.currXmlId[TID_W]) dropdown.insertItem(0, str(wearable.hwId), int(wearable.hwId)) dropdown.setCurrentIndex(0) elif (len(hwIdList) == 0): dropdown.addItem("[no unassigned wearables detected]", -1) def initiateDropdownRefresh(self, typeId): if (typeId == TID_Z): titleText = "Searching for Zone Modules..." else: # typeId = TID_D titleText = "Searching for Devices..." self.pauseChangeDialog.setWindowTitle(titleText) self.dropdownRefreshThread.setTypeId(typeId) self.dropdownRefreshThread.start() self.pauseChangeGif.start() self.pauseChangeDialog.show() def finishDropdownRefresh(self): if (self.dropdownRefreshThread.typeId == TID_Z): self.refreshZoneModuleDropdown() else: # typeId == TID_D self.refreshDeviceDropdown() self.pauseChangeGif.stop() self.pauseChangeDialog.hide() def refreshZoneModuleDropdown(self): hwIdList = self.dropdownRefreshThread.hwIdList dropdown = self.dialogUis[TID_Z].dropdownModule dropdown.clear() for hwId in hwIdList: dropdown.addItem(str(hwId), hwId) if (not self.newFlag ): # add and select current hwId if editing existing zone zone = self.systemState.getHardwareObjectByXmlId( TID_Z, self.currXmlId[TID_Z]) dropdown.insertItem(0, str(zone.hwId), int(zone.hwId)) dropdown.setCurrentIndex(0) elif (len(hwIdList) == 0): dropdown.addItem("[no unassigned modules detected]", -1) def refreshDeviceDropdown(self): hwTupleList = self.dropdownRefreshThread.hwIdList dropdown = self.dialogUis[TID_D].dropdownDevice dropdown.clear() for (hwId, listName) in hwTupleList: dropdown.addItem(hwId + " - " + listName, (hwId, listName)) # add and select current hwId if editing existing zone if (not self.newFlag): device = self.systemState.getHardwareObjectByXmlId( TID_D, self.currXmlId[TID_D]) dropdown.insertItem(0, device.hwId + " - " + device.listName, (device.hwId, device.listName)) dropdown.setCurrentIndex(0) elif (len(hwTupleList) == 0): dropdown.addItem("[no unassigned devices detected]", 'INVALID') def populateConfigDropdowns(self, device): configUi = self.dialogUis[TID_C] dropdown = configUi.dropdownZone dropdown.clear() for zone in self.systemState.dicts[TID_Z].values(): dropdown.addItem(zone.name, zone.xmlId) if (zone.xmlId == device.zone): dropdown.setCurrentIndex(dropdown.count() - 1) if (dropdown.count() == 0): dropdown.addItem("[no zones exist]", -1) actions = DEVICE_ACTIONS[device.devType] dropdown = configUi.dropdownEntryAction dropdown.clear() dropdown2 = configUi.dropdownExitAction dropdown2.clear() for actionId in DEVICE_ACTIONS[device.devType].keys(): dropdown.addItem(actions[actionId], actionId) if (actionId == device.enter): dropdown.setCurrentIndex(dropdown.count() - 1) dropdown2.addItem(actions[actionId], actionId) if (actionId == device.exit): dropdown2.setCurrentIndex(dropdown2.count() - 1) def populateHardwareTables(self): for wearable in self.systemState.dicts[TID_W].values(): self.updateWearableTable(wearable, True) for zone in self.systemState.dicts[TID_Z].values(): self.updateZoneTable(zone, True) for device in self.systemState.dicts[TID_D].values(): self.updateDeviceTable(device, True) def updateWearableTable(self, wearable, isNew): if (isNew): self.tables[TID_W].insertRow(0) # "Name" item with xmlId data item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(wearable.name) item.setData(5, wearable.xmlId) self.tables[TID_W].setItem(0, 0, item) # "Wearable ID" item item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(str(wearable.hwId)) self.tables[TID_W].setItem(0, 1, item) else: items = self.tables[TID_W].selectedItems() items[0].setText(wearable.name) items[1].setText(str(wearable.hwId)) def updateZoneTable(self, zone, isNew): if (isNew): self.tables[TID_Z].insertRow(0) # "Name" item with xmlId data item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(zone.name) item.setData(5, zone.xmlId) self.tables[TID_Z].setItem(0, 0, item) # "Module ID" item item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(str(zone.hwId)) self.tables[TID_Z].setItem(0, 1, item) # "Threshold" item item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(str(zone.threshold)) self.tables[TID_Z].setItem(0, 2, item) else: items = self.tables[TID_Z].selectedItems() items[0].setText(zone.name) items[1].setText(str(zone.hwId)) items[2].setText(str(zone.threshold)) def updateDeviceTable(self, device, isNew): if (isNew): self.tables[TID_D].insertRow(0) # "Name" item with xmlId data item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(device.name) item.setData(5, device.xmlId) self.tables[TID_D].setItem(0, 0, item) # "Bluetooth Address" item item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(device.hwId) self.tables[TID_D].setItem(0, 1, item) # "Type" item item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(DEVICE_TYPES[device.devType]) self.tables[TID_D].setItem(0, 2, item) else: items = self.tables[TID_D].selectedItems() items[0].setText(device.name) items[2].setText(device.hwId) items[2].setText(DEVICE_TYPES[device.devType]) def createConfigTable(self): configTable = self.tables[TID_C] configTable.clearContents() for i in range(configTable.rowCount()): configTable.removeRow(0) for device in self.systemState.dicts[TID_D].values(): configTable.insertRow(0) # "Device" item with xmlId data item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(device.name) item.setData(5, device.xmlId) configTable.setItem(0, 0, item) # "Containing Zone" item item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) if (device.zone == -1): text = "[unassigned]" else: text = self.systemState.dicts[TID_Z][device.zone].name item.setText(text) item.setData(5, device.zone) configTable.setItem(0, 1, item) # "Entry Action" item item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(DEVICE_ACTIONS[device.devType][device.enter]) configTable.setItem(0, 2, item) # "Exit Action" item item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) item.setText(DEVICE_ACTIONS[device.devType][device.exit]) configTable.setItem(0, 3, item) def updateConfigTableEntry(self, device): items = self.tables[TID_C].selectedItems() if (device.zone == -1): text = "[unassigned]" else: text = self.systemState.dicts[TID_Z][device.zone].name items[1].setText(text) items[1].setData(5, device.zone) items[2].setText(DEVICE_ACTIONS[device.devType][device.enter]) items[3].setText(DEVICE_ACTIONS[device.devType][device.exit]) def createZoneOccupationTable(self): for zone in self.systemState.dicts[TID_Z].values(): self.updateZoneOccupationTableRow(zone) def updateZoneOccupationTableRow(self, zone, tableItems=None): if (tableItems == None): tableItems = [] for i in range(2): item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) tableItems.append(item) self.zoTable.insertRow(0) self.zoTable.setItem(0, 0, tableItems[0]) self.zoTable.setItem(0, 1, tableItems[1]) tableItems[0].setText(zone.name) tableItems[0].setData(5, zone.xmlId) wearablesPresent = "" firstOneFlag = True signalDataList = zone.wearablesInZone.items() counter = 0 for wearbleId, signalData in signalDataList: wearable = self.systemState.getHardwareObjectByHwId( TID_W, wearbleId) if (not signalData.isInZone): continue counter += 1 if (firstOneFlag): firstOneFlag = False else: wearablesPresent = wearablesPresent + ", " wearablesPresent = wearablesPresent + wearable.name if (counter == 0): wearablesPresent = "[none]" tableItems[1].setText(wearablesPresent) def createDeviceStateTable(self): for device in self.systemState.dicts[TID_D].values(): self.updateDeviceStateTableRow(device) def updateDeviceStateTableRow(self, device, tableItems=None): if (tableItems == None): tableItems = [] for i in range(2): item = QTableWidgetItem() item.setTextAlignment(ITEM_ALIGN_FLAGS) item.setFlags(ITEM_INTERACT_FLAGS) tableItems.append(item) self.dsTable.insertRow(0) self.dsTable.setItem(0, 0, tableItems[0]) self.dsTable.setItem(0, 1, tableItems[1]) tableItems[0].setText(device.name) tableItems[0].setData(5, device.xmlId) tableItems[1].setText(DEVICE_STATES[device.devType][device.state]) def removeFromStatusTable(self, typeId, xmlId): if (typeId != TID_Z and typeId != TID_D): return else: if (typeId == TID_Z): table = self.zoTable else: # typeId == TID_D table = self.dsTable for row in range(table.rowCount()): if ((table.item(row, 0)).data(5) == xmlId): table.removeRow(row) return
def resizeEvent(self, event): QWidget.resizeEvent(self, event) self.updateDisplayValues()
class Weather(widgets.widget.Widget): global status global status_text global temperature global recept_time global weather_icon global args def updateWeatherTask(self): api_key = str(self.args['api_key']) place_id = self.args['place_id'] owm = pyowm.OWM(api_key) observation = owm.weather_at_id(place_id) logging.info('updateWeatherTask ' + str(observation)) w = observation.get_weather() self.status_text.setText(w.get_detailed_status()) temp = w.get_temperature(unit='celsius') self.temperature.setText("max "+ str(temp['temp_max']) + " curr. " + str(temp['temp']) + " min " + str(temp['temp_min'])) #Handle time conversion dtime_utc = (observation.get_reception_time(timeformat='date')).replace(tzinfo=pytz.timezone('UTC')) dtime_local = dtime_utc.astimezone(pytz.timezone('Europe/Berlin')) self.recept_time.setText(dtime_local.strftime("%Y-%m-%d %H:%M:%S %Z%z")) #Get weather icon url = 'http://openweathermap.org/img/w/'+w.get_weather_icon_name()+'.png' data = urllib.request.urlopen(url).read() pixmap = QPixmap() pixmap.loadFromData(data) self.weather_icon.setPixmap(pixmap) #Update each 10 min t = threading.Timer(600, self.updateWeatherTask) t.daemon = True t.start() return 1 def __init__(self, w_args, parent=None): super(Weather, self).__init__(parent) self.args = w_args self.status_text = QLabel("Updating") self.temperature = QLabel("....") self.recept_time = QLabel("....") url = 'http://openweathermap.org/img/w/01d.png' data = urllib.request.urlopen(url).read() pixmap = QPixmap() pixmap.loadFromData(data) self.weather_icon = QLabel() self.weather_icon.setPixmap(pixmap) self.status = QWidget() stat_layout = QHBoxLayout() stat_layout.addWidget(self.status_text) stat_layout.addWidget(self.weather_icon) stat_layout.setContentsMargins(0, 0, 0, 0) self.status.setLayout(stat_layout) # # Add mainLayout = QVBoxLayout() mainLayout.setSpacing(0) mainLayout.addWidget(self.status) mainLayout.addWidget(self.temperature) mainLayout.addWidget(self.recept_time) mainW = QWidget() mainW.setLayout(mainLayout) mainL = QHBoxLayout() mainL.setContentsMargins(0,0,0,0) mainL.addWidget(mainW) self.setLayout(mainL) mainW.setObjectName("Container") self.setMinimumHeight(200) self.setMinimumWidth(400) #Start weatherupdatetask as thread t = threading.Timer(1.0, self.updateWeatherTask) t.daemon = True t.start() #background self.setAutoFillBackground(True) self.setWindowFlags(QtCore.Qt.FramelessWindowHint) bg = "" if 'background' in self.args: if w_args['background'] == 'transparent': self.setAttribute(QtCore.Qt.WA_TranslucentBackground) if w_args['background'][0] == '#': bg = "background-color:"+self.args['background']+";" pass mainW.setStyleSheet("QWidget#Container" "{border-style: outset;" + bg + "border-width: 1px;" "border-color: rgb(60, 60, 60);" "}") #text color ct = '' if 'color' in self.args: ct = "color: " + w_args['color'] + ";" #text-size ts = '' if 'font_size' in self.args: ts = "font-size: " + w_args['font_size'] + ";" self.setStyleSheet(ct+ts)
def __init__(self, systemState): self.systemState = systemState self.currXmlId = [-1, -1, -1, -1] self.afterPauseTask = TASK_NONE self.iconPause = QtGui.QIcon("./images/pause.png") self.iconActivate = QtGui.QIcon("./images/play.png") self.iconWait = QtGui.QIcon("./images/wait.png") self.mainWindow = QWidget() self.mainUi = Ui_MainScreen() self.mainUi.setupUi(self.mainWindow) self.pauseChangeDialog = QDialog() self.pauseChangeDialog.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowStaysOnTopHint) self.pauseChangeDialogUi = Ui_PauseChangeDialog() self.pauseChangeDialogUi.setupUi(self.pauseChangeDialog) self.pauseChangeGif = QtGui.QMovie("./images/waiting.gif") self.pauseChangeGif.setScaledSize(QtCore.QSize(140, 140)) self.pauseChangeDialogUi.labelGIF.setMovie(self.pauseChangeGif) self.pauseChangeThread = PauseChangeThread(self.systemState) self.showWhenPauseDone = None self.dropdownRefreshThread = DropdownRefreshThread(self.systemState) self.doRefresh = -1 self.statusRefreshThread1 = StatusRefreshThread() self.statusRefreshThread2 = StatusRefreshThread() self.statuRefreshThreadSelect = False self.delTypeId = -1 self.confirmDialog = QDialog() self.confirmDialog.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint) self.confirmDialogUi = Ui_ConfirmDialog() self.confirmDialogUi.setupUi(self.confirmDialog) self.dialogs = [] for i in range(NUM_DIALOGS): dialog = QDialog() dialog.setWindowFlags(QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowTitleHint) self.dialogs.append(dialog) self.dialogUis = [] self.dialogUis.append(Ui_WearableDialog()) self.dialogUis.append(Ui_ZoneDialog()) self.dialogUis.append(Ui_DeviceDialog()) self.dialogUis.append(Ui_ConfigDialog()) for i in range(NUM_DIALOGS): self.dialogUis[i].setupUi(self.dialogs[i]) self.tables = [ self.mainUi.tableWearable, self.mainUi.tableZone, self.mainUi.tableDevice, self.mainUi.tableConfig ] self.zoTable = self.mainUi.tableZoneOccupation self.dsTable = self.mainUi.tableDeviceState self.buttonGroups = [] self.buttonGroups.append([ self.mainUi.buttonEditWearable, self.mainUi.buttonDeleteWearable, self.mainUi.buttonNewWearable ]) self.buttonGroups.append([ self.mainUi.buttonEditZone, self.mainUi.buttonDeleteZone, self.mainUi.buttonNewZone ]) self.buttonGroups.append([ self.mainUi.buttonEditDevice, self.mainUi.buttonDeleteDevice, self.mainUi.buttonNewDevice ]) self.buttonGroups.append( [self.mainUi.buttonEditConfig, self.mainUi.buttonClearConfig]) self.connectUiElements() # populate tables with current system info self.populateHardwareTables() self.createZoneOccupationTable() self.createDeviceStateTable() # populate device type dropdown dropdown = self.dialogUis[TID_D].dropdownType for deviceType in DEVICE_TYPES.keys(): dropdown.addItem(DEVICE_TYPES[deviceType], deviceType) # set initial button enabled/disabled state, etc for i in range(4): self.selectionUpdate(i) # initially, system should be unpaused self.mainUi.labelPauseStatus.setText("<b>System Active<b>") self.mainUi.buttonPause.setIcon(self.iconPause) self.manuallyPaused = False # now that everything is set up, let the other threads start doing their thing self.systemState.setSystemPause(RESUME) # since we start in the status tab, we want to make sure it's updating when we begin self.statusRefresh() # let's go! self.mainWindow.show()
def __init__(self, parent=None): super(VideoWindow, self).__init__(parent) self.setWindowTitle("PyQt Video Player Widget Example - pythonprogramminglanguage.com") self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) videoWidget = QVideoWidget() self.playButton = QPushButton() self.playButton.setEnabled(False) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play) self.positionSlider = QSlider(Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) self.errorLabel = QLabel() self.errorLabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) # Create new action openAction = QAction(QIcon('open.png'), '&Open', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open movie') openAction.triggered.connect(self.openFile) # Create exit action exitAction = QAction(QIcon('exit.png'), '&Exit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.exitCall) # Create menu bar and add action menuBar = self.menuBar() fileMenu = menuBar.addMenu('&File') #fileMenu.addAction(newAction) fileMenu.addAction(openAction) fileMenu.addAction(exitAction) # Create a widget for window contents wid = QWidget(self) self.setCentralWidget(wid) # Create layouts to place inside widget controlLayout = QHBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(self.playButton) controlLayout.addWidget(self.positionSlider) layout = QVBoxLayout() layout.addWidget(videoWidget) layout.addLayout(controlLayout) layout.addWidget(self.errorLabel) # Set widget to contain window contents wid.setLayout(layout) self.mediaPlayer.setVideoOutput(videoWidget) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) self.mediaPlayer.error.connect(self.handleError)
def __init__(self, w_args, parent=None): super(Weather, self).__init__(parent) self.args = w_args self.status_text = QLabel("Updating") self.temperature = QLabel("....") self.recept_time = QLabel("....") url = 'http://openweathermap.org/img/w/01d.png' data = urllib.request.urlopen(url).read() pixmap = QPixmap() pixmap.loadFromData(data) self.weather_icon = QLabel() self.weather_icon.setPixmap(pixmap) self.status = QWidget() stat_layout = QHBoxLayout() stat_layout.addWidget(self.status_text) stat_layout.addWidget(self.weather_icon) stat_layout.setContentsMargins(0, 0, 0, 0) self.status.setLayout(stat_layout) # # Add mainLayout = QVBoxLayout() mainLayout.setSpacing(0) mainLayout.addWidget(self.status) mainLayout.addWidget(self.temperature) mainLayout.addWidget(self.recept_time) mainW = QWidget() mainW.setLayout(mainLayout) mainL = QHBoxLayout() mainL.setContentsMargins(0,0,0,0) mainL.addWidget(mainW) self.setLayout(mainL) mainW.setObjectName("Container") self.setMinimumHeight(200) self.setMinimumWidth(400) #Start weatherupdatetask as thread t = threading.Timer(1.0, self.updateWeatherTask) t.daemon = True t.start() #background self.setAutoFillBackground(True) self.setWindowFlags(QtCore.Qt.FramelessWindowHint) bg = "" if 'background' in self.args: if w_args['background'] == 'transparent': self.setAttribute(QtCore.Qt.WA_TranslucentBackground) if w_args['background'][0] == '#': bg = "background-color:"+self.args['background']+";" pass mainW.setStyleSheet("QWidget#Container" "{border-style: outset;" + bg + "border-width: 1px;" "border-color: rgb(60, 60, 60);" "}") #text color ct = '' if 'color' in self.args: ct = "color: " + w_args['color'] + ";" #text-size ts = '' if 'font_size' in self.args: ts = "font-size: " + w_args['font_size'] + ";" self.setStyleSheet(ct+ts)
#!/usr/bin/python3 # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import QApplication, QWidget if __name__ == '__main__': app = QApplication(sys.argv) w = QWidget() w.resize(250, 150) w.move(300, 300) w.setWindowTitle('Simple') w.show() sys.exit(app.exec_())
# -*- coding: utf-8 -*- """ gathered from http://zetcode.com/gui/pyqt5/firstprograms/ """ import sys from PyQt5.QtWidgets import QApplication, QWidget if __name__ == '__main__': app = QApplication(sys.argv) w = QWidget() w.resize(250, 250) w.move(1200, 20) w.setWindowTitle('Start Simple') w.show() sys.exit(app.exec_())
def __init__(self, network: Network, config: 'SimpleConfig', wizard=False): self.network = network self.config = config self.tor_proxy = None self.tabs = tabs = QTabWidget() proxy_tab = QWidget() blockchain_tab = QWidget() tabs.addTab(blockchain_tab, _('Overview')) tabs.addTab(proxy_tab, _('Proxy')) fixed_width_hostname = 24 * char_width_in_lineedit() fixed_width_port = 6 * char_width_in_lineedit() # Proxy tab grid = QGridLayout(proxy_tab) grid.setSpacing(8) # proxy setting self.proxy_cb = QCheckBox(_('Use proxy')) self.proxy_cb.clicked.connect(self.check_disable_proxy) self.proxy_cb.clicked.connect(self.set_proxy) self.proxy_cb.setEnabled(self.config.is_modifiable('proxy')) self.proxy_mode = QComboBox() self.proxy_mode.addItems(['SOCKS4', 'SOCKS5']) self.proxy_host = QLineEdit() self.proxy_host.setFixedWidth(fixed_width_hostname) self.proxy_port = QLineEdit() self.proxy_port.setFixedWidth(fixed_width_port) self.proxy_user = QLineEdit() self.proxy_user.setPlaceholderText(_("Proxy user")) self.proxy_password = PasswordLineEdit() self.proxy_password.setPlaceholderText(_("Password")) self.proxy_password.setFixedWidth(fixed_width_port) self.proxy_mode.currentIndexChanged.connect(self.set_proxy) self.proxy_host.editingFinished.connect(self.set_proxy) self.proxy_port.editingFinished.connect(self.set_proxy) self.proxy_user.editingFinished.connect(self.set_proxy) self.proxy_password.editingFinished.connect(self.set_proxy) self.proxy_mode.currentIndexChanged.connect( self.proxy_settings_changed) self.proxy_host.textEdited.connect(self.proxy_settings_changed) self.proxy_port.textEdited.connect(self.proxy_settings_changed) self.proxy_user.textEdited.connect(self.proxy_settings_changed) self.proxy_password.textEdited.connect(self.proxy_settings_changed) self.tor_cb = QCheckBox(_("Use Tor Proxy")) self.tor_cb.setIcon(read_QIcon("tor_logo.png")) self.tor_cb.hide() self.tor_cb.clicked.connect(self.use_tor_proxy) self.tor_auto_on_cb = QCheckBox(self.network.TOR_AUTO_ON_MSG) self.tor_auto_on_cb.setIcon(read_QIcon("tor_logo.png")) self.tor_auto_on_cb.setChecked(self.config.get('tor_auto_on', True)) self.tor_auto_on_cb.clicked.connect(self.use_tor_auto_on) self.fiat_bypass_tor_cb = QCheckBox(self.network.FIAT_BYPASS_TOR_MSG) fiat_bypass_tor = self.config.get('fiat_bypass_tor', False) self.fiat_bypass_tor_cb.setChecked(fiat_bypass_tor) self.fiat_bypass_tor_cb.clicked.connect(self.fiat_bypass_tor) grid.addWidget(self.tor_cb, 1, 0, 1, 3) grid.addWidget(self.proxy_cb, 2, 0, 1, 3) grid.addWidget( HelpButton( _('Proxy settings apply to all connections: with Dash Electrum servers, but also with third-party services.' )), 2, 4) grid.addWidget(self.proxy_mode, 4, 1) grid.addWidget(self.proxy_host, 4, 2) grid.addWidget(self.proxy_port, 4, 3) grid.addWidget(self.proxy_user, 5, 2) grid.addWidget(self.proxy_password, 5, 3) grid.addWidget(self.tor_auto_on_cb, 6, 0, 1, 3) grid.addWidget( HelpButton( _('During wallet startup try to detect and use Tor Proxy.')), 6, 4) grid.addWidget(self.fiat_bypass_tor_cb, 7, 0, 1, 3) grid.setRowStretch(8, 1) # Blockchain Tab grid = QGridLayout(blockchain_tab) msg = ' '.join([ _("Dash Electrum connects to several nodes in order to download block headers and find out the longest blockchain." ), _("This blockchain is used to verify the transactions sent by your transaction server." ) ]) self.status_label = QLabel('') grid.addWidget(QLabel(_('Status') + ':'), 0, 0) grid.addWidget(self.status_label, 0, 1, 1, 3) grid.addWidget(HelpButton(msg), 0, 4) self.autoconnect_cb = QCheckBox(_('Select server automatically')) self.autoconnect_cb.setEnabled( self.config.is_modifiable('auto_connect')) self.autoconnect_cb.clicked.connect(self.set_server) self.autoconnect_cb.clicked.connect(self.update) msg = ' '.join([ _("If auto-connect is enabled, Dash Electrum will always use a server that is on the longest blockchain." ), _("If it is disabled, you have to choose a server you want to use. Dash Electrum will warn you if your server is lagging." ) ]) grid.addWidget(self.autoconnect_cb, 1, 0, 1, 3) grid.addWidget(HelpButton(msg), 1, 4) self.server_e = QLineEdit() self.server_e.setFixedWidth(fixed_width_hostname + fixed_width_port) self.server_e.editingFinished.connect(self.set_server) msg = _( "Dash Electrum sends your wallet addresses to a single server, in order to receive your transaction history." ) grid.addWidget(QLabel(_('Server') + ':'), 2, 0) grid.addWidget(self.server_e, 2, 1, 1, 3) grid.addWidget(HelpButton(msg), 2, 4) self.height_label = QLabel('') msg = _('This is the height of your local copy of the blockchain.') grid.addWidget(QLabel(_('Blockchain') + ':'), 3, 0) grid.addWidget(self.height_label, 3, 1) grid.addWidget(HelpButton(msg), 3, 4) self.split_label = QLabel('') grid.addWidget(self.split_label, 4, 0, 1, 3) self.nodes_list_widget = NodesListWidget(self) grid.addWidget(self.nodes_list_widget, 6, 0, 1, 5) vbox = QVBoxLayout() vbox.addWidget(tabs) self.layout_ = vbox # tor detector self.td = td = TorDetector() td.found_proxy.connect(self.suggest_proxy) td.start() self.fill_in_proxy_settings() self.update()
def __init__(self, parent): """ Constructor @param parent reference to the parent widget (QWidget) """ E5TabWidget.__init__(self, parent, dnd=True) from .HelpTabBar import HelpTabBar self.__tabBar = HelpTabBar(self) self.setCustomTabBar(True, self.__tabBar) self.__mainWindow = parent self.setUsesScrollButtons(True) self.setDocumentMode(True) self.setElideMode(Qt.ElideNone) from .ClosedTabsManager import ClosedTabsManager self.__closedTabsManager = ClosedTabsManager(self) self.__closedTabsManager.closedTabAvailable.connect( self.__closedTabAvailable) from .UrlBar.StackedUrlBar import StackedUrlBar self.__stackedUrlBar = StackedUrlBar(self) self.__tabBar.tabMoved.connect(self.__stackedUrlBar.moveBar) self.__tabContextMenuIndex = -1 self.currentChanged[int].connect(self.__currentChanged) self.setTabContextMenuPolicy(Qt.CustomContextMenu) self.customTabContextMenuRequested.connect(self.__showContextMenu) self.__rightCornerWidget = QWidget(self) self.__rightCornerWidgetLayout = QHBoxLayout(self.__rightCornerWidget) self.__rightCornerWidgetLayout.setContentsMargins(0, 0, 0, 0) self.__rightCornerWidgetLayout.setSpacing(0) self.__navigationMenu = QMenu(self) self.__navigationMenu.aboutToShow.connect(self.__showNavigationMenu) self.__navigationMenu.triggered.connect(self.__navigationMenuTriggered) self.__navigationButton = QToolButton(self) self.__navigationButton.setIcon( UI.PixmapCache.getIcon("1downarrow.png")) self.__navigationButton.setToolTip(self.tr("Show a navigation menu")) self.__navigationButton.setPopupMode(QToolButton.InstantPopup) self.__navigationButton.setMenu(self.__navigationMenu) self.__navigationButton.setEnabled(False) self.__rightCornerWidgetLayout.addWidget(self.__navigationButton) self.__closedTabsMenu = QMenu(self) self.__closedTabsMenu.aboutToShow.connect( self.__aboutToShowClosedTabsMenu) self.__closedTabsButton = QToolButton(self) self.__closedTabsButton.setIcon(UI.PixmapCache.getIcon("trash.png")) self.__closedTabsButton.setToolTip( self.tr("Show a navigation menu for closed tabs")) self.__closedTabsButton.setPopupMode(QToolButton.InstantPopup) self.__closedTabsButton.setMenu(self.__closedTabsMenu) self.__closedTabsButton.setEnabled(False) self.__rightCornerWidgetLayout.addWidget(self.__closedTabsButton) self.__closeButton = QToolButton(self) self.__closeButton.setIcon(UI.PixmapCache.getIcon("close.png")) self.__closeButton.setToolTip(self.tr("Close the current help window")) self.__closeButton.setEnabled(False) self.__closeButton.clicked[bool].connect(self.closeBrowser) self.__rightCornerWidgetLayout.addWidget(self.__closeButton) if Preferences.getUI("SingleCloseButton") or \ not hasattr(self, 'setTabsClosable'): self.__closeButton.show() else: self.setTabsClosable(True) self.tabCloseRequested.connect(self.closeBrowserAt) self.__closeButton.hide() self.setCornerWidget(self.__rightCornerWidget, Qt.TopRightCorner) self.__newTabButton = QToolButton(self) self.__newTabButton.setIcon(UI.PixmapCache.getIcon("plus.png")) self.__newTabButton.setToolTip(self.tr("Open a new help window tab")) self.setCornerWidget(self.__newTabButton, Qt.TopLeftCorner) self.__newTabButton.clicked[bool].connect(self.newBrowser) self.__initTabContextMenu() self.__historyCompleter = None
def __init__(self, parent: 'ElectrumWindow', config: 'SimpleConfig'): WindowModalDialog.__init__(self, parent, _('Preferences')) self.config = config self.window = parent self.need_restart = False self.fx = self.window.fx self.wallet = self.window.wallet vbox = QVBoxLayout() tabs = QTabWidget() gui_widgets = [] tx_widgets = [] oa_widgets = [] # language lang_help = _( 'Select which language is used in the GUI (after restart).') lang_label = HelpLabel(_('Language') + ':', lang_help) lang_combo = QComboBox() lang_combo.addItems(list(languages.values())) lang_keys = list(languages.keys()) lang_cur_setting = self.config.get("language", '') try: index = lang_keys.index(lang_cur_setting) except ValueError: # not in list index = 0 lang_combo.setCurrentIndex(index) if not self.config.is_modifiable('language'): for w in [lang_combo, lang_label]: w.setEnabled(False) def on_lang(x): lang_request = list(languages.keys())[lang_combo.currentIndex()] if lang_request != self.config.get('language'): self.config.set_key("language", lang_request, True) self.need_restart = True lang_combo.currentIndexChanged.connect(on_lang) gui_widgets.append((lang_label, lang_combo)) nz_help = _( 'Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"' ) nz_label = HelpLabel(_('Zeros after decimal point') + ':', nz_help) nz = QSpinBox() nz.setMinimum(0) nz.setMaximum(self.config.decimal_point) nz.setValue(self.config.num_zeros) if not self.config.is_modifiable('num_zeros'): for w in [nz, nz_label]: w.setEnabled(False) def on_nz(): value = nz.value() if self.config.num_zeros != value: self.config.num_zeros = value self.config.set_key('num_zeros', value, True) self.window.history_list.update() self.window.address_list.update() nz.valueChanged.connect(on_nz) gui_widgets.append((nz_label, nz)) #use_rbf = bool(self.config.get('use_rbf', True)) #use_rbf_cb = QCheckBox(_('Use Replace-By-Fee')) #use_rbf_cb.setChecked(use_rbf) #use_rbf_cb.setToolTip( # _('If you check this box, your transactions will be marked as non-final,') + '\n' + \ # _('and you will have the possibility, while they are unconfirmed, to replace them with transactions that pay higher fees.') + '\n' + \ # _('Note that some merchants do not accept non-final transactions until they are confirmed.')) #def on_use_rbf(x): # self.config.set_key('use_rbf', bool(x)) # batch_rbf_cb.setEnabled(bool(x)) #use_rbf_cb.stateChanged.connect(on_use_rbf) #tx_widgets.append((use_rbf_cb, None)) #batch_rbf_cb = QCheckBox(_('Batch RBF transactions')) #batch_rbf_cb.setChecked(bool(self.config.get('batch_rbf', False))) #batch_rbf_cb.setEnabled(use_rbf) #batch_rbf_cb.setToolTip( # _('If you check this box, your unconfirmed transactions will be consolidated into a single transaction.') + '\n' + \ # _('This will save fees.')) #def on_batch_rbf(x): # self.config.set_key('batch_rbf', bool(x)) #batch_rbf_cb.stateChanged.connect(on_batch_rbf) #tx_widgets.append((batch_rbf_cb, None)) # lightning lightning_widgets = [] help_local_wt = _("""If this option is checked, Electrum will run a local watchtower and protect your channels even if your wallet is not open. For this to work, your computer needs to be online regularly.""") local_wt_cb = QCheckBox(_("Run a local watchtower")) local_wt_cb.setToolTip(help_local_wt) local_wt_cb.setChecked( bool(self.config.get('run_local_watchtower', False))) def on_local_wt_checked(x): self.config.set_key('run_local_watchtower', bool(x)) local_wt_cb.stateChanged.connect(on_local_wt_checked) lightning_widgets.append((local_wt_cb, None)) help_persist = _( """If this option is checked, Electrum will persist after you close all your wallet windows, and the Electrum icon will be visible in the taskbar. Use this if you want your local watchtower to keep running after you close your wallet.""" ) persist_cb = QCheckBox(_("Persist after all windows are closed")) persist_cb.setToolTip(help_persist) persist_cb.setChecked(bool(self.config.get('persist_daemon', False))) def on_persist_checked(x): self.config.set_key('persist_daemon', bool(x)) persist_cb.stateChanged.connect(on_persist_checked) lightning_widgets.append((persist_cb, None)) help_remote_wt = _( """To use a remote watchtower, enter the corresponding URL here""") remote_wt_cb = QCheckBox(_("Use a remote watchtower")) remote_wt_cb.setToolTip(help_remote_wt) remote_wt_cb.setChecked(bool(self.config.get('use_watchtower', False))) def on_remote_wt_checked(x): self.config.set_key('use_watchtower', bool(x)) self.watchtower_url_e.setEnabled(bool(x)) remote_wt_cb.stateChanged.connect(on_remote_wt_checked) watchtower_url = self.config.get('watchtower_url') self.watchtower_url_e = QLineEdit(watchtower_url) self.watchtower_url_e.setEnabled( self.config.get('use_watchtower', False)) def on_wt_url(): url = self.watchtower_url_e.text() or None watchtower_url = self.config.set_key('watchtower_url', url) self.watchtower_url_e.editingFinished.connect(on_wt_url) lightning_widgets.append((remote_wt_cb, self.watchtower_url_e)) msg = _('OpenAlias record, used to receive coins and to sign payment requests.') + '\n\n'\ + _('The following alias providers are available:') + '\n'\ + '\n'.join(['https://cryptoname.co/', 'http://xmr.link']) + '\n\n'\ + 'For more information, see https://openalias.org' alias_label = HelpLabel(_('OpenAlias') + ':', msg) alias = self.config.get('alias', '') self.alias_e = QLineEdit(alias) self.set_alias_color() self.alias_e.editingFinished.connect(self.on_alias_edit) oa_widgets.append((alias_label, self.alias_e)) # units units = base_units_list msg = (_( 'Base unit of your wallet.' ) + '\n1 BTC = 1000 mBTC. 1 mBTC = 1000 bits. 1 bit = 100 sat.\n' + _( 'This setting affects the Send tab, and all balance related fields.' )) unit_label = HelpLabel(_('Base unit') + ':', msg) unit_combo = QComboBox() unit_combo.addItems(units) unit_combo.setCurrentIndex(units.index(self.window.base_unit())) def on_unit(x, nz): unit_result = units[unit_combo.currentIndex()] if self.window.base_unit() == unit_result: return edits = self.window.amount_e, self.window.receive_amount_e amounts = [edit.get_amount() for edit in edits] self.config.set_base_unit(unit_result) nz.setMaximum(self.config.decimal_point) self.window.history_list.update() self.window.request_list.update() self.window.address_list.update() for edit, amount in zip(edits, amounts): edit.setAmount(amount) self.window.update_status() unit_combo.currentIndexChanged.connect(lambda x: on_unit(x, nz)) gui_widgets.append((unit_label, unit_combo)) system_cameras = qrscanner._find_system_cameras() qr_combo = QComboBox() qr_combo.addItem("Default", "default") for camera, device in system_cameras.items(): qr_combo.addItem(camera, device) #combo.addItem("Manually specify a device", config.get("video_device")) index = qr_combo.findData(self.config.get("video_device")) qr_combo.setCurrentIndex(index) msg = _("Install the zbar package to enable this.") qr_label = HelpLabel(_('Video Device') + ':', msg) qr_combo.setEnabled(qrscanner.libzbar is not None) on_video_device = lambda x: self.config.set_key( "video_device", qr_combo.itemData(x), True) qr_combo.currentIndexChanged.connect(on_video_device) gui_widgets.append((qr_label, qr_combo)) colortheme_combo = QComboBox() colortheme_combo.addItem(_('Light'), 'default') colortheme_combo.addItem(_('Dark'), 'dark') index = colortheme_combo.findData( self.config.get('qt_gui_color_theme', 'default')) colortheme_combo.setCurrentIndex(index) colortheme_label = QLabel(_('Color theme') + ':') def on_colortheme(x): self.config.set_key('qt_gui_color_theme', colortheme_combo.itemData(x), True) self.need_restart = True colortheme_combo.currentIndexChanged.connect(on_colortheme) gui_widgets.append((colortheme_label, colortheme_combo)) updatecheck_cb = QCheckBox( _("Automatically check for software updates")) updatecheck_cb.setChecked(bool(self.config.get('check_updates', False))) def on_set_updatecheck(v): self.config.set_key('check_updates', v == Qt.Checked, save=True) updatecheck_cb.stateChanged.connect(on_set_updatecheck) gui_widgets.append((updatecheck_cb, None)) filelogging_cb = QCheckBox(_("Write logs to file")) filelogging_cb.setChecked(bool(self.config.get('log_to_file', False))) def on_set_filelogging(v): self.config.set_key('log_to_file', v == Qt.Checked, save=True) self.need_restart = True filelogging_cb.stateChanged.connect(on_set_filelogging) filelogging_cb.setToolTip( _('Debug logs can be persisted to disk. These are useful for troubleshooting.' )) gui_widgets.append((filelogging_cb, None)) preview_cb = QCheckBox(_('Advanced preview')) preview_cb.setChecked(bool(self.config.get('advanced_preview', False))) preview_cb.setToolTip( _("Open advanced transaction preview dialog when 'Pay' is clicked." )) def on_preview(x): self.config.set_key('advanced_preview', x == Qt.Checked) preview_cb.stateChanged.connect(on_preview) tx_widgets.append((preview_cb, None)) usechange_cb = QCheckBox(_('Use change addresses')) usechange_cb.setChecked(self.window.wallet.use_change) if not self.config.is_modifiable('use_change'): usechange_cb.setEnabled(False) def on_usechange(x): usechange_result = x == Qt.Checked if self.window.wallet.use_change != usechange_result: self.window.wallet.use_change = usechange_result self.window.wallet.db.put('use_change', self.window.wallet.use_change) multiple_cb.setEnabled(self.window.wallet.use_change) usechange_cb.stateChanged.connect(on_usechange) usechange_cb.setToolTip( _('Using change addresses makes it more difficult for other people to track your transactions.' )) tx_widgets.append((usechange_cb, None)) def on_multiple(x): multiple = x == Qt.Checked if self.wallet.multiple_change != multiple: self.wallet.multiple_change = multiple self.wallet.db.put('multiple_change', multiple) multiple_change = self.wallet.multiple_change multiple_cb = QCheckBox(_('Use multiple change addresses')) multiple_cb.setEnabled(self.wallet.use_change) multiple_cb.setToolTip('\n'.join([ _('In some cases, use up to 3 change addresses in order to break ' 'up large coin amounts and obfuscate the recipient address.'), _('This may result in higher transactions fees.') ])) multiple_cb.setChecked(multiple_change) multiple_cb.stateChanged.connect(on_multiple) tx_widgets.append((multiple_cb, None)) def fmt_docs(key, klass): lines = [ln.lstrip(" ") for ln in klass.__doc__.split("\n")] return '\n'.join([key, "", " ".join(lines)]) choosers = sorted(coinchooser.COIN_CHOOSERS.keys()) if len(choosers) > 1: chooser_name = coinchooser.get_name(self.config) msg = _( 'Choose coin (UTXO) selection method. The following are available:\n\n' ) msg += '\n\n'.join( fmt_docs(*item) for item in coinchooser.COIN_CHOOSERS.items()) chooser_label = HelpLabel(_('Coin selection') + ':', msg) chooser_combo = QComboBox() chooser_combo.addItems(choosers) i = choosers.index(chooser_name) if chooser_name in choosers else 0 chooser_combo.setCurrentIndex(i) def on_chooser(x): chooser_name = choosers[chooser_combo.currentIndex()] self.config.set_key('coin_chooser', chooser_name) chooser_combo.currentIndexChanged.connect(on_chooser) tx_widgets.append((chooser_label, chooser_combo)) def on_unconf(x): self.config.set_key('confirmed_only', bool(x)) conf_only = bool(self.config.get('confirmed_only', False)) unconf_cb = QCheckBox(_('Spend only confirmed coins')) unconf_cb.setToolTip(_('Spend only confirmed inputs.')) unconf_cb.setChecked(conf_only) unconf_cb.stateChanged.connect(on_unconf) tx_widgets.append((unconf_cb, None)) def on_outrounding(x): self.config.set_key('coin_chooser_output_rounding', bool(x)) enable_outrounding = bool( self.config.get('coin_chooser_output_rounding', True)) outrounding_cb = QCheckBox(_('Enable output value rounding')) outrounding_cb.setToolTip( _('Set the value of the change output so that it has similar precision to the other outputs.' ) + '\n' + _('This might improve your privacy somewhat.') + '\n' + _('If enabled, at most 100 satoshis might be lost due to this, per transaction.' )) outrounding_cb.setChecked(enable_outrounding) outrounding_cb.stateChanged.connect(on_outrounding) tx_widgets.append((outrounding_cb, None)) block_explorers = sorted(util.block_explorer_info().keys()) msg = _( 'Choose which online block explorer to use for functions that open a web browser' ) block_ex_label = HelpLabel(_('Online Block Explorer') + ':', msg) block_ex_combo = QComboBox() block_ex_combo.addItems(block_explorers) block_ex_combo.setCurrentIndex( block_ex_combo.findText(util.block_explorer(self.config))) def on_be(x): be_result = block_explorers[block_ex_combo.currentIndex()] self.config.set_key('block_explorer', be_result, True) block_ex_combo.currentIndexChanged.connect(on_be) tx_widgets.append((block_ex_label, block_ex_combo)) # Fiat Currency hist_checkbox = QCheckBox() hist_capgains_checkbox = QCheckBox() fiat_address_checkbox = QCheckBox() ccy_combo = QComboBox() ex_combo = QComboBox() def update_currencies(): if not self.window.fx: return currencies = sorted( self.fx.get_currencies(self.fx.get_history_config())) ccy_combo.clear() ccy_combo.addItems([_('None')] + currencies) if self.fx.is_enabled(): ccy_combo.setCurrentIndex( ccy_combo.findText(self.fx.get_currency())) def update_history_cb(): if not self.fx: return hist_checkbox.setChecked(self.fx.get_history_config()) hist_checkbox.setEnabled(self.fx.is_enabled()) def update_fiat_address_cb(): if not self.fx: return fiat_address_checkbox.setChecked(self.fx.get_fiat_address_config()) def update_history_capgains_cb(): if not self.fx: return hist_capgains_checkbox.setChecked( self.fx.get_history_capital_gains_config()) hist_capgains_checkbox.setEnabled(hist_checkbox.isChecked()) def update_exchanges(): if not self.fx: return b = self.fx.is_enabled() ex_combo.setEnabled(b) if b: h = self.fx.get_history_config() c = self.fx.get_currency() exchanges = self.fx.get_exchanges_by_ccy(c, h) else: exchanges = self.fx.get_exchanges_by_ccy('USD', False) ex_combo.blockSignals(True) ex_combo.clear() ex_combo.addItems(sorted(exchanges)) ex_combo.setCurrentIndex( ex_combo.findText(self.fx.config_exchange())) ex_combo.blockSignals(False) def on_currency(hh): if not self.fx: return b = bool(ccy_combo.currentIndex()) ccy = str(ccy_combo.currentText()) if b else None self.fx.set_enabled(b) if b and ccy != self.fx.ccy: self.fx.set_currency(ccy) update_history_cb() update_exchanges() self.window.update_fiat() def on_exchange(idx): exchange = str(ex_combo.currentText()) if self.fx and self.fx.is_enabled( ) and exchange and exchange != self.fx.exchange.name(): self.fx.set_exchange(exchange) def on_history(checked): if not self.fx: return self.fx.set_history_config(checked) update_exchanges() self.window.history_model.refresh('on_history') if self.fx.is_enabled() and checked: self.fx.trigger_update() update_history_capgains_cb() def on_history_capgains(checked): if not self.fx: return self.fx.set_history_capital_gains_config(checked) self.window.history_model.refresh('on_history_capgains') def on_fiat_address(checked): if not self.fx: return self.fx.set_fiat_address_config(checked) self.window.address_list.refresh_headers() self.window.address_list.update() update_currencies() update_history_cb() update_history_capgains_cb() update_fiat_address_cb() update_exchanges() ccy_combo.currentIndexChanged.connect(on_currency) hist_checkbox.stateChanged.connect(on_history) hist_capgains_checkbox.stateChanged.connect(on_history_capgains) fiat_address_checkbox.stateChanged.connect(on_fiat_address) ex_combo.currentIndexChanged.connect(on_exchange) fiat_widgets = [] fiat_widgets.append((QLabel(_('Fiat currency')), ccy_combo)) fiat_widgets.append((QLabel(_('Source')), ex_combo)) fiat_widgets.append((QLabel(_('Show history rates')), hist_checkbox)) fiat_widgets.append((QLabel(_('Show capital gains in history')), hist_capgains_checkbox)) fiat_widgets.append((QLabel(_('Show Fiat balance for addresses')), fiat_address_checkbox)) tabs_info = [ (gui_widgets, _('General')), (tx_widgets, _('Transactions')), (lightning_widgets, _('Lightning')), (fiat_widgets, _('Fiat')), (oa_widgets, _('OpenAlias')), ] for widgets, name in tabs_info: tab = QWidget() tab_vbox = QVBoxLayout(tab) grid = QGridLayout() for a, b in widgets: i = grid.rowCount() if b: if a: grid.addWidget(a, i, 0) grid.addWidget(b, i, 1) else: grid.addWidget(a, i, 0, 1, 2) tab_vbox.addLayout(grid) tab_vbox.addStretch(1) tabs.addTab(tab, name) vbox.addWidget(tabs) vbox.addStretch(1) vbox.addLayout(Buttons(CloseButton(self))) self.setLayout(vbox)
def initUI(self): self.img_label = ImageLabel() self.img_label.setBackgroundRole(QPalette.Base) self.img_label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.img_label.setScaledContents(True) self.scroll_area = QScrollArea() self.scroll_area.setBackgroundRole(QPalette.Light) self.scroll_area.setWidget(self.img_label) self.scroll_area.setVisible(True) self.file_menu = self.menuBar().addMenu('&File') self.file_open_menu = self.file_menu.addAction(self.tr('Open')) self.file_open_menu.setShortcut(QKeySequence.Open) self.file_open_menu.setStatusTip( 'select directory with data and media') self.view_menu = self.menuBar().addMenu(self.tr('&View')) self.zoom_in_act = self.view_menu.addAction(self.tr('Zoom &In')) self.zoom_in_act.setShortcut(QKeySequence.ZoomIn) self.zoom_out_act = self.view_menu.addAction(self.tr('Zoom &Out')) self.zoom_out_act.setShortcut(QKeySequence.ZoomOut) self.zoom_reset_act = self.view_menu.addAction(self.tr('Zoom &Reset')) self.zoom_reset_act.setShortcut(self.tr('Ctrl+N')) self.fit_act = self.view_menu.addAction(self.tr('&Fit Window')) self.fit_act.setShortcut(self.tr('Ctrl+F')) self.fit_act.setCheckable(True) self.view_menu.addSeparator() self.grid_act = self.view_menu.addAction(self.tr('Grid')) self.grid_act.setShortcut('Ctrl+G') self.grid_act.setCheckable(True) self.slider = QSlider(Qt.Horizontal) self.slider.setMaximum(10) self.data_button = QPushButton('Data') self.media_button = QPushButton('Media') self.minus_100_button = QPushButton('-100') self.minus_5_button = QPushButton('-5') self.minus_1_button = QPushButton('-1') self.plus_1_button = QPushButton('+1') self.plus_5_button = QPushButton('+5') self.plus_100_button = QPushButton('+100') self.index_label = QLabel('000/000') hbox = QHBoxLayout() hbox.addStretch() for w in [ self.data_button, self.minus_100_button, self.minus_5_button, self.minus_1_button, self.index_label, self.plus_1_button, self.plus_5_button, self.plus_100_button, self.media_button ]: hbox.addWidget(w) hbox.addStretch() vbox = QVBoxLayout() vbox.addWidget(self.scroll_area) #vbox.addStretch() vbox.addWidget(self.slider) vbox.addLayout(hbox) cw = QWidget() cw.setLayout(vbox) self.setCentralWidget(cw) self.statusBar().showMessage('') self.setGeometry(0, 0, self.WINDOW_WIDTH, self.WINDOW_HEIGHT)