def testPropertyValues(self): app = QApplication(sys.argv) textEdit = QPlainTextEdit() textEdit.insertPlainText("PySide INdT") selection = QTextEdit.ExtraSelection() selection.cursor = textEdit.textCursor() selection.cursor.setPosition(2) self.assertEqual(selection.cursor.position(), 2)
def __init__(self): super(MainWindow, self).__init__() hBoxLayout = QHBoxLayout(self) self.plainTextEdit = QPlainTextEdit() self.plainTextEdit.setMinimumWidth(400) self.plainTextEdit.setReadOnly(True) hBoxLayout.addWidget(self.plainTextEdit) self.renderWindow = RenderWindow(QSurfaceFormat()) container = QWidget.createWindowContainer(self.renderWindow) container.setMinimumSize(QSize(400, 400)) hBoxLayout.addWidget(container)
class MainWindow(QWidget): def __init__(self): super(MainWindow, self).__init__() hBoxLayout = QHBoxLayout(self) self.plainTextEdit = QPlainTextEdit() self.plainTextEdit.setMinimumWidth(400) self.plainTextEdit.setReadOnly(True) hBoxLayout.addWidget(self.plainTextEdit) self.renderWindow = RenderWindow(QSurfaceFormat()) container = QWidget.createWindowContainer(self.renderWindow) container.setMinimumSize(QSize(400, 400)) hBoxLayout.addWidget(container) def updateDescription(self): text = "{}\n\nPython {}\n\n{}".format(QLibraryInfo.build(), sys.version, self.renderWindow.glInfo()) self.plainTextEdit.setPlainText(text)
class EditWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.logData: Class.LogInfo = None self.resultMap = dict() self._initUI() self._initData() def getLogData(self): return self.logData def setLogData(self, data: Class.LogInfo): self.logData = data self.topText.setPlainText(self.logData.data) def toPlainText(self): return self.topText.toPlainText() def _initUI(self): self.mainLayout = QVBoxLayout(self) self.topText = QPlainTextEdit(self) self.topText.setLineWrapMode(QPlainTextEdit.NoWrap) self.topText.setCenterOnScroll(True) self.topText.setAcceptDrops(False) self.topText.verticalScrollBar() self.bottomText = QTabWidget(self) self.bottomText.setDocumentMode(True) self.bottomText.setMovable(True) self.bottomText.setTabsClosable(True) self.bottomText.tabCloseRequested.connect(self.tabCloseRequested) self.mainLayout.addWidget(self.topText, 1) self.mainLayout.addWidget(self.bottomText, 1) self.setLayout(self.mainLayout) def tabCloseRequested(self, index): self.bottomText.removeTab(index) def _initData(self): pass # self.topText.setPlainText('''10-18 16:52:37.542544 13034 13073 D _V_CommonModel: [VivoVideo]onLoaded # 10-18 16:52:37.545425 13034 13034 D EventBus: No subscribers registered for event class com.vivo.video.baselibrary.lifecycle.PlayerStateChangeEvent # 10-18 16:52:37.545536 13034 13034 D EventBus: No subscribers registered for event class org.greenrobot.eventbus.g # 10-18 16:52:37.559381 2359 2359 I _V_MainThreadMonitor: scheduleCheck true, true, 900 # 10-18 16:52:37.561130 13034 13034 D _V_LiveTabFragment: [VivoVideo]liveCategory load onsuccess # 10-18 16:52:37.561572 714 791 D BufferLayer: triger signalLayerUpdate # 10-18 16:52:37.561937 13034 13034 D _V_LiveCategoryFragmentAdapter: [VivoVideo]com.vivo.video.app.home.HomeActivity@489a20a # 10-18 16:52:37.565738 13034 13034 D _V_BaseFragment: [VivoVideo]init onCreateView # 10-18 16:52:37.576986 13034 13034 I RepluginBridge: getApi,clazz:interface com.unionyy.mobile.vivo.api.VV2YYInfoAction # 10-18 16:52:37.577233 13034 13034 I RepluginBridge: getApi,clazz:interface com.unionyy.mobile.vivo.api.VV2YYAuthAction # 10-18 16:52:37.577331 13034 13034 I RepluginBridge: getApi,clazz:interface com.unionyy.mobile.vivo.api.VV2YYInfoAction # 10-18 16:52:37.577359 13034 13034 I RepluginBridge: getApi,clazz:interface com.unionyy.mobile.vivo.api.VV2YYAuthAction''') def cursorPositionChanged(self): print("cursorPositionChanged") def handlerFilterResult(self, filterResult): result = self.resultMap.get(filterResult.orgTag) if result: print("已存在%s" % filterResult.orgTag) result.setPlainText(filterResult.value) else: print("未存在%s" % filterResult.orgTag) filterResultView = QPlainTextEdit(self) highlighter = LogQSyntaxHighlighter(filterResultView.document()) highlighter.setHighlignterTags(filterResult.tag) filterResultView.setPlainText(filterResult.value) filterResultView.setLineWrapMode(QPlainTextEdit.NoWrap) filterResultView.cursorPositionChanged.connect( self.cursorPositionChanged) self.bottomText.addTab(filterResultView, filterResult.orgTag) self.bottomText.setCurrentIndex(self.bottomText.count() - 1) self.resultMap.setdefault(filterResult.orgTag, filterResultView) def destroy(self, destroyWindow: bool = ..., destroySubWindows: bool = ...): RxBus.instance.unRegister(self) super.destroy(destroyWindow, destroySubWindows) print("destroy") def create(self, arg__1: int = ..., initializeWindow: bool = ..., destroyOldWindow: bool = ...): super.create(arg__1, initializeWindow, destroyOldWindow) print("create")
class BarrenLandsWindow(QMainWindow): """User interface to interact with the barren lands library.""" def __init__(self, width=400, height=600, zones=None): """Initialization of BarrenLands GUI Args: width (int): The width of the canvas/field. height (int): The height of the canvas/field. zones (str): Text data to add to raw input if provided. """ QMainWindow.__init__(self) self.app = QApplication.instance() self.resources = pathlib.Path(__file__).parent self.results = set() self.canvas_width = width self.canvas_height = height self.user_input = zones # Colors for drawing onto the QGraphicsScene self.brush_barren = QBrush(QColor(120, 120, 75), Qt.Dense2Pattern) self.brush_overlay = QBrush(QColor(20, 20, 20, 35), Qt.SolidPattern) self.brush_innerlay = QBrush(QColor(32, 37, 44), Qt.SolidPattern) self.brush_fertile = QBrush(QColor(90, 220, 90, 150), Qt.Dense5Pattern) self.brush_fertile_no_go = QBrush(QColor(90, 220, 90, 150), Qt.BDiagPattern) # Setup the filed class that will handle our calculations. self.field = land.Field(width=self.canvas_width, height=self.canvas_height) self.barren_zones = list() self.fertile_zones = list() self.setup_window() self.build_core_ui() self.build_controls() def setup_window(self): """Setup all the window related settings/flags.""" self.setWindowTitle("Barren Lands") self.setMinimumHeight(600) self.setMinimumWidth(700) self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) self.setWindowIcon(QIcon(utils.get_icon())) self.setStyleSheet(utils.get_css()) def build_core_ui(self): """Sets up the core elements of this window. Notes: Setting up QGraphicsScene: https://stackoverflow.com/questions/23174481/pyside-qt-layout-not-working """ self.base_widget = QWidget(self) self.layout_base = QHBoxLayout(self.base_widget) self.layout_canvas = QVBoxLayout() self.setContentsMargins(0, 0, 0, 0) # Setup the QGraphics items to display out zones as active elements. scene_zone = QRect(0, 0, self.canvas_width, self.canvas_height) self.scene = QGraphicsScene(scene_zone, self) self.canvas = QGraphicsView(self.scene, self) self.canvas.setFixedSize(self.canvas_width + 1, self.canvas_height + 1) # Draw faint bullseye for target. self.scene.addEllipse(self.get_center_rect(300), Qt.NoPen, self.brush_overlay) self.scene.addEllipse(self.get_center_rect(200), Qt.NoPen, self.brush_innerlay) self.scene.addEllipse(self.get_center_rect(100), Qt.NoPen, self.brush_overlay) self.layout_canvas.addWidget(self.canvas) self.lbl_island = QLabel("Island Areas:") self.layout_canvas.addWidget(self.lbl_island) self.layout_base.addLayout(self.layout_canvas) # Set the core widget to the window. self.setCentralWidget(self.base_widget) def get_center_rect(self, size): """Generates a QRect that is at the center of the canvas and it's width/height set to size. Args: size (int): The size to set the bounds to. Returns: (QRectF): A rectangle coordinate that is center on the canvas with a given size. """ return QRectF(self.canvas_width * 0.5 - (size * 0.5), self.canvas_height * 0.5 - (size * 0.5), size, size) def build_controls(self): """Build the control panel that contains all the inputs.""" self.controls = QWidget(self) self.layout_controls = QVBoxLayout(self.controls) self.layout_controls.setContentsMargins(0, 0, 0, 0) # Initialize the text box for user input self.input = self.build_coord_input() # Create the buttons self.btn_add_bzone = BarrenButton(label="Add", parent=self, cmd=self.ctl_add_input) self.btn_run = BarrenButton(label="Analyze", parent=self, cmd=self.ctl_run) # Build the utility buttons self.layout_btm_btn = QHBoxLayout() self.layout_btm_btn.setContentsMargins(0, 0, 0, 0) self.btn_reset = BarrenButton(label="Reset All", parent=self, cmd=self.ctl_clear_zones) self.btn_debug = BarrenButton(label="Debug", parent=self, cmd=self.ctr_debug) self.layout_btm_btn.addWidget(self.btn_debug) self.layout_btm_btn.addWidget(self.btn_reset) self.results_grp = self.build_results_group() self.lbl_area = QLabel("Total Area: 0") self.lbl_area.setAlignment(Qt.AlignCenter) # Add everything to the controls layout self.layout_controls.addLayout(self.input) self.layout_controls.addWidget(self.btn_add_bzone) self.layout_controls.addWidget(self.btn_run) self.layout_controls.addWidget(self.results_grp) self.layout_controls.addWidget(self.lbl_area) self.layout_controls.addLayout(self.layout_btm_btn) # Add to the windows base layout. self.layout_base.addWidget(self.controls) def build_results_group(self): """Build the results group to contain the results of analysis. Returns: results_grp (QGroupBox): The group box that contains the results layout. """ grp_results = QGroupBox("Results: Largest island zone.") grp_results.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # Add a layout to hold all the results from the Analysis. self.layout_results = QVBoxLayout() self.layout_results.setContentsMargins(0, 0, 0, 0) grp_results.setLayout(self.layout_results) return grp_results def build_coord_input(self): """Build the necessary elements for the user input text box. Returns: (QVBoxLayout): The base layout of the coord input. """ layout_base = QVBoxLayout() layout_base.setContentsMargins(0, 0, 0, 0) self.raw_input = QPlainTextEdit() self.raw_input.setMaximumHeight(75) self.raw_input.setPlaceholderText('example: "0 292 399 307"') if self.user_input: self.raw_input.setPlainText(self.user_input) self.layout_input = QVBoxLayout() self.layout_input.setContentsMargins(0, 0, 0, 0) layout_base.addWidget(self.raw_input) layout_base.addLayout(self.layout_input) return layout_base def ctr_debug(self): """CONTROL: Called by the 'debug' button to randomly assign colors to the zones.""" for result in self.results: rand_color = [random.randint(0, 255) for i in range(3)] rand_color = QColor(*rand_color) brush = QBrush(rand_color, Qt.Dense5Pattern) result.rectangle.setBrush(brush) result.base = brush def ctl_add_input(self): """CONTROL: Called by the 'Add' button to handle parsing the raw input.""" raw_data = self.raw_input.toPlainText() if raw_data: parsed_input = utils.format_raw_input(raw_data) for user_input in parsed_input: start_coord = land.Coord(user_input[0], user_input[1]) end_coord = land.Coord(user_input[2], user_input[3]) zone = land.Zone(start_coord, end_coord) self.field.add_zone(zone, barren=True) self.draw_zone(zone, barren=True) def ctl_run(self): """CONTROL: Called by the 'Run' button to initialize the final analysis.""" # Make sure some values are cleared ahead of the analysis. self.clear_results() for rectangle in self.fertile_zones: self.scene.removeItem(rectangle) self.field.fertile_zones = set() # Run the analysis self.field.check_zones() total_area = 0 # Format and draw the results in the QGraphicsScene. for i, island in enumerate(self.field.islands): for zone in island: rectangle = self.draw_zone(zone) size = zone.get_size() if i == 0: # Only add (largest) island to results. Always at 0. total_area += size self.results.add( ResultLabel(label=str(size), rectangle=rectangle, zone=zone)) else: # This zone is fertile, but Inaccessible. rectangle.setBrush(self.brush_fertile_no_go) self.canvas.update() # Pain the update for the user to see the new zone. self.app.processEvents() # Dont show all at the same time. (For more pleasing visual) time.sleep(.015) # Print islands, smallest to largest. print("Islands", self.field.islands_as_area()) island_areas = " ".join(str(i) for i in self.field.islands_as_area()) self.lbl_island.setText(f"Island Areas: {island_areas}") # Set the label as the total area as the largest island. self.lbl_area.setText(f"Total Area: {total_area}") # Sort the results by their zones area. for result in sorted(self.results, key=lambda x: x.zone.get_size()): # Add the result to the results layout in the UI self.layout_results.addWidget(result) def ctl_clear_zones(self): """CONTROL: Called by the 'Reset' button to handle resetting the data and graphics.""" for rectangle in self.barren_zones + self.fertile_zones: self.scene.removeItem(rectangle) self.field.fertile_zones = set() self.fertile_zones = list() self.field.barren_zones = set() self.barren_zones = list() self.clear_results() def clear_results(self): """Clears the results set in preparation for incoming new results.""" for result in self.results: result.deleteLater() self.results = set() self.lbl_area.setText("Total Area:") self.lbl_island.setText("Island Areas:") def draw_zone(self, zone, barren=False): """Creates a QGraphicsRecItem from a Zone and adds it to the scene. Args: zone (Zone): The zone to generate the rectangle from. barren (bool): barren colors if True else fertile color. Returns: (QGraphicsRecItem): The drown rectangle that is added to the canvas. """ # Build the QGraphicsRecItem from the zone data. rectangle = self.scene.addRect(zone.start.x, zone.start.y, zone.end.x - zone.start.x + 1, zone.end.y - zone.start.y + 1) if barren: self.barren_zones.append(rectangle) brush = self.brush_barren else: self.fertile_zones.append(rectangle) brush = self.brush_fertile # Apply the color to the rectangle item. rectangle.setBrush(brush) # Remove the default border rectangle.setPen(Qt.NoPen) return rectangle
class OffenerPostenEditor( QWidget ): """ Zum Editieren eines einzelnen Offenen Postens. """ debiKrediAuswahlFirmaPressed = Signal() debiKrediAuswahlVwPressed = Signal() def __init__( self, x:XOffenerPosten, parent=None ): QWidget.__init__( self, parent ) self._layout = QGridLayout() self.setLayout( self._layout ) self._erfasstAm = SmartDateEdit() self._debiKredi = QLineEdit() self._btnAuswahlDebiKredi_Firma = QPushButton( text="..." ) self._btnAuswahlDebiKredi_Firma.clicked.connect( self._onDebiKrediAuswahl_Firma ) self._btnAuswahlDebiKredi_Vw = QPushButton( text="..." ) self._btnAuswahlDebiKredi_Vw.clicked.connect( self._onDebiKrediAuswahl_Vw ) self._betrag = FloatEdit() self._betragBeglichen = FloatEdit() self._letzteBuchungAm = SmartDateEdit() self._bemerkung = QPlainTextEdit() self._offenerPosten:XOffenerPosten = x self._createGui() self._dataToGui() def _createGui( self ): r = c = 0 l = self._layout self._erfasstAm.setPlaceholderText( "erfasst am" ) self._erfasstAm.setToolTip( "Erfassungsdatum des Offenen Postens" ) self._erfasstAm.setMaximumWidth( 90 ) l.addWidget( self._erfasstAm, r, c ) c += 1 self._debiKredi.setMinimumWidth( 250 ) self._debiKredi.setPlaceholderText( "Debitor oder Kreditor" ) self._debiKredi.setToolTip( "Debitor oder Kreditor eintragen" ) l.addWidget( self._debiKredi, r, c ) c += 1 vbox = QVBoxLayout() vbox.addWidget( self._btnAuswahlDebiKredi_Firma ) self._btnAuswahlDebiKredi_Firma.setFixedSize( QSize( 30, 30 ) ) self._btnAuswahlDebiKredi_Firma.setToolTip( "Öffnet einen Dialog zur Auswahl einer Firma " "als Debitor oder Kreditor" ) vbox.addWidget( self._btnAuswahlDebiKredi_Vw ) self._btnAuswahlDebiKredi_Vw.setFixedSize( QSize( 30, 30 ) ) self._btnAuswahlDebiKredi_Vw.setToolTip( "Öffnet einen Dialog zur Auswahl eines Verwalters " "als Debitor oder Kreditor" ) l.addLayout( vbox, r, c ) #l.addWidget( self._btnAuswahlDebiKredi, r, c ) c += 1 self._betrag.setPlaceholderText( "Betrag" ) self._betrag.setToolTip( "Ursprünglicher offener Betrag. '-' = Debit, '+' = Kredit" ) self._betrag.setFixedWidth( 80 ) l.addWidget( self._betrag, r, c ) c += 1 self._betragBeglichen.setPlaceholderText( "bezahlt" ) self._betragBeglichen.setToolTip( "Bereits bezahlter Betrag" ) self._betragBeglichen.setFixedWidth( 80 ) l.addWidget( self._betragBeglichen, r, c ) c += 1 self._letzteBuchungAm.setPlaceholderText( "letzte Buchg" ) self._letzteBuchungAm.setToolTip( "Datum der letzten (Teil-)Buchung" ) self._letzteBuchungAm.setMaximumWidth( 90 ) l.addWidget( self._letzteBuchungAm, r, c ) c += 1 self._bemerkung.setToolTip( "Bemerkung - z.B. Dokumentation von Teilzahlungen" ) self._bemerkung.setPlaceholderText( "Bemerkung" ) self._bemerkung.setMaximumHeight( 60 ) l.addWidget( self._bemerkung, r, c ) def _dataToGui( self ) -> None: x = self._offenerPosten self._erfasstAm.setDateFromIsoString( x.erfasst_am ) self._debiKredi.setText( x.debi_kredi ) self._betrag.setFloatValue( x.betrag ) self._betragBeglichen.setFloatValue( x.betrag_beglichen ) if x.letzte_buchung_am: self._letzteBuchungAm.setDateFromIsoString( x.letzte_buchung_am ) self._bemerkung.setPlainText( x.bemerkung ) def guiToData( self ) -> None: x = self._offenerPosten x.erfasst_am = self._erfasstAm.getDate() x.debi_kredi = self._debiKredi.text() x.betrag = self._betrag.getFloatValue() x.betrag_beglichen = self._betragBeglichen.getFloatValue() x.letzte_buchung_am = self._letzteBuchungAm.getDate() x.bemerkung = self._bemerkung.toPlainText() def getOposCopyWithChanges( self ) -> XOffenerPosten: """ liefert eine Kopie des in ARbeit befindlichen XOffenerPosten-Objekts. Die in der GUI vorgenommenen Änderungen sind darin enthalten. Die Änderungen sind NICHT im Original-OPOS enthalten! Das Einfügen der Änderungen in das Original-OPOS passiert durch Aufruf von guiToData(). :return: eine Kopie des Original-OPOS mit Änderungen """ xcopy = copy.copy( self._offenerPosten ) xcopy.erfasst_am = self._erfasstAm.getDate() xcopy.debi_kredi = self._debiKredi.text() xcopy.betrag = self._betrag.getFloatValue() xcopy.betrag_beglichen = self._betragBeglichen.getFloatValue() xcopy.letzte_buchung_am = self._letzteBuchungAm.getDate() xcopy.bemerkung = self._bemerkung.toPlainText() return xcopy def _onDebiKrediAuswahl_Firma( self ): self.debiKrediAuswahlFirmaPressed.emit() def _onDebiKrediAuswahl_Vw( self ): self.debiKrediAuswahlVwPressed.emit() def setOffenerPosten( self, x:XOffenerPosten ): self._offenerPosten = x if x.erfasst_am > "": self._erfasstAm.setDateFromIsoString( x.erfasst_am ) self._debiKredi.setText( x.debi_kredi ) self._betrag.setFloatValue( x.betrag ) self._betragBeglichen.setFloatValue( x.betrag_beglichen ) if x.letzte_buchung_am > "": self._letzteBuchungAm.setDateFromIsoString( x.letzte_buchung_am ) self._bemerkung.setPlainText( x.bemerkung ) def getOffenerPosten( self ) -> XOffenerPosten: x = self._offenerPosten if x is None: return XOffenerPosten() x.erfasst_am = self._erfasstAm.getDate() x.debi_kredi = self._debiKredi.text() x.betrag = self._betrag.getFloatValue() x.betrag_beglichen = self._betragBeglichen.getFloatValue() x.letzte_buchung_am = self._letzteBuchungAm.getDate() x.bemerkung = self._bemerkung.toPlainText() return x def setDebiKredi( self, debikredi:str ): self._debiKredi.setText( debikredi )
class GridTransformerDialog(QDialog): def __init__(self, parent=None): super(GridTransformerDialog, self).__init__( parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint) self.setWindowTitle("Grid Transformer") self.setWindowIcon(qta.icon('fa.th')) # dict to store inputs that will get passed to the grid transformer # this gets validated to ensure all the bits of info are in it before # the run button gets enabled self.grid_transformer_inputs = {} self.layout = QVBoxLayout() self.setLayout(self.layout) self._add_inputs() self._add_output() self._add_process() close_layout = QHBoxLayout() close_layout.addStretch() button_close = QPushButton("Close") button_close.clicked.connect(self.close_dialog) close_layout.addWidget(button_close) self.layout.addLayout(close_layout) def _add_inputs(self): inputs_groupbox = QGroupBox("Inputs") inputs_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) inputs_layout = QVBoxLayout() inputs_layout.setSpacing(0) inputs_groupbox.setLayout(inputs_layout) for input_band_name in input_band_names: inputband = GridTransformerInputBand(input_band_name) inputs_layout.addWidget(inputband) inputband.band_selected.connect(self._band_selected) inputband.log_message.connect(self._log_message) self.layout.addWidget(inputs_groupbox) def _band_selected(self, band_details): band_name, filename, band_index = band_details self.grid_transformer_inputs[band_name] = (filename, band_index) self.validate() def validate(self): self.run_button.setEnabled(self._is_valid()) def _is_valid(self) -> bool: '''Is this ready to run, as in has the user specified all inputs needed for the grid transformer''' for band_name in input_band_names: if band_name not in self.grid_transformer_inputs: return False if self.grid_transformer_inputs[band_name] is None: return False if 'output' not in self.grid_transformer_inputs: return False return True def _log_message(self, message): self.log_messages.appendPlainText(message) def _add_output(self): output_groupbox = QGroupBox("Output") output_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) output_layout = QVBoxLayout() output_layout.setSpacing(0) output_groupbox.setLayout(output_layout) output_file_layout = QHBoxLayout() output_file_layout.setSpacing(4) self.output_file_input = QLineEdit() self.output_file_input.textChanged.connect( self._on_output_filename_changed) self.output_file_input.setMinimumWidth(400) self.output_file_input.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) output_file_layout.addWidget(self.output_file_input) output_layout.addLayout(output_file_layout) self.open_output_file_button = QPushButton() output_file_layout.addWidget(self.open_output_file_button) self.open_output_file_button.setIcon(qta.icon('fa.folder-open')) self.open_output_file_button.setToolTip("Select output file location") self.open_output_file_button.clicked.connect(self._click_open_output) self.layout.addWidget(output_groupbox) def _on_output_filename_changed(self, filename): self.grid_transformer_inputs['output'] = filename self.validate() def _set_output_filename(self, filename): self.output_file_input.setText(filename) self.grid_transformer_inputs['output'] = filename self.validate() def _click_open_output(self): filters = ("GeoTIFF (*.tif *.tiff)") filename, _ = QFileDialog.getSaveFileName( self, f"Select output file", GuiSettings.settings().value(output_folder_settings), filters) if filename is None: return last_open_folder = os.path.dirname(filename) if os.path.exists(last_open_folder): GuiSettings.settings().setValue(output_folder_settings, last_open_folder) self._set_output_filename(filename) def _add_process(self): process_groupbox = QGroupBox("Process") process_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) process_layout = QVBoxLayout() process_layout.setSpacing(0) process_groupbox.setLayout(process_layout) pbar_frame = QFrame() pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) pbar_hbox = QHBoxLayout() pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16)) pbar_hbox.setSpacing(16) # Run and stop buttons hbox = QHBoxLayout() hbox.setSpacing(8) self.run_button = QPushButton() # is only enabled when validation passes self.run_button.setEnabled(False) self.run_button.setText("Run") self.run_button.setFixedWidth(100) run_icon = qta.icon('fa.play', color='green') self.run_button.setIcon(run_icon) self.run_button.clicked.connect(self._click_run) hbox.addWidget(self.run_button) self.stop_button = QPushButton() self.stop_button.setEnabled(False) self.stop_button.setText("Stop") self.stop_button.setFixedWidth(100) stop_icon = qta.icon('fa.stop', color='red') self.stop_button.setIcon(stop_icon) self.stop_button.clicked.connect(self._click_stop) hbox.addWidget(self.stop_button) self.progress_bar = QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setAlignment(QtCore.Qt.AlignCenter) self.progress_bar.setValue(0) self.progress_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) pbar_hbox.addLayout(hbox) pbar_hbox.addWidget(self.progress_bar) pbar_frame.setLayout(pbar_hbox) process_layout.addWidget(pbar_frame) self.warning_frame = QFrame() self.warning_frame.setVisible(False) self.warning_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() warning_icon_widget = qta.IconWidget('fa.warning', color='red') warning_icon_widget.setIconSize(QtCore.QSize(48, 48)) warning_icon_widget.update() hbox.addWidget(warning_icon_widget) warning_label = QLabel( "Grid Transformer did not complete successfully. Please refer to " "log output.") warning_label.setStyleSheet("QLabel { color: red; }") warning_label.setWordWrap(True) warning_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(warning_label) self.warning_frame.setLayout(hbox) process_layout.addWidget(self.warning_frame) self.success_frame = QFrame() self.success_frame.setVisible(False) self.success_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() success_icon_widget = qta.IconWidget('fa.check', color='green') success_icon_widget.setIconSize(QtCore.QSize(48, 48)) success_icon_widget.update() hbox.addWidget(success_icon_widget) success_label = QLabel("Grid Transformer completed successfully.") success_label.setStyleSheet("QLabel { color: green; }") success_label.setWordWrap(True) success_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(success_label) self.success_frame.setLayout(hbox) process_layout.addWidget(self.success_frame) log_layout = QVBoxLayout() log_layout.setSpacing(4) log_label = QLabel("Log messages") log_label.setStyleSheet("QLabel { color: grey; }") log_layout.addWidget(log_label) self.log_messages = QPlainTextEdit() log_font = QFont("monospace") log_font.setStyleHint(QFont.TypeWriter) self.log_messages.setFont(log_font) self.log_messages.setReadOnly(True) self.log_messages.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # self.log_messages.sizePolicy.setVerticalStretch(1) log_layout.addWidget(self.log_messages) process_layout.addLayout(log_layout) self.layout.addWidget(process_groupbox) def _on_progress(self, progress): self.progress_bar.setValue(int(progress * 100)) def _on_complete(self, successful: bool): self.warning_frame.setVisible(not successful) self.success_frame.setVisible(successful) self.stop_button.setEnabled(False) self.run_button.setEnabled(True) run_time = time.perf_counter() - self.start_time self._log_message( f"Total grid transformation time = {run_time:.2f} sec") self._log_message("\n\n") def _click_run(self): self.warning_frame.setVisible(False) self.success_frame.setVisible(False) self.stop_button.setEnabled(True) self.run_button.setEnabled(False) self.gt_executor = QtGridTransformerThread( self.grid_transformer_inputs) self.gt_executor.progress.connect(self._on_progress) self.gt_executor.message.connect(self._log_message) self.gt_executor.complete.connect(self._on_complete) self.start_time = time.perf_counter() self._log_message("\n\nStarting Grid Transformer process") self.gt_executor.start() def _click_stop(self): if self.gt_executor is not None: self.gt_executor.stop() def close_dialog(self): self.close()
def __init__(self, *args, **kwargs): super(Notepad, self).__init__(*args, **kwargs) self.setWindowIcon(QIcon('arti.PNG')) self.setGeometry(200, 100, 700, 400) layout = QVBoxLayout() self.editor = QPlainTextEdit() self.editor.setFont(QFont('Roboto', 12)) # self.path holds the path of the currently open file. # If none, we haven't got a file open yet (or creating new). self.path = None layout.addWidget(self.editor) container = QWidget() container.setLayout(layout) self.setCentralWidget(container) self.status = QStatusBar() self.setStatusBar(self.status) file_toolbar = QToolBar("File") file_toolbar.setIconSize(QSize(14, 14)) self.addToolBar(file_toolbar) file_menu = self.menuBar().addMenu("&File") open_file_action = QAction(QIcon(), "Open file...", self) open_file_action.setStatusTip("Open file") open_file_action.triggered.connect(self.file_open) file_menu.addAction(open_file_action) file_toolbar.addAction(open_file_action) open_file_action.setShortcut(QKeySequence('Ctrl+O')) save_file_action = QAction(QIcon(), "Save", self) save_file_action.setStatusTip("Save current page") save_file_action.triggered.connect(self.file_save) file_menu.addAction(save_file_action) file_toolbar.addAction(save_file_action) save_file_action.setShortcut(QKeySequence('Ctrl+S')) saveas_file_action = QAction(QIcon(), "Save As...", self) saveas_file_action.setStatusTip("Save current page to specified file") saveas_file_action.triggered.connect(self.file_saveas) file_menu.addAction(saveas_file_action) file_toolbar.addAction(saveas_file_action) saveas_file_action.setShortcut(QKeySequence('Ctrl+Shift+S')) print_action = QAction(QIcon(), "Print...", self) print_action.setStatusTip("Print current page") print_action.triggered.connect(self.file_print) file_menu.addAction(print_action) file_toolbar.addAction(print_action) print_action.setShortcut(QKeySequence('Ctrl+P')) edit_toolbar = QToolBar("Edit") edit_toolbar.setIconSize(QSize(16, 16)) self.addToolBar(edit_toolbar) edit_menu = self.menuBar().addMenu("&Edit") undo_action = QAction(QIcon(), "Undo", self) undo_action.setStatusTip("Undo last change") undo_action.triggered.connect(self.editor.undo) edit_menu.addAction(undo_action) undo_action.setShortcut(QKeySequence('Ctrl+Z')) redo_action = QAction(QIcon(), "Redo", self) redo_action.setStatusTip("Redo last change") redo_action.triggered.connect(self.editor.redo) edit_toolbar.addAction(redo_action) edit_menu.addAction(redo_action) redo_action.setShortcut(QKeySequence('Ctrl+Y')) edit_menu.addSeparator() cut_action = QAction(QIcon(), "Cut", self) cut_action.setStatusTip("Cut selected text") cut_action.triggered.connect(self.editor.cut) edit_toolbar.addAction(cut_action) edit_menu.addAction(cut_action) cut_action.setShortcut(QKeySequence('Ctrl+X')) copy_action = QAction(QIcon(), "Copy", self) copy_action.setStatusTip("Copy selected text") copy_action.triggered.connect(self.editor.copy) edit_toolbar.addAction(copy_action) edit_menu.addAction(copy_action) copy_action.setShortcut(QKeySequence('Ctrl+C')) paste_action = QAction(QIcon(), "Paste", self) paste_action.setStatusTip("Paste from clipboard") paste_action.triggered.connect(self.editor.paste) edit_toolbar.addAction(paste_action) edit_menu.addAction(paste_action) paste_action.setShortcut(QKeySequence('Ctrl+V')) select_action = QAction(QIcon(), "Select all", self) select_action.setStatusTip("Select all text") select_action.triggered.connect(self.editor.selectAll) edit_menu.addAction(select_action) select_action.setShortcut(QKeySequence('Ctrl+A')) edit_menu.addSeparator() wrap_action = QAction(QIcon(), "Wrap text to window", self) wrap_action.setStatusTip("Toggle wrap text to window") wrap_action.setCheckable(True) wrap_action.setChecked(True) wrap_action.triggered.connect(self.edit_toggle_wrap) edit_menu.addAction(wrap_action) self.update_title() self.show()
class micGui(QWidget): app_icon = QIcon() app = QApplication([]) handlers = han.Handlers(50) changesAvailable = True changed = -1 #0: handle, #1: type, #2: resolution, #3: rate handleUpdated = -1 sliders = [] comboBoxResol = 0 comboBoxRate = 0 resolIndex = -1 rateIndex = -1 modeIndex = -1 filterIndex = -1 guiSettings = guiSettings(initValues=[0, 2, 3, 0, 50]) queue = Queue() # Initializes graphical setup and updates queue def __init__(self, queue, numberOfHandles=10): super(micGui, self).__init__() self.setupGui(numberOfHandles) self.queue = queue # Configs graphical elements and their initializations def setupGui(self, numberOfHandles): self.configWindow() self.configureBackground() self.resolutionOptions() self.samplingRateOptions() self.modeOptions() self.showSettingsButton() for i in range(numberOfHandles): self.sliders.append( self.createImgSlider("./mic/gui/filter-gui/slider.png", i)) self.sliders[i].valueChanged[int].connect( lambda val, index=i: self.setHandlers(val, index)) self.handlers.register_callback(self.updateHandlersStatus) # Updates handle value when signal is received and sends # a signal for filter updater def updateHandlersStatus(self, handleNumber): self.changesAvailable = True self.handleUpdated = handleNumber self.changed = 0 # Sends gui settings def setHandlers(self, newVal, handlerID): self.guiSettings.updatesAvailable = True self.guiSettings.handleSelected = handlerID self.guiSettings.handleValue = newVal self.queue.put(self.guiSettings) # Initializes resolution options and it's changes callback def resolutionOptions(self): resolutions = ["Ultra High", "High", "Normal", "Low", "Ultra Low"] self.comboBoxResol = self.setComboBox(2, 542, 187, "comboBoxResol", resolutions) l = lambda optionSelected, optionIndex=2: self.updateComboBoxStatus( optionSelected, optionIndex) self.comboBoxResol.currentIndexChanged[int].connect(l) # Initializes sampling rate options and it's changes callback def samplingRateOptions(self): rates = ["48000", "44100", "32000", "22050", "11025", "8000"] self.comboBoxRate = self.setComboBox(3, 542, 125, "comboBoxRate", rates) l = lambda optionSelected, optionIndex=3: self.updateComboBoxStatus( optionSelected, optionIndex) self.comboBoxRate.currentIndexChanged[int].connect(l) # Initializes mode options and it's changes callback def modeOptions(self): modes = ["FIR (slow)", "Butterworth (fast)", "Devil", "Goblin"] self.comboBoxMode = self.setComboBox(0, 542, 63, "comboBoxMode", modes) l = lambda optionSelected, optionIndex=1: self.updateComboBoxStatus( optionSelected, optionIndex) self.comboBoxMode.currentIndexChanged[int].connect(l) # If any combo box option is changed, this callback is called. # Sends update to updates queue. @QtCore.Slot(int) def updateComboBoxStatus(self, newVal, changeCode): self.changesAvailable = True self.changed = changeCode if (changeCode == 3): self.rateIndex = newVal self.guiSettings.rateSelected = newVal elif (changeCode == 2): self.resolIndex = newVal self.guiSettings.resolutionSelected = newVal elif (changeCode == 1): self.filterIndex = newVal self.guiSettings.filterSelected = newVal self.queue.put(self.guiSettings) # Sets background image def configureBackground(self): image = "mic/gui/filter-gui/UI.png" self.text_field = QPlainTextEdit(self) self.text_field.setDisabled(True) self.text_field.setMinimumSize(720, 301) self.text_field.setStyleSheet("background-image: url(" + image + "); background-attachment: fixed") # Initializes combo box def setComboBox(self, startingIndex=0, xPos=0, yPos=0, objName="default", items=[]): combo = QComboBox(self) for item in items: combo.addItem(item) combo.setObjectName(objName) combo.setGeometry(QRect(xPos, yPos, 125, 22)) combo.setCurrentIndex(startingIndex) combo.setStyleSheet( "background-color: rgb(47, 47, 47) ; color: rgb(255, 96, 96);") return combo # Initializes Windows and title bar icons def configIcons(self): self.app_icon.addFile('mic/gui/filter-gui/icon/icon16.png', QSize(16, 16)) self.app_icon.addFile('mic/gui/filter-gui/icon/icon24.png', QSize(24, 24)) self.app_icon.addFile('mic/gui/filter-gui/icon/icon32.png', QSize(32, 32)) self.app_icon.addFile('mic/gui/filter-gui/icon/icon48.png', QSize(48, 48)) self.app_icon.addFile('mic/gui/filter-gui/icon/icon256.png', QSize(256, 256)) self.app.setWindowIcon(self.app_icon) # Initializes general window's elements like # title Bar and window size def configWindow(self): self.configIcons() self.setWindowTitle('Bokus Multiband Filter') self.setWindowFlags(self.windowFlags() | QtCore.Qt.CustomizeWindowHint) self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowMaximizeButtonHint) self.setFixedSize(720, 301) # Creates an slider, with an image as a handle def createImgSlider(self, imgPath, index): xPosition = 36 + 47 * index slider = QSlider(self) slider.setObjectName(u"slider" + str(index)) slider.setGeometry(QRect(xPosition, -1, 51, 300)) slider.setCursor(QCursor(Qt.OpenHandCursor)) slider.setMouseTracking(False) slider.setFocusPolicy(Qt.StrongFocus) slider.setAcceptDrops(False) slider.setAutoFillBackground(False) slider.setStyleSheet(u"QSlider::handle:vertical {\n" " image: url(" + imgPath + ");\n" " width: 90px;\n" " height: 90px\n" "}\n" "\n" "QSlider::groove:vertical{\n" " background: rgba(0, 0, 0, 0);\n" "}") slider.setValue(50) slider.setSliderPosition(50) slider.setOrientation(Qt.Vertical) slider.setInvertedAppearance(False) return slider # [DEPRECATED] loads GUI from from.ui (PyQt) def load_ui(self): loader = QUiLoader() path = os.path.join(os.path.dirname(__file__), "./gui/filter-gui/form2.ui") ui_file = QFile(path) ui_file.open(QFile.ReadOnly) loader.load(ui_file, self) ui_file.close() # [DEPRECATED. Replaced with combo boxes] loads buttons for mode selecting. def filterModeButtons(self): self.filterTypeButtons = QButtonGroup(self) self.configFilterTypeButtons("firButton", True, 560, 49, 0) self.configFilterTypeButtons("iirButton", False, 560, 68, 1) self.configFilterTypeButtons("devilButton", False, 560, 86, 2) self.configFilterTypeButtons("goblinButton", False, 560, 104, 3) # [DEPRECATED. Used in filterModeButtons] def configFilterTypeButtons(self, name=u"default", checked=False, xPos=0, yPos=0, idButton=0): button = QRadioButton(self) button.setObjectName(name) button.setEnabled(True) button.setGeometry(QRect(xPos, yPos, 82, 17)) button.setCursor(QCursor(Qt.PointingHandCursor)) button.setChecked(checked) lam = lambda id=idButton: self.buttonChecked(id) self.connect(button, SIGNAL("clicked()"), lam) self.filterTypeButtons.addButton(button, idButton) # [DEPRECATED. Used in filterModeButtons] def buttonChecked(self, idButton): self.filterIndex = idButton self.guiSettings.filterSelected = idButton self.queue.put(self.guiSettings) # Properly closes GUI if flag is received def sys_exit(self, exitProgram): self.app.exec_() exitProgram.value = True self.queue.put(None) sys.exit() # Properly closes settings window def closeEvent(self, event): self.closeSettings() # Properly closes settings window def closeSettings(self): if hasattr(self, 'sets'): self.sets.close() # Initializes button for opening settings def showSettingsButton(self): image = "./mic/gui/filter-gui/settings-button.png" imageHover = "./mic/gui/filter-gui/settings-button-hover.png" button = QPushButton("", self) button.setGeometry(685, 10, 24, 27) button.setStyleSheet("border-radius : 50") button.setStyleSheet("QPushButton {border-image: url(" + image + "); } QPushButton:hover { border-image: url(" + imageHover + ")}") button.clicked.connect(self.openSettings) self.settingsButton = button # Shows settings def openSettings(self): self.sets = settingsWindow() self.sets.show()
class QNotesWindow(QDialog): def __init__(self, game: Game): super(QNotesWindow, self).__init__() self.game = game self.setWindowTitle("Notes") self.setWindowIcon(CONST.ICONS["Notes"]) self.setMinimumSize(400, 100) self.resize(600, 450) self.vbox = QVBoxLayout() self.setLayout(self.vbox) self.vbox.addWidget( QLabel("Saved notes are available as a page in your kneeboard.") ) self.textbox = QPlainTextEdit(self) try: self.textbox.setPlainText(self.game.notes) self.textbox.moveCursor(QTextCursor.End) except AttributeError: # old save may not have game.notes pass self.textbox.move(10, 10) self.textbox.resize(600, 450) self.textbox.setStyleSheet("background: #1D2731;") self.vbox.addWidget(self.textbox) self.button_row = QHBoxLayout() self.vbox.addLayout(self.button_row) self.clear_button = QPushButton(self) self.clear_button.setText("CLEAR") self.clear_button.setProperty("style", "btn-primary") self.clear_button.clicked.connect(self.clearNotes) self.button_row.addWidget(self.clear_button) self.save_button = QPushButton(self) self.save_button.setText("SAVE") self.save_button.setProperty("style", "btn-success") self.save_button.clicked.connect(self.saveNotes) self.button_row.addWidget(self.save_button) def clearNotes(self) -> None: self.textbox.setPlainText("") def saveNotes(self) -> None: self.game.notes = self.textbox.toPlainText() self.save_button.setText("SAVED") QTimer.singleShot(5000, lambda: self.save_button.setText("SAVE"))
def _initForm(self): layout = QFormLayout() self.runCommand = QLineEdit(self, maxLength=200) self.runCommand.setStyleSheet(Theme.templateEditor.inputStyle) self.runCommand.setFont(Theme.templateEditor.inputCodeFont) self.runCommand.setFixedHeight(Theme.templateEditor.inputHeight) if self.powermode: self.backendName = QLineEdit(self, maxLength=20) self.backendName.setStyleSheet(Theme.templateEditor.inputStyle) self.backendName.setFont(Theme.templateEditor.inputFont) self.backendName.setFixedHeight(Theme.templateEditor.inputHeight) self.editorMode = QComboBox() [self.editorMode.addItem(mode) for mode in self._availableModes()] self.editorMode.currentIndexChanged.connect( self.onEditorModeChanged) self.inputRegex = QLineEdit(self, maxLength=100) self.inputRegex.setToolTip("regex") self.inputRegex.setStyleSheet(Theme.templateEditor.inputStyle) self.inputRegex.setFont(Theme.templateEditor.inputCodeFont) self.inputRegex.setFixedHeight(Theme.templateEditor.inputHeight) self.inputReplace = QLineEdit(self, maxLength=100) self.inputReplace.setToolTip("substitution string") self.inputReplace.setStyleSheet(Theme.templateEditor.inputStyle) self.inputReplace.setFont(Theme.templateEditor.inputCodeFont) self.inputReplace.setFixedHeight(Theme.templateEditor.inputHeight) self.outputRegex = QLineEdit(self, maxLength=100) self.outputRegex.setToolTip("regex") self.outputRegex.setStyleSheet(Theme.templateEditor.inputStyle) self.outputRegex.setFont(Theme.templateEditor.inputCodeFont) self.outputRegex.setFixedHeight(Theme.templateEditor.inputHeight) self.outputReplace = QLineEdit(self, maxLength=100) self.outputReplace.setToolTip("substitution string") self.outputReplace.setStyleSheet(Theme.templateEditor.inputStyle) self.outputReplace.setFont(Theme.templateEditor.inputCodeFont) self.outputReplace.setFixedHeight(Theme.templateEditor.inputHeight) self.description = QPlainTextEdit(self, minimumHeight=80) self.description.setStyleSheet( Theme.templateEditor.descriptionStyle) self.description.setFont(Theme.templateEditor.descriptionFont) layout.addRow(self.tr("Run Command:"), self.runCommand) if self.powermode: layout.addRow(self.tr("Backend Name:"), self.backendName) layout.addRow(self.tr("Editor Mode:"), self.editorMode) inputMiddlewareLayout = QHBoxLayout() inputMiddlewareLayout.addWidget(self.inputRegex) inputMiddlewareLayout.addWidget(self.inputReplace) layout.addRow(self.tr("Input Middleware:"), inputMiddlewareLayout) outputMiddlewareLayout = QHBoxLayout() outputMiddlewareLayout.addWidget(self.outputRegex) outputMiddlewareLayout.addWidget(self.outputReplace) layout.addRow(self.tr("Output Middleware:"), outputMiddlewareLayout) layout.addRow(self.tr("Description:"), self.description) layout.setSpacing(10) layout.setContentsMargins(10, 10, 10, 10) self.layout().addLayout(layout)
def __init__(self, user): super(Widget, self).__init__() self.library = QWidget() self.get_books_api = 'books' self.get_users_api = 'users' self.reservation_api = '/reservation/' self.user = user self.h_spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.v_spacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self._user_id = None self._book_id = None self._role_id = 1 self.dialog_password = QDialog() self.dialog_profile = QDialog() self.dialog_permission = QDialog() self.dialog_set_permission = QDialog() self.dialog_book = QDialog() self.layout_password = QFormLayout() self.layout_profile = QFormLayout() self.layout_permission = QFormLayout() self.layout_book = QFormLayout() self.regex = QRegExp('^(\w|\.|\_|\-)+[@](\w|\_|\-|\.)+[.]\w{2,3}$') self.validator = QRegExpValidator(self.regex) self.btn_cancel_box = QDialogButtonBox.Cancel self.btn_ok_box = QDialogButtonBox.Ok self.btn_save_box = QDialogButtonBox.Save # Strona główna self.lbl_home = HomeTextBrowser() # Profil self.edit_name = QLineEdit() self.edit_subname = QLineEdit() self.edit_email = QLineEdit() self.btn_delete_profile = QPushButton('Usuń konto') self.profile_widget() # Biblioteka self.lbl_title = QLabel() self.edit_search = QLineEdit() self.tbl_result = QTableWidget() self.btn_next_page = QPushButton('Następna >') self.btn_back_page = QPushButton('< Poprzednia') self.combo_sort_by = QComboBox() self.combo_sort_direction = QComboBox() self.layout_btn = QHBoxLayout() self.layout_search = QHBoxLayout() self.layout_library = QVBoxLayout() self.library_widget() self.tbl_result.setAlternatingRowColors(True) self.tbl_result.setCornerButtonEnabled(False) self.tbl_result.verticalHeader().setSortIndicatorShown(True) self.tbl_result.setSelectionBehavior(QAbstractItemView.SelectRows) self.tbl_result.setEditTriggers(QAbstractItemView.NoEditTriggers) self.tbl_result.setWordWrap(True) self.tbl_result.horizontalHeader().setStretchLastSection(True) self.tbl_result.resizeColumnsToContents() self.tbl_result.resizeRowsToContents() self.tbl_result.verticalHeader().setDefaultAlignment(Qt.AlignCenter | Qt.TextWordWrap) self.tbl_result.cellDoubleClicked.connect(self.cell_was_clicked) font = QFont() font.setPointSize(14) font.setBold(True) self.lbl_title.setFont(font) self.lbl_title.setAlignment(Qt.AlignCenter) # Edycja książki self.edit_isbn = QLineEdit() self.edit_book_name = QLineEdit() self.edit_author = QLineEdit() self.edit_publisher = QLineEdit() self.edit_publish_date = QLineEdit() self.edit_category = QLineEdit() self.edit_isbn.setPlaceholderText('Wymagane') self.edit_book_name.setPlaceholderText('Wymagane') self.edit_author.setPlaceholderText('Wymagane') self.edit_publisher.setPlaceholderText('Wymagane') self.edit_publish_date.setPlaceholderText('Wymagane') self.edit_category.setPlaceholderText('Wymagane') self.edit_language_book = QLineEdit() self.edit_book_description = QPlainTextEdit() self.btn_delete_book = QPushButton('Usuń książkę') self.btn_borrow_book = QPushButton('Wypożycz książkę') self.book_id_widget() # Zmiana hasła self.edit_passwd1 = QLineEdit() self.edit_passwd2 = QLineEdit() self.edit_passwd3 = QLineEdit() self.change_password_widget() # Profil z uprawnieniami self.edit_pass2 = QLineEdit() self.edit_pass3 = QLineEdit() self.edit_new_name = QLineEdit() self.edit_new_surname = QLineEdit() self.edit_new_email = QLineEdit() self.combo_role_id = QComboBox(self) self.role_profile_widget()
class TrackEditor(Observation, QWidget, metaclass=FinalMeta): def __init__(self, subject, powermode=False, allowEditBackend=False, confirmUpdate=True): Observation.__init__(self, subject) QWidget.__init__(self) self._template = None self.deleted = False self.shouldSave = False self.powermode = powermode self.allowEditBackend = allowEditBackend self.confirmUpdate = confirmUpdate self.descriptionMaxLen = 1000 self._code = "" layout = QVBoxLayout() layout.setAlignment(Qt.AlignTop) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) if self.allowEditBackend: self._initForm() self._initCodeEditor() self.setFixedSize(630, 600) self.setAttribute(Qt.WA_StyledBackground) self.setStyleSheet(Theme.templateEditor.style) self.setContextMenuPolicy(Qt.NoContextMenu) self.setWindowModality(Qt.ApplicationModal) self.setWindowFlags(Qt.Tool | Qt.WindowTitleHint | Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint | Qt.WindowMaximizeButtonHint) self.setWindowFlag(Qt.WindowMinimizeButtonHint, False) self.codeView.closeShortcut.setEnabled(False) QShortcut(QKeySequence(self.tr("Ctrl+w")), self, self.close) def _initForm(self): layout = QFormLayout() self.runCommand = QLineEdit(self, maxLength=200) self.runCommand.setStyleSheet(Theme.templateEditor.inputStyle) self.runCommand.setFont(Theme.templateEditor.inputCodeFont) self.runCommand.setFixedHeight(Theme.templateEditor.inputHeight) if self.powermode: self.backendName = QLineEdit(self, maxLength=20) self.backendName.setStyleSheet(Theme.templateEditor.inputStyle) self.backendName.setFont(Theme.templateEditor.inputFont) self.backendName.setFixedHeight(Theme.templateEditor.inputHeight) self.editorMode = QComboBox() [self.editorMode.addItem(mode) for mode in self._availableModes()] self.editorMode.currentIndexChanged.connect( self.onEditorModeChanged) self.inputRegex = QLineEdit(self, maxLength=100) self.inputRegex.setToolTip("regex") self.inputRegex.setStyleSheet(Theme.templateEditor.inputStyle) self.inputRegex.setFont(Theme.templateEditor.inputCodeFont) self.inputRegex.setFixedHeight(Theme.templateEditor.inputHeight) self.inputReplace = QLineEdit(self, maxLength=100) self.inputReplace.setToolTip("substitution string") self.inputReplace.setStyleSheet(Theme.templateEditor.inputStyle) self.inputReplace.setFont(Theme.templateEditor.inputCodeFont) self.inputReplace.setFixedHeight(Theme.templateEditor.inputHeight) self.outputRegex = QLineEdit(self, maxLength=100) self.outputRegex.setToolTip("regex") self.outputRegex.setStyleSheet(Theme.templateEditor.inputStyle) self.outputRegex.setFont(Theme.templateEditor.inputCodeFont) self.outputRegex.setFixedHeight(Theme.templateEditor.inputHeight) self.outputReplace = QLineEdit(self, maxLength=100) self.outputReplace.setToolTip("substitution string") self.outputReplace.setStyleSheet(Theme.templateEditor.inputStyle) self.outputReplace.setFont(Theme.templateEditor.inputCodeFont) self.outputReplace.setFixedHeight(Theme.templateEditor.inputHeight) self.description = QPlainTextEdit(self, minimumHeight=80) self.description.setStyleSheet( Theme.templateEditor.descriptionStyle) self.description.setFont(Theme.templateEditor.descriptionFont) layout.addRow(self.tr("Run Command:"), self.runCommand) if self.powermode: layout.addRow(self.tr("Backend Name:"), self.backendName) layout.addRow(self.tr("Editor Mode:"), self.editorMode) inputMiddlewareLayout = QHBoxLayout() inputMiddlewareLayout.addWidget(self.inputRegex) inputMiddlewareLayout.addWidget(self.inputReplace) layout.addRow(self.tr("Input Middleware:"), inputMiddlewareLayout) outputMiddlewareLayout = QHBoxLayout() outputMiddlewareLayout.addWidget(self.outputRegex) outputMiddlewareLayout.addWidget(self.outputReplace) layout.addRow(self.tr("Output Middleware:"), outputMiddlewareLayout) layout.addRow(self.tr("Description:"), self.description) layout.setSpacing(10) layout.setContentsMargins(10, 10, 10, 10) self.layout().addLayout(layout) def _initCodeEditor(self): self.codeView = CodeView(self.subject, viewTip=False) self.layout().addWidget(QLabel("Setup Code:", margin=10)) self.layout().addWidget(self.codeView) self.codeView.setDelegate(self) def _availableModes(self): return acePropertyNames("mode-", ".js", False) def onEditorModeChanged(self, e): mode = self.editorMode.itemText(e) self.codeView.setMode(mode) if self._template is not None: self._template.editor_mode = mode def onSave(self): self.shouldSave = True if self.allowEditBackend: self._template.run_command = self.runCommand.text().strip() if self.powermode and self.allowEditBackend: self._template.backend_name = self.backendName.text().strip() self._template.editor_mode = self.editorMode.currentText() self._template.backend_middleware.input.regex = \ self.inputRegex.text() self._template.backend_middleware.input.substitution = \ self.inputReplace.text() self._template.backend_middleware.output.regex = \ self.outputRegex.text() self._template.backend_middleware.output.substitution = \ self.outputReplace.text() self._template.description = self.description.toPlainText( )[:self.descriptionMaxLen] self._template.setup_code = self._code def setTemplate(self, delegate): self._template = delegate self.codeView.setDelegate(self) self.deserialize() def setCode(self, code, notify): if self._template is None: return self._code = code if self.shouldSave: self._template.setup_code = code self.onTemplateUpdate() def onTemplateUpdate(self): pass def code(self): if self._template is None: return "" return self._template.setup_code def codeWindowTitle(self): return "Track Template Editor" def deserialize(self): if self._template is None: return if self.allowEditBackend: self.runCommand.setText(self._template.run_command.strip()) if self.powermode and self.allowEditBackend: self.backendName.setText(self._template.backend_name.strip()) self.editorMode.setCurrentText(self._template.editor_mode) self.inputRegex.setText( self._template.backend_middleware.input.regex) self.inputReplace.setText( self._template.backend_middleware.input.substitution) self.outputRegex.setText( self._template.backend_middleware.output.regex) self.outputReplace.setText( self._template.backend_middleware.output.substitution) self.description.document().setPlainText( self._template.description) else: self.codeView.setMode(self._template.editor_mode) self._code = self._template.setup_code self.setWindowTitle("Track Template Editor") def delete(self): self.deleted = True self.codeView.delete() self.unregister() self.setParent(None) self.deleteLater() def template(self): return self._template def showEvent(self, event): self.shouldSave = False self.codeView.show() super().showEvent(event) def closeEvent(self, event): if self._template is not None and not self.deleted: if self.confirmUpdate: question = "Do you want to save changes in " +\ f"{self._template.backend_name} template?" confirmation = ConfirmationDialog("Update Track Template", question) if confirmation.exec_() == ConfirmationDialog.Yes: self.onSave() else: self.onSave() self.codeView.close() super().closeEvent(event)
class GCodeSenderGUI(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) QLocale.setDefault(QLocale.English) self.__central_widget = None self.__menu_bar = None self.__status_bar = None self.__g_code_sender = GCodeSender() self.__init_central_widget() # self.__init_menu_bar_widget() layout = QVBoxLayout(self) layout.addWidget(self.__central_widget) # self.setCentralWidget(self.__central_widget) # self.setMenuBar(self.__menu_bar) # self.setWindowTitle("MyGCodeSender") def __init_central_widget(self): self.__central_widget = QWidget(self) central_layout = QGridLayout(self.__central_widget) self.__init_right_column_widget(self.__central_widget) central_layout.addWidget(self.__right_column_widget, 0, 2, 1, 1) self.__init_console_widget(self.__central_widget) central_layout.addWidget(self.__console_widget, 0, 0, 1, 2) self.__init_bottom_widget(self.__central_widget) central_layout.addWidget(self.__bottom_widget, 1, 0, 1, 3) self.__right_column_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) # self.__console_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) # self.__bottom_widget.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) def __init_console_widget(self, parent=None): self.__console_widget = QPlainTextEdit(parent) self.__console_widget.setReadOnly(True) self.__console_widget.setStyleSheet("QPlainTextEdit { background-color : dimgrey}") palette = self.__console_widget.palette() palette.setColor(QPalette.Text, QColor(255, 255, 255)) self.__console_widget.setPalette(palette) self.__g_code_sender.print_text_signal.connect(self.__console_widget.appendPlainText) def __init_bottom_widget(self, parent=None): self.__bottom_widget = QWidget(parent) send_button = QPushButton("Send", self.__bottom_widget) send_button.setObjectName("send_button") send_button.clicked.connect(self.__send_single_command) start_button = QPushButton("Start", self.__bottom_widget) start_button.setObjectName("start_button") start_button.clicked.connect(self.__g_code_sender.start) load_gcode_button = QPushButton("Load Gcode", self.__bottom_widget) load_gcode_button.setObjectName("load_gcode_button") load_gcode_button.clicked.connect(self.__load_gcode_file) self.__line_sender_edit = QLineEdit(self.__bottom_widget) self.__line_sender_edit.setObjectName("line_sender_edit") self.__line_sender_edit.setPlaceholderText("Send Manual Gcode") self.__line_sender_edit.returnPressed.connect(self.__send_single_command) self.__progress_bar = QProgressBar(self.__bottom_widget) self.__progress_bar.setProperty("value", 0) self.__progress_bar.setObjectName("progress_bar") self.__progress_bar.setRange(0, 100) self.__g_code_sender.percentage_progress_signal.connect(self.__progress_bar.setValue) # defining bottom layout bottom_layout = QGridLayout(self.__bottom_widget) bottom_layout.addWidget(self.__line_sender_edit, 0, 0, 1, 1) bottom_layout.addWidget(send_button, 0, 1, 1, 1) bottom_layout.addWidget(load_gcode_button, 0, 2, 1, 1) bottom_layout.addWidget(start_button, 0, 3, 1, 1) bottom_layout.addWidget(self.__progress_bar, 1, 0, 1, 4) def __init_right_column_widget(self, parent=None): self.__right_column_widget = QWidget(parent) port_label = QLabel("Port Number", self.__right_column_widget) port_label.setObjectName("port_label") self.__port_combo_box = MyQComboBox(self.__right_column_widget) self.__port_combo_box.setObjectName("port_combo_box") self.__port_combo_box.addItems(self.__g_code_sender.get_ports_list()) self.__port_combo_box.currentIndexChanged.connect(self.__g_code_sender.set_comport) self.__port_combo_box.combo_box_clicked.connect(self.__update_ports_list) baudrate_label = QLabel("Baudrate", self.__right_column_widget) baudrate_combo_box = QComboBox(self.__right_column_widget) baudrate_combo_box.setObjectName("baudrate_combo_box") baudrate_combo_box.addItems([str(i) for i in self.__g_code_sender.get_baudrates_list()]) baudrate_combo_box.currentIndexChanged.connect(self.__g_code_sender.set_baudrate) connect_button = QPushButton("Connect GLAMS", self.__right_column_widget) connect_button.setObjectName("connect_button") connect_button.clicked.connect(self.__g_code_sender.connect_serial) disconnect_button = QPushButton("Disconnect GLAMS", self.__right_column_widget) disconnect_button.setObjectName("disconnect_button") disconnect_button.clicked.connect(self.__g_code_sender.disconnect) motor_connect_button = QPushButton("Connect Motor", self.__right_column_widget) motor_connect_button.setObjectName("motor_connect_button") motor_connect_button.clicked.connect(self.__g_code_sender.motor_connect) home_motors_button = QPushButton("Home Motors", self.__right_column_widget) home_motors_button.setObjectName("home_motors_button") home_motors_button.clicked.connect(self.__g_code_sender.home_motors) stop_button = QPushButton("STOP", self.__right_column_widget) stop_button.setObjectName("stop_button") stop_button.clicked.connect(self.__g_code_sender.emergency_stop) stop_button.setStyleSheet("QPushButton {background-color: red; border-style: outset; border-width: 6px; " "border-radius: 10px; border-color: beige; font: bold 20px; padding: 10px;}") pause_button = QPushButton("Pause", self.__right_column_widget) pause_button.setObjectName("pause_button") pause_button.clicked.connect(self.__g_code_sender.pause) right_column_layout = QVBoxLayout(self.__right_column_widget) right_column_layout.addWidget(stop_button) right_column_layout.addWidget(port_label) right_column_layout.addWidget(self.__port_combo_box) right_column_layout.addWidget(baudrate_label) right_column_layout.addWidget(baudrate_combo_box) right_column_layout.addWidget(connect_button) right_column_layout.addWidget(disconnect_button) right_column_layout.addWidget(motor_connect_button) right_column_layout.addWidget(home_motors_button) right_column_layout.addWidget(pause_button) @Slot() def __send_single_command(self): command = self.__line_sender_edit.text() self.__g_code_sender.execute_gcode_command(command) @Slot() def __load_gcode_file(self): file_path = QFileDialog.getOpenFileName(caption='Select GCode File', dir='../', filter="GCode Files (*.g)") file_path = file_path[0] self.__g_code_sender.open_file(file_path) @Slot() def __update_ports_list(self): self.__g_code_sender.update_port_list() current_idx = self.__port_combo_box.currentIndex() self.__port_combo_box.blockSignals(True) self.__port_combo_box.clear() self.__port_combo_box.addItems(self.__g_code_sender.get_ports_list()) self.__port_combo_box.blockSignals(False) self.__port_combo_box.setCurrentIndex(current_idx) def get_settings_window(self, parent=None): gcodesender_settings = QGroupBox("GCodeSender Settings:", parent) buildplate_label = QLabel("Buildplate Motor:", gcodesender_settings) nodes = [str(item) for item in self.__g_code_sender.get_motor_nodes_id_list()] self.buildplate_combo_box = MyQComboBox(gcodesender_settings) self.buildplate_combo_box.addItems(nodes) self.buildplate_combo_box.setCurrentIndex(self.__g_code_sender.get_buildplate_node()) self.buildplate_combo_box.combo_box_clicked.connect(self.__update_nodes_list) self.buildplate_combo_box.currentIndexChanged.connect(self.__set_buildplate_node) wiper_label = QLabel("Wiper Motor:", gcodesender_settings) self.wiper_combo_box = MyQComboBox(gcodesender_settings) self.wiper_combo_box.addItems(nodes) self.wiper_combo_box.setCurrentIndex(self.__g_code_sender.get_wiper_node()) self.wiper_combo_box.combo_box_clicked.connect(self.__update_nodes_list) self.wiper_combo_box.currentIndexChanged.connect(self.__set_wiper_node) buildplate_recoat_offset_label = QLabel("Buildplate recoating offset (mm):", gcodesender_settings) buildplate_recoat_offset_spin = QDoubleSpinBox(gcodesender_settings) buildplate_recoat_offset_spin.setRange(0, 99999) buildplate_recoat_offset_spin.setDecimals(3) buildplate_recoat_offset_spin.setSingleStep(0.001) buildplate_recoat_offset_spin.setValue(self.__g_code_sender.get_building_plate_recoating_offset()) buildplate_recoat_offset_spin.valueChanged.connect(self.__g_code_sender.set_building_plate_recoat_offset) buildplate_recoat_feedrate_label = QLabel("Buildplate recoating feedrate (mm/min):", gcodesender_settings) buildplate_recoat_feedrate_spin = QDoubleSpinBox(gcodesender_settings) buildplate_recoat_feedrate_spin.setRange(0, 99999) buildplate_recoat_feedrate_spin.setDecimals(3) buildplate_recoat_feedrate_spin.setSingleStep(0.001) buildplate_recoat_feedrate_spin.setValue(self.__g_code_sender.get_building_plate_recoating_feedrate()) buildplate_recoat_feedrate_spin.valueChanged.connect(self.__g_code_sender.set_building_plate_recoat_feedrate) wiper_recoat_offset_label = QLabel("Wiper recoating offset: (mm)", gcodesender_settings) wiper_recoat_offset_spin = QDoubleSpinBox(gcodesender_settings) wiper_recoat_offset_spin.setRange(0, 99999) wiper_recoat_offset_spin.setDecimals(3) wiper_recoat_offset_spin.setSingleStep(0.001) wiper_recoat_offset_spin.setValue(self.__g_code_sender.get_wiper_recoating_offset()) wiper_recoat_offset_spin.valueChanged.connect(self.__g_code_sender.set_wiper_recoat_offset) wiper_recoat_feedrate_label = QLabel("Wiper recoating feedrate (mm/min):", gcodesender_settings) wiper_recoat_feedrate_spin = QDoubleSpinBox(gcodesender_settings) wiper_recoat_feedrate_spin.setRange(0, 99999) wiper_recoat_feedrate_spin.setDecimals(3) wiper_recoat_feedrate_spin.setSingleStep(0.001) wiper_recoat_feedrate_spin.setValue(self.__g_code_sender.get_wiper_recoating_feedrate()) wiper_recoat_feedrate_spin.valueChanged.connect(self.__g_code_sender.set_wiper_recoat_feedrate) motor_layout = QGridLayout(gcodesender_settings) motor_layout.addWidget(buildplate_label, 0, 0) motor_layout.addWidget(self.buildplate_combo_box, 0, 1) motor_layout.addWidget(buildplate_recoat_offset_label, 1, 0) motor_layout.addWidget(buildplate_recoat_offset_spin, 1, 1) motor_layout.addWidget(buildplate_recoat_feedrate_label, 2, 0) motor_layout.addWidget(buildplate_recoat_feedrate_spin, 2, 1) motor_layout.addWidget(wiper_label, 3, 0) motor_layout.addWidget(self.wiper_combo_box, 3, 1) motor_layout.addWidget(wiper_recoat_offset_label, 4, 0) motor_layout.addWidget(wiper_recoat_offset_spin, 4, 1) motor_layout.addWidget(wiper_recoat_feedrate_label, 5, 0) motor_layout.addWidget(wiper_recoat_feedrate_spin, 5, 1) return gcodesender_settings @Slot(int) def __set_buildplate_node(self, value): nodes = self.__g_code_sender.get_motor_nodes_count_list() ports = self.__g_code_sender.get_motor_ports_connected() node_idx = value for port_idx in range(ports): if node_idx < nodes[port_idx]: self.__g_code_sender.set_buildplate_port(port_idx) self.__g_code_sender.set_buildplate_node(node_idx) return else: node_idx = node_idx - nodes[port_idx] @Slot(int) def __set_wiper_node(self, value): nodes = self.__g_code_sender.get_motor_nodes_count_list() ports = self.__g_code_sender.get_motor_ports_connected() node_idx = value for port_idx in range(ports): if node_idx < nodes[port_idx]: self.__g_code_sender.set_wiper_port(port_idx) self.__g_code_sender.set_wiper_node(node_idx) return else: node_idx = node_idx - nodes[port_idx] return @Slot() def __update_nodes_list(self): nodes = [str(item) for item in self.__g_code_sender.get_motor_nodes_id_list()] buildplate_current_idx = self.buildplate_combo_box.currentIndex() self.buildplate_combo_box.blockSignals(True) self.buildplate_combo_box.clear() self.buildplate_combo_box.addItems(nodes) self.buildplate_combo_box.blockSignals(False) self.buildplate_combo_box.setCurrentIndex(buildplate_current_idx) wiper_current_idx = self.wiper_combo_box.currentIndex() self.wiper_combo_box.blockSignals(True) self.wiper_combo_box.clear() self.wiper_combo_box.addItems(nodes) self.wiper_combo_box.blockSignals(False) self.wiper_combo_box.setCurrentIndex(wiper_current_idx)
class RunTab(QtWidgets.QWidget): run_checks = QtCore.Signal() def __init__(self, prj: QAXProject): super(RunTab, self).__init__() self.prj = prj self.check_executor = None self.vbox = QtWidgets.QVBoxLayout() self.setLayout(self.vbox) self._add_check_outputs() self._add_process() # final setup self.set_run_stop_buttons_enabled(False) def _add_check_outputs(self): co_groupbox = QGroupBox("Check outputs") co_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) co_layout = QVBoxLayout() co_layout.setSpacing(16) co_groupbox.setLayout(co_layout) self.qajson_spatial_checkbox = QCheckBox( "Include summary spatial output in QAJSON. " "Supports QAX visualisation.") self.qajson_spatial_checkbox.setCheckState( QtCore.Qt.CheckState.Checked) co_layout.addWidget(self.qajson_spatial_checkbox) export_layout = QVBoxLayout() export_layout.setSpacing(4) self.export_spatial_checkbox = QCheckBox( "Export detailed spatial outputs to file. " "Supports visualisation in other geospatial applications.") self.export_spatial_checkbox.stateChanged.connect( self._on_export_spatial_changed) export_layout.addWidget(self.export_spatial_checkbox) output_folder_layout = QHBoxLayout() output_folder_layout.setSpacing(4) output_folder_layout.addSpacerItem(QtWidgets.QSpacerItem(37, 20)) self.output_folder_label = QLabel( "Detailed spatial output folder location:") output_folder_layout.addWidget(self.output_folder_label) self.output_folder_input = QLineEdit() self.output_folder_input.setText( GuiSettings.settings().value("spatial_outputs")) self.output_folder_input.setMinimumWidth(300) self.output_folder_input.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) output_folder_layout.addWidget(self.output_folder_input) self.open_output_folder_button = QPushButton() output_folder_layout.addWidget(self.open_output_folder_button) self.open_output_folder_button.setIcon(qta.icon('fa.folder-open')) self.open_output_folder_button.setToolTip( f"Select file containing data") self.open_output_folder_button.clicked.connect( self._click_open_spatial_export_folder) export_layout.addLayout(output_folder_layout) co_layout.addLayout(export_layout) self._on_export_spatial_changed() self.vbox.addWidget(co_groupbox) def _click_open_spatial_export_folder(self): output_folder = QFileDialog.getExistingDirectory( self, f"Select folder for spatial outputs", GuiSettings.settings().value("spatial_outputs"), QFileDialog.ShowDirsOnly) if os.path.exists(output_folder): GuiSettings.settings().setValue("spatial_outputs", output_folder) self.output_folder_input.setText(output_folder) def _on_export_spatial_changed(self): is_export = self.export_spatial_checkbox.isChecked() self.output_folder_label.setEnabled(is_export) self.output_folder_input.setEnabled(is_export) self.open_output_folder_button.setEnabled(is_export) def _add_process(self): process_groupbox = QGroupBox("Process") process_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) process_layout = QVBoxLayout() process_layout.setSpacing(0) process_groupbox.setLayout(process_layout) pbar_frame = QFrame() pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) pbar_hbox = QHBoxLayout() pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16)) pbar_hbox.setSpacing(16) # Run and stop buttons hbox = QHBoxLayout() hbox.setSpacing(8) self.run_button = QPushButton() # is only enabled when validation passes self.run_button.setEnabled(False) self.run_button.setText("Run") self.run_button.setToolTip("Start check execution") self.run_button.setFixedWidth(100) run_icon = qta.icon('fa.play', color='green') self.run_button.setIcon(run_icon) self.run_button.clicked.connect(self._click_run) hbox.addWidget(self.run_button) self.stop_button = QPushButton() self.stop_button.setEnabled(False) self.stop_button.setText("Stop") self.stop_button.setToolTip("Stop check execution") self.stop_button.setFixedWidth(100) stop_icon = qta.icon('fa.stop', color='red') self.stop_button.setIcon(stop_icon) self.stop_button.clicked.connect(self._click_stop) hbox.addWidget(self.stop_button) self.progress_bar = QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setAlignment(QtCore.Qt.AlignCenter) self.progress_bar.setValue(0) self.progress_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) pbar_hbox.addLayout(hbox) pbar_hbox.addWidget(self.progress_bar) pbar_frame.setLayout(pbar_hbox) process_layout.addWidget(pbar_frame) vbox = QVBoxLayout() vbox.setSpacing(8) vbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16)) process_layout.addLayout(vbox) hbox = QHBoxLayout() vbox.addLayout(hbox) check_name_label = QLabel("Check:") check_name_label.setFixedWidth(80) hbox.addWidget(check_name_label) self.check_name_text_label = QLabel("n/a") hbox.addWidget(self.check_name_text_label) hbox = QHBoxLayout() vbox.addLayout(hbox) status_name_label = QLabel("Status:") status_name_label.setFixedWidth(80) hbox.addWidget(status_name_label) self.status_name_text_label = QLabel("Not started") hbox.addWidget(self.status_name_text_label) self.warning_frame = QFrame() self.warning_frame.setVisible(False) self.warning_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() warning_icon_widget = qta.IconWidget('fa.warning', color='red') warning_icon_widget.setIconSize(QtCore.QSize(48, 48)) warning_icon_widget.update() hbox.addWidget(warning_icon_widget) warning_label = QLabel( "Grid Transformer did not complete successfully. Please refer to " "log output.") warning_label.setStyleSheet("QLabel { color: red; }") warning_label.setWordWrap(True) warning_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(warning_label) self.warning_frame.setLayout(hbox) process_layout.addWidget(self.warning_frame) self.success_frame = QFrame() self.success_frame.setVisible(False) self.success_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() success_icon_widget = qta.IconWidget('fa.check', color='green') success_icon_widget.setIconSize(QtCore.QSize(48, 48)) success_icon_widget.update() hbox.addWidget(success_icon_widget) success_label = QLabel("All checks completed successfully.") success_label.setStyleSheet("QLabel { color: green; }") success_label.setWordWrap(True) success_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(success_label) self.success_frame.setLayout(hbox) process_layout.addWidget(self.success_frame) log_layout = QVBoxLayout() log_layout.setSpacing(4) log_label = QLabel("Log messages") log_label.setStyleSheet("QLabel { color: grey; }") log_layout.addWidget(log_label) self.log_messages = QPlainTextEdit() log_font = QFont("monospace") log_font.setStyleHint(QFont.TypeWriter) self.log_messages.setFont(log_font) self.log_messages.setReadOnly(True) self.log_messages.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) log_layout.addWidget(self.log_messages) process_layout.addLayout(log_layout) self.vbox.addWidget(process_groupbox) def set_run_stop_buttons_enabled(self, is_running: bool) -> NoReturn: if is_running: self.run_button.setEnabled(False) self.stop_button.setEnabled(True) else: self.run_button.setEnabled(True) self.stop_button.setEnabled(False) def _log_message(self, message): self.log_messages.appendPlainText(message) def run_executor(self, check_executor: QtCheckExecutorThread): # we pass the check_executor into the run tab as this is where the UI # components are that will display the execution status. self.set_run_stop_buttons_enabled(True) self._log_message("Check execution started") self.start_time = time.perf_counter() self.check_executor = check_executor self.check_executor.options = self.get_options() self.check_executor.check_tool_started.connect( self._on_check_tool_started) self.check_executor.progress.connect(self._on_progress) self.check_executor.qajson_updated.connect(self._on_qajson_update) self.check_executor.checks_complete.connect(self._on_checks_complete) self.check_executor.status_changed.connect(self._on_status_change) self.check_executor.start() def get_options(self) -> Dict: ''' Gets a list of options based on user entered data. eg; the spatial output specifications. ''' return { CheckOption.spatial_output_qajson: self.qajson_spatial_checkbox.isChecked(), CheckOption.spatial_output_export: self.export_spatial_checkbox.isChecked(), CheckOption.spatial_output_export_location: self.output_folder_input.text() } def _click_run(self): self.run_checks.emit() def _click_stop(self): if self.check_executor is None: logger.warn("Check executor does not exist, cannot stop") return self._log_message("Stopping check execution") self.check_executor.stop() @QtCore.Slot(float) def _on_progress(self, progress): self.progress_bar.setValue(int(progress * 100)) @QtCore.Slot() def _on_qajson_update(self): self.prj.qa_json = self.check_executor.qa_json @QtCore.Slot(object) def _on_check_tool_started(self, tpl): check_tool_name, check_number, total_check_count = tpl self.check_name_text_label.setText("{} ({}/{})".format( check_tool_name, check_number, total_check_count)) @QtCore.Slot() def _on_checks_complete(self): run_time = time.perf_counter() - self.start_time self._log_message( f"Execution time for all checks = {run_time:.2f} sec") self._log_message("\n\n") self.set_run_stop_buttons_enabled(False) self.prj.qa_json = self.check_executor.qa_json @QtCore.Slot(str) def _on_status_change(self, status): self.status_name_text_label.setText(status)
class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.textEdit = QPlainTextEdit() self.curFile = "" self.centralWidget = qtw.QWidget() self.mainWindow = self.createMainWindow() self.centralWidget.setLayout(self.mainWindow) self.setCentralWidget(self.centralWidget) #self.setFixedSize(1000, 550) self.createActions() self.createMenus() #self.createToolBars() self.createStatusBar() self.readSettings() self.textEdit.document().contentsChanged.connect(self.documentWasModified) #self.setCurrentFile("") self.setUnifiedTitleAndToolBarOnMac(True) #self.menuBar = qtw.QLayout.menuBar() #self.statusBar = qtw.QMainWindow.statusBar() self.Qsettings = QSettings() #self.connectlist() def createMainWindow(self): self.graphics = GraphicsWindow() self.spreadsheet = self.graphics.scene_class.spreadsheet self.control = self.spreadsheet.control self.controlobj = self.control.controlBox self.control.nextButton.clicked.connect(self.spreadsheet.update_table) self.control.nextButton.clicked.connect(self.graphics.update_view) self.control.prevButton.clicked.connect(self.spreadsheet.prev_table) self.control.prevButton.clicked.connect(self.graphics.prev_view) self.righttop = QVBoxLayout() self.righttop.addLayout(self.controlobj) self.righttop.addWidget(self.spreadsheet.table) self.mainWin = QHBoxLayout() self.mainWin.addWidget(self.graphics) self.mainWin.addLayout(self.righttop) return self.mainWin def closeEvent(self, event): if self.maybeSave: self.writeSettings event.accept() else: event.ignore() def newFile(self): if self.maybeSave: self.textEdit.clear() self.setCurrentFile("") def open(self): if self.maybeSave: fileName = QFileDialog.getOpenFileName(self) if not fileName.isEmpty(): self.loadFile(fileName) def save(self): if self.curFile == "": return self.saveAs else: return self.saveFile(self.curFile) def saveAs(self): fileName = QFileDialog.getSaveFileName(self) if fileName.isEmpty(): return False return self.saveFile(fileName) def about(self): QMessageBox.about(self, "About Application\n", "The <b>Application</b> example demonstrates how to\n" "write modern GUI applications using Qt, With a menu bar\n" "toolbars, and a status bar.") def documentWasModified(self): self.setWindowModified(self.textEdit.document().isModified()) def createActions(self): self.Act = QAction(QIcon(":/images/new.png"), "&New", self) self.Act.setShortcuts(QKeySequence.New) self.Act.setStatusTip("Create a new file") self.Act.triggered.connect(self.newFile) self.openAct = QAction(QIcon(":/images/new.png"), "&Open", self) self.openAct.setShortcuts(QKeySequence.Open) self.openAct.setStatusTip("Open an exsting file") self.openAct.triggered.connect(self.open) self.saveAct = QAction("&Save", self) self.saveAct.setShortcuts(QKeySequence.Save) self.saveAct.setStatusTip("Save a file") self.saveAct.triggered.connect(self.save) self.saveasAct = QAction("&Save as", self) self.saveasAct.setShortcuts(QKeySequence.SaveAs) self.saveasAct.setStatusTip("Save as a file") self.saveasAct.triggered.connect(self.saveAs) self.aboutQtAct = QAction("About &Qt", self) self.aboutQtAct.setStatusTip("Show the Qt library's About box") self.aboutQtAct.triggered.connect(qApp.aboutQt) self.exitAct = QAction("&Exit", self) self.exitAct.setStatusTip("Exit") self.exitAct.triggered.connect(self.exit) #self.cutAct.setEnabled(False) #self.copyAct.setEnabled(False) #self.textEdit.copyAvailable[bool].connect(self.cutAct.setEnabled) #self.textEdit.copyAvailable[bool].connect(self.copyAct.setEnabled) self.findAct = QAction("&Find", self) self.findAct.triggered.connect(self.find) self.gotocellAct = QAction("&GoToCell", self) self.gotocellAct.triggered.connect(self.gotocell) self.sortAct = QAction("&Sort", self) self.sortAct.triggered.connect(self.sort) self.undoAct = QAction("&Undo", self) self.redoAct = QAction("&Redo", self) self.cutAct = QAction("&Cut", self) self.copyAct = QAction("&Copy", self) self.pasteAct = QAction("&Paste", self) self.aboutAct = QAction("&About", self) self.boldAct = QAction("&Bold", self) self.italicAct = QAction("&Italic", self) self.leftAlignAct = QAction("&LeftAlign", self) self.rightAlignAct = QAction("&Alignment", self) self.justifyAct = QAction("&Justify", self) self.centerAct = QAction("&Center", self) self.setLineSpacingAct = QAction("&setLine", self) self.setParagrahSpacingAct = QAction("&setPAragrah", self) def createStatusBar(self): self.statusBar().showMessage("Ready") def createMenus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.Act) self.fileMenu.addAction(self.openAct) self.fileMenu.addAction(self.saveAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAct) self.editMenu = self.menuBar().addMenu("&Edit") self.editMenu.addAction(self.undoAct) self.editMenu.addAction(self.redoAct) self.editMenu.addSeparator() self.editMenu.addAction(self.cutAct) self.editMenu.addAction(self.copyAct) self.editMenu.addAction(self.pasteAct) self.editMenu.addSeparator() self.dataMenu = self.menuBar().addMenu("&Data") self.dataMenu.addAction(self.findAct) self.dataMenu.addAction(self.gotocellAct) self.dataMenu.addAction(self.sortAct) self.helpMenu = self.menuBar().addMenu("&Help") self.helpMenu.addAction(self.aboutAct) self.helpMenu.addAction(self.aboutQtAct) self.formatMenu = self.editMenu.addMenu("&Fornat") self.formatMenu.addAction(self.boldAct) self.formatMenu.addAction(self.italicAct) self.formatMenu.addSeparator().setText("Alignment") self.formatMenu.addAction(self.leftAlignAct) self.formatMenu.addAction(self.rightAlignAct) self.formatMenu.addAction(self.justifyAct) self.formatMenu.addAction(self.centerAct) self.formatMenu.addSeparator() self.formatMenu.addAction(self.setLineSpacingAct) self.formatMenu.addAction(self.setParagrahSpacingAct) def readSettings(self): self.settings = QSettings("Trolltrch", "Application Example") self.pos = self.settings.value("pos", QPoint(200, 200))#.toPoint() self.size = self.settings.value("size", QSize(400, 400))#.toSize() self.resize(self.size) self.move(self.pos) def writeSettings(self): self.settings = QSettings("Trolltech", "Application Example") self.settings.setValue("pos", self.pos) self.setting.setValue("size", self.size) def maybeSave(self): if self.textEdit.document().isModified(): ret = QMessageBox.warning(self, "Application", "The document has been modified.\n" "Do you want to save your changes?", QMessageBox.Save | QMessageBox.Discard | QMessageBox.cancel) if ret == QMessageBox.Save: return self.save elif ret == QMessageBox.Cancel: return False return True def loadFile(self, fileName): file = QFile(fileName) if not file.open(QFile.ReadOnly | QFile.Text): QMessageBox.warning(self, "Application", "Cannot read file" "{}:\n{}".format(fileName, file.errorString())) return False in_ = QTextStream(file) QApplication.setOverrideCursor(Qt.WaitCursor) self.textEdit.setPlainText(in_.readAll()) QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage("File loaded", 2000) def saveFile(self, fileName): file = QFile(fileName) if not file.open(QFile.WriteOnly | QFile.Text): QMessageBox.warning(self, "Application", "Cannot write file %1:\n%2.".arg(fileName) .arg(file.errorString())) return False self.out = QTextStream(file) QApplication.setOverrideCursor(Qt.WaitCursor) self.out = self.textEdit.toPlainText() QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage("File saved", 2000) return True def setCurrentFile(self, fileName): self.curFile = fileName self.textEdit.document().setModified(False) self.setWindowModified(False) if self.curFile.isEmpty(): shownName = "untitled.txt" else: shownName = strippedName(curFile) setWindowTitle(tr("%1[*] - %2").arg(shownName).arg("Application")) def strippedName(self, fullFileName): return QFileInfo(fullFileName).fileName() def exit(self): pass ''' def connectlist(self): self.copyAct.triggered.connect(self.spreadsheet.copy()) self.pasteAct.triggered.connect(self.spreadsheet.paste()) # self. ''' def find(self): print("findをクリックしました") self.fw = FindDialog() self.fw.show() self.fw.activateWindow() def gotocell(self): self.gw = GoToCell() self.gw.show() self.gw.activateWindow() def sort(self): self.sw = Sort() self.sw.show() self.sw.activateWindow()
class Widget(QWidget): cinema_url_label_text = "粘贴独播库的连续剧/综艺/动漫 URL: " movie_url_label_text = "粘贴独播库的电影 URL: " cinema_dest_label_text = "输入连续剧/综艺/动漫名 (用来命名下载的目录): " movie_dest_label_text = "输入电影名 (用来命名下载的文件): " def __init__(self): QWidget.__init__(self) self.q = None self.pool = None self.top = QHBoxLayout() self.top.setMargin(10) self.radioButtonMov = QRadioButton("电影") self.radioButtonCinema = QRadioButton("连续剧/综艺/动漫") self.top.addWidget(self.radioButtonMov) self.top.addWidget(self.radioButtonCinema) self.middle = QVBoxLayout() self.middle.setMargin(10) self.url_label = QLabel() self.url = QLineEdit() self.url_label.setBuddy(self.url) self.middle.addWidget(self.url_label) self.middle.addWidget(self.url) self.browse_folder_label = QLabel("下载到:") self.browseFolder = QPushButton("选择目录") self.browse_folder_label.setBuddy(self.browseFolder) self.middle.addWidget(self.browse_folder_label) self.middle.addWidget(self.browseFolder) self.browse_folder_value = "" self.dest_file_label = QLabel() # "输入电影/电视剧名 (用来命名下载的文件/目录): " title set by choose_movie_widgets() later self.folder_or_filename = QLineEdit() self.dest_file_label.setBuddy(self.folder_or_filename) self.middle.addWidget(self.dest_file_label) self.middle.addWidget(self.folder_or_filename) self.bk_cinemae_spin_from = 1 self.bk_cinemae_spin_to = 1 self.fromEpSpinBox = QSpinBox() self.fromEpSpinBox.setMinimum(1) self.fromEpSpinBox.setMaximum(2147483647) self.fromEpLabel = QLabel("&从第几集开始下载:") self.fromEpLabel.setBuddy(self.fromEpSpinBox) self.toEpSpinBox = QSpinBox() self.toEpSpinBox.setMinimum(1) self.toEpSpinBox.setMaximum(2147483647) self.toEpLabel = QLabel("&到第几集停止下载:") self.toEpLabel.setBuddy(self.toEpSpinBox) self.cinema_ly = QHBoxLayout() #self.cinema_ly.setMargin(10) self.cinema_ly.addWidget(self.fromEpLabel) self.cinema_ly.addWidget(self.fromEpSpinBox) self.cinema_ly.addWidget(self.toEpLabel) self.cinema_ly.addWidget(self.toEpSpinBox) self.middle.addLayout(self.cinema_ly) self.proxy_label = QLabel("(如有)代理:") self.proxy = QLineEdit() self.proxy_label.setBuddy(self.proxy) self.middle.addWidget(self.proxy_label) self.middle.addWidget(self.proxy) self.add = QPushButton("开始下载") self.add.setEnabled(False) self.middle.addWidget(self.add) self.stop_me = QPushButton("停止下载") self.stop_me.setEnabled(False) self.middle.addWidget(self.stop_me) self.log_area = QPlainTextEdit() self.log_area.setReadOnly(True) self.log_area.setMaximumBlockCount(1000) self.middle.addWidget(self.log_area) #self.table_view.setSizePolicy(size) #self.layout.addWidget(self.table) self.layout = QVBoxLayout() self.layout.addLayout(self.top) self.layout.addLayout(self.middle) self.setLayout(self.layout) self.radioButtonMov.toggled.connect(self.choose_movie_widgets) self.radioButtonCinema.toggled.connect(self.choose_cinema_widgets) self.url.textChanged[str].connect(self.check_disable_download) self.browseFolder.clicked.connect(self.add_folder) self.folder_or_filename.textChanged[str].connect( self.check_disable_download) self.add.clicked.connect(self.start_download) self.stop_me.clicked.connect(self.stop_download) self.radioButtonMov.setChecked( True) #set default only after .connect above # TESTING PURPOSE ''' self.radioButtonMov.setChecked(False) self.url.setText('https://www.duboku.net/voddetail-969.html') self.browse_folder_value = 'C:/Users/Administrator/Documents/duboku' self.folder_or_filename.setText('初恋') ''' #set current process (not queue that one) log handler: logger = logging.getLogger(__name__) handler2 = LoggerWriter() logger.addHandler(handler2) logger.setLevel(logging.INFO) #DEBUG handler2.emitter.sigLog.connect(self.log_area.appendPlainText) sys.stdout = handler2 #LoggerWriter() #sys.stderr = handler2 #Seems no difference #handler2.emitter.sigLog.emit('hihi') @Slot() def choose_movie_widgets(self): if self.radioButtonMov.isChecked(): self.url_label.setText(self.movie_url_label_text) self.dest_file_label.setText(self.movie_dest_label_text) self.fromEpLabel.setDisabled(True) self.toEpLabel.setDisabled(True) self.fromEpSpinBox.setDisabled(True) self.toEpSpinBox.setDisabled(True) self.bk_cinemae_spin_from = self.fromEpSpinBox.value() self.bk_cinemae_spin_to = self.toEpSpinBox.value() self.fromEpSpinBox.setValue(1) self.toEpSpinBox.setValue(1) @Slot() def choose_cinema_widgets(self): if self.radioButtonCinema.isChecked(): self.url_label.setText(self.cinema_url_label_text) self.dest_file_label.setText(self.cinema_dest_label_text) self.fromEpLabel.setEnabled(True) self.toEpLabel.setEnabled(True) self.fromEpSpinBox.setEnabled(True) self.toEpSpinBox.setEnabled(True) self.fromEpSpinBox.setValue(self.bk_cinemae_spin_from) self.toEpSpinBox.setValue(self.bk_cinemae_spin_to) @Slot() def add_folder(self, s): #fname = QFileDialog.getOpenFileName(self, 'Open file', "c:\'", "Image files (*.jpg *.gif)") #fname = QFileDialog.getOpenFileName(self, 'Open file', '', QFileDialog.ShowDirsOnly) fname = QFileDialog.getExistingDirectory(self, '选择下载至什么目录', '', QFileDialog.ShowDirsOnly) #print('repr: ' + repr(fname)) if fname and fname.strip(): fname = fname.strip() self.browse_folder_value = fname #if getOpenFileName, will return ('/home/xiaobai/Pictures/disco.jpg', 'Image files (*.jpg *.gif)') #, while if getExistingDirectory, will return single path string only self.browseFolder.setText(fname) self.check_disable_download(fname) #else: # print('User cancel') @Slot() def check_disable_download(self, s): if self.url.text().strip( ) and self.browse_folder_value and self.folder_or_filename.text(): self.add.setEnabled(True) else: self.add.setEnabled(False) def task_done(self, retVal): self.add.setEnabled(True) self.stop_me.setEnabled(False) @Slot() def stop_download(self): if self.q: self.q.close() if self.pool: self.pool.terminate() self.add.setEnabled(True) self.stop_me.setEnabled(False) print('下载停止。') @Slot() def start_download(self): if self.fromEpSpinBox.value() > self.toEpSpinBox.value(): self.log_area.setPlainText('[!] 从第几集必须小于或等于到第几集。') return #No need worry click twice too fast, it seems already handle by PySide2 self.add.setEnabled(False) self.stop_me.setEnabled(True) self.log_area.clear() dest_full_path = os.path.join(self.browse_folder_value, self.folder_or_filename.text()) ''' print('dest_full_path: ' + repr(dest_full_path)) print('self.url.text(): ' + repr(self.url.text())) print('self.fromEpSpinBox.value(): ' + repr(self.fromEpSpinBox.value())) print('self.toEpSpinBox.value(): ' + repr(self.toEpSpinBox.value())) ''' import duboku_console #Windows can't set like that bcoz not update for args.url, must put explicitly #duboku_console.redirect_stdout_to_custom_stdout(arg_url, ...etc, LoggerWriter()) #failed other process handler = LogHandlerOtherProcess() handler.emitter.sigLog.connect(self.log_area.appendPlainText) ''' #ref current process: logger = logging.getLogger(__name__) handler2 = LoggerWriter() logger.addHandler(handler2) logger.setLevel(logging.DEBUG) handler2.emitter.sigLog.connect(self.log_area.appendPlainText) sys.stdout = handler2 #LoggerWriter() #handler2.emitter.sigLog.emit('hihi') ''' #handler = LoggerWriter() #handler.emitter.sigLog.connect(self.log_area.appendPlainText) self.q = multiprocessing.Queue() self.ql = QueueListener(self.q, handler) self.ql.start() self.pool = multiprocessing.Pool(1, worker_init, [self.q]) if self.radioButtonMov.isChecked(): self.pool.apply_async(duboku_console.main, args=(None, dest_full_path, self.fromEpSpinBox.value(), self.toEpSpinBox.value(), self.url.text().strip(), LoggerWriterOtherProcess(), False, self.proxy.text()), callback=self.task_done) else: self.pool.apply_async(duboku_console.main, args=(dest_full_path, None, self.fromEpSpinBox.value(), self.toEpSpinBox.value(), self.url.text().strip(), LoggerWriterOtherProcess(), False, self.proxy.text()), callback=self.task_done)
class MainWindow(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.highlighter = Highlighter() self.setupFileMenu() self.setupEditor() self.setCentralWidget(self.editor) self.setWindowTitle(self.tr("Syntax Highlighter")) def newFile(self): self.editor.clear() def openFile(self, path = ""): fileName = path if not fileName: fileName, _ = QFileDialog.getOpenFileName(self, self.tr("Open File"), "", "qmake Files (*.pro *.prf *.pri)") if fileName: inFile = QFile(fileName) if inFile.open(QFile.ReadOnly | QFile.Text): stream = QTextStream(inFile) self.editor.setPlainText(stream.readAll()) def setupEditor(self): variableFormat = QTextCharFormat() variableFormat.setFontWeight(QFont.Bold) variableFormat.setForeground(Qt.blue) self.highlighter.addMapping("\\b[A-Z_]+\\b", variableFormat) singleLineCommentFormat = QTextCharFormat() singleLineCommentFormat.setBackground(QColor("#77ff77")) self.highlighter.addMapping("#[^\n]*", singleLineCommentFormat) quotationFormat = QTextCharFormat() quotationFormat.setBackground(Qt.cyan) quotationFormat.setForeground(Qt.blue) self.highlighter.addMapping("\".*\"", quotationFormat) functionFormat = QTextCharFormat() functionFormat.setFontItalic(True) functionFormat.setForeground(Qt.blue) self.highlighter.addMapping("\\b[a-z0-9_]+\\(.*\\)", functionFormat) font = QFont() font.setFamily("Courier") font.setFixedPitch(True) font.setPointSize(10) self.editor = QPlainTextEdit() self.editor.setFont(font) self.highlighter.setDocument(self.editor.document()) def setupFileMenu(self): fileMenu = self.menuBar().addMenu(self.tr("&File")) newFileAct = fileMenu.addAction(self.tr("&New...")) newFileAct.setShortcut(QKeySequence(QKeySequence.New)) newFileAct.triggered.connect(self.newFile) openFileAct = fileMenu.addAction(self.tr("&Open...")) openFileAct.setShortcut(QKeySequence(QKeySequence.Open)) openFileAct.triggered.connect(self.openFile) quitAct = fileMenu.addAction(self.tr("E&xit")) quitAct.setShortcut(QKeySequence(QKeySequence.Quit)) quitAct.triggered.connect(self.close) helpMenu = self.menuBar().addMenu("&Help") helpMenu.addAction("About &Qt", qApp.aboutQt)
def _init_widgets(self): try: from tracer import QEMURunner except: QMessageBox.about(self, 'Error', f"Unable to import QEMURunner, install angr tracer") self.close() self.setWindowTitle('New trace state') container = QVBoxLayout() layout = QGridLayout() row = 0 args_label = QLabel(self) args_label.setText("Command-line arguments:") layout.addWidget(args_label, row, 0) row += 1 args = QLineEdit(self) bin_name = str(self.instance.project).split(" ")[1][:-1] args.setText(bin_name) layout.addWidget(args, row, 0) row += 1 input_label = QLabel(self) input_label.setText("Input:") layout.addWidget(input_label, row, 0) row += 1 input_box = QPlainTextEdit() input_box.setWordWrapMode(QTextOption.WordWrap) layout.addWidget(input_box, row, 0) row += 1 addr_label = QLabel(self) addr_label.setText("Stop address:") layout.addWidget(addr_label, row, 0) row += 1 addr_box = QLineEdit(self) layout.addWidget(addr_box, row, 0) row += 1 def parse_address(): txt = addr_box.text() try: return self.instance.project.kb.labels.lookup(txt) except KeyError: pass try: return int(txt, 16) except ValueError: return None ok_button = QPushButton(self) ok_button.setText('OK') def do_ok(): argv = shlex.split(args.text()) inp = bytes(input_box.toPlainText().encode('latin-1')) addr = parse_address() try: p = self.instance.project r = QEMURunner(binary=bin_name, argv=argv, input=inp, project=p) s = p.factory.entry_state( mode='tracing', stdin=angr.SimFileStream) s.preconstrainer.preconstrain_file(inp, s.posix.stdin, True) sm = p.factory.simgr( s, save_unsat=True, hierarchy=False, save_unconstrained=r.crash_mode) t = sm.use_technique( angr.exploration_techniques.Tracer( trace=r.trace, resiliency=True, keep_predecessors=1, crash_addr=r.crash_addr)) sm.use_technique(angr.exploration_techniques.Oppologist()) sm.explore(find=addr) # add state to global state store state = sm.traced[0] if len(sm.traced) > 0 else sm.found[0] name = f"{hex(state.addr)} trace" state.gui_data.base_name = name state.gui_data.is_base = True state.gui_data.name = name state.gui_data.is_original = True self.instance.states.append(state) self._base_state_combo.refresh() for i in range(self._base_state_combo.count()): if self._base_state_combo.itemText(i) == name: self._base_state_combo.setCurrentIndex(i) self._address_box.setText(hex(state.addr)) self.close() except Exception as e: QMessageBox.about(self, 'Error', f"{repr(e)}") ok_button.clicked.connect(do_ok) cancel_button = QPushButton(self) cancel_button.setText('Cancel') def do_cancel(): self.close() cancel_button.clicked.connect(do_cancel) buttons_layout = QHBoxLayout() buttons_layout.addWidget(ok_button) buttons_layout.addWidget(cancel_button) container.addLayout(layout) container.addLayout(buttons_layout) self.setLayout(container) self.exec_()
from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QPlainTextEdit app = QApplication([]) window = QMainWindow() window.resize(500, 400) window.move(300, 310) window.setWindowTitle('薪资统计') textEdit = QPlainTextEdit(window) textEdit.setPlaceholderText("请输入薪资表") textEdit.move(10,25) textEdit.resize(300,350) button = QPushButton('统计', window) button.move(380,80) window.show() app.exec_()
class MainWindow(QMainWindow): font: QFont vertical_layout: QVBoxLayout central_widget: QWidget text_box: QPlainTextEdit recognize_button: QPushButton assistant: AssistantInterface def __init__(self, assistant: AssistantInterface): super().__init__() qInitResources() self.assistant = assistant self.build_layout() self.init_handlers() def build_layout(self): self.setup_window() self.setup_styles() self.setup_font() self.build_central_widget() self.build_vertical_layout() self.build_text_box() self.build_recognize_button() QMetaObject.connectSlotsByName(self) def setup_window(self): window_size = QSize(420, 700) self.setObjectName("window") self.resize(window_size) self.setMinimumSize(window_size) self.setMaximumSize(window_size) self.setWindowTitle(u"Voice Assistant") self.setAutoFillBackground(False) def setup_styles(self): file = QFile(":/styles/style.css") file.open(QFile.ReadOnly) byte_array = file.readAll() file.close() self.setStyleSheet(byte_array.data().decode()) def setup_font(self): self.font = QFont() self.font.setFamily(u"Helvetica") self.font.setPointSize(18) def build_central_widget(self): size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) self.central_widget = QWidget(self) self.central_widget.setObjectName(u"central_widget") self.central_widget.setSizePolicy(size_policy) self.setCentralWidget(self.central_widget) def build_vertical_layout(self): self.vertical_layout = QVBoxLayout(self.central_widget) self.vertical_layout.setObjectName(u"vertical_layout") def build_text_box(self): text_box_size = QSize(420, 600) self.text_box = QPlainTextEdit(self.central_widget) self.text_box.setObjectName(u"text_box") self.text_box.setMaximumSize(text_box_size) self.text_box.setFont(self.font) self.text_box.setContextMenuPolicy(Qt.NoContextMenu) self.text_box.setUndoRedoEnabled(False) self.text_box.setReadOnly(True) self.text_box.setPlaceholderText("Waiting for your question...") self.vertical_layout.addWidget(self.text_box) def build_recognize_button(self): button_size = QSize(140, 40) self.recognize_button = QPushButton(self.central_widget) self.recognize_button.setObjectName(u"recognize_button") self.recognize_button.setEnabled(True) self.recognize_button.setMinimumSize(button_size) self.recognize_button.setMaximumSize(button_size) self.recognize_button.setFont(self.font) self.recognize_button.setAutoFillBackground(False) self.recognize_button.setText("Recognize") self.recognize_button.setShortcut("Return") self.vertical_layout.addWidget(self.recognize_button, 0, Qt.AlignHCenter) def init_handlers(self): self.recognize_button.pressed.connect(self.start_recognition) self.assistant.on_wake = self.on_assistant_started self.assistant.on_sleep = self.on_assistant_finished self.assistant.on_assistant_listen = self.on_recognize_started self.assistant.on_user_message = self.on_user_text self.assistant.on_assistant_message = self.on_assistant_text def on_assistant_started(self): self.recognize_button.setEnabled(False) def on_assistant_finished(self): self.recognize_button.setEnabled(True) self.recognize_button.setText("Recognize") def on_recognize_started(self): self.async_play_sound() self.recognize_button.setText("Listening...") def on_user_text(self, user_text: str): self.recognize_button.setText("Processing...") self.append_message(f"[You] {user_text}") def on_assistant_text(self, assistant_answer: str): signed_text = f"[{self.assistant.get_name()}] {assistant_answer}" self.append_message(signed_text) def append_message(self, message: str): self.text_box.appendPlainText(f"{message}\n") def start_recognition(self): coroutine = self.assistant.handle() asyncio.create_task(coroutine) @async_function def async_play_sound(self): file = QFile(":/sounds/click.mp3") file.open(QFile.ReadOnly) byte_array = file.readAll() file.close() with tempfile.NamedTemporaryFile("wb", delete=True) as temp: temp.write(byte_array.data()) playsound(temp.name) def closeEvent(self, event: QCloseEvent): for task in asyncio.all_tasks(): task.cancel() asyncio.get_running_loop().stop() async def start(self): self.show()
def __init__(self): QWidget.__init__(self) self.q = None self.pool = None self.top = QHBoxLayout() self.top.setMargin(10) self.radioButtonMov = QRadioButton("电影") self.radioButtonCinema = QRadioButton("连续剧/综艺/动漫") self.top.addWidget(self.radioButtonMov) self.top.addWidget(self.radioButtonCinema) self.middle = QVBoxLayout() self.middle.setMargin(10) self.url_label = QLabel() self.url = QLineEdit() self.url_label.setBuddy(self.url) self.middle.addWidget(self.url_label) self.middle.addWidget(self.url) self.browse_folder_label = QLabel("下载到:") self.browseFolder = QPushButton("选择目录") self.browse_folder_label.setBuddy(self.browseFolder) self.middle.addWidget(self.browse_folder_label) self.middle.addWidget(self.browseFolder) self.browse_folder_value = "" self.dest_file_label = QLabel() # "输入电影/电视剧名 (用来命名下载的文件/目录): " title set by choose_movie_widgets() later self.folder_or_filename = QLineEdit() self.dest_file_label.setBuddy(self.folder_or_filename) self.middle.addWidget(self.dest_file_label) self.middle.addWidget(self.folder_or_filename) self.bk_cinemae_spin_from = 1 self.bk_cinemae_spin_to = 1 self.fromEpSpinBox = QSpinBox() self.fromEpSpinBox.setMinimum(1) self.fromEpSpinBox.setMaximum(2147483647) self.fromEpLabel = QLabel("&从第几集开始下载:") self.fromEpLabel.setBuddy(self.fromEpSpinBox) self.toEpSpinBox = QSpinBox() self.toEpSpinBox.setMinimum(1) self.toEpSpinBox.setMaximum(2147483647) self.toEpLabel = QLabel("&到第几集停止下载:") self.toEpLabel.setBuddy(self.toEpSpinBox) self.cinema_ly = QHBoxLayout() #self.cinema_ly.setMargin(10) self.cinema_ly.addWidget(self.fromEpLabel) self.cinema_ly.addWidget(self.fromEpSpinBox) self.cinema_ly.addWidget(self.toEpLabel) self.cinema_ly.addWidget(self.toEpSpinBox) self.middle.addLayout(self.cinema_ly) self.proxy_label = QLabel("(如有)代理:") self.proxy = QLineEdit() self.proxy_label.setBuddy(self.proxy) self.middle.addWidget(self.proxy_label) self.middle.addWidget(self.proxy) self.add = QPushButton("开始下载") self.add.setEnabled(False) self.middle.addWidget(self.add) self.stop_me = QPushButton("停止下载") self.stop_me.setEnabled(False) self.middle.addWidget(self.stop_me) self.log_area = QPlainTextEdit() self.log_area.setReadOnly(True) self.log_area.setMaximumBlockCount(1000) self.middle.addWidget(self.log_area) #self.table_view.setSizePolicy(size) #self.layout.addWidget(self.table) self.layout = QVBoxLayout() self.layout.addLayout(self.top) self.layout.addLayout(self.middle) self.setLayout(self.layout) self.radioButtonMov.toggled.connect(self.choose_movie_widgets) self.radioButtonCinema.toggled.connect(self.choose_cinema_widgets) self.url.textChanged[str].connect(self.check_disable_download) self.browseFolder.clicked.connect(self.add_folder) self.folder_or_filename.textChanged[str].connect( self.check_disable_download) self.add.clicked.connect(self.start_download) self.stop_me.clicked.connect(self.stop_download) self.radioButtonMov.setChecked( True) #set default only after .connect above # TESTING PURPOSE ''' self.radioButtonMov.setChecked(False) self.url.setText('https://www.duboku.net/voddetail-969.html') self.browse_folder_value = 'C:/Users/Administrator/Documents/duboku' self.folder_or_filename.setText('初恋') ''' #set current process (not queue that one) log handler: logger = logging.getLogger(__name__) handler2 = LoggerWriter() logger.addHandler(handler2) logger.setLevel(logging.INFO) #DEBUG handler2.emitter.sigLog.connect(self.log_area.appendPlainText) sys.stdout = handler2 #LoggerWriter()
def setHighlighter(self): self.modes.append( QCCodeHighlighter(self.document(), color_scheme=ColorSchemeIDA())) QPlainTextEdit.setReadOnly(self, True) self.setTextInteractionFlags(Qt.TextSelectableByKeyboard | Qt.TextSelectableByMouse)
def _add_process(self): process_groupbox = QGroupBox("Process") process_groupbox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) process_layout = QVBoxLayout() process_layout.setSpacing(0) process_groupbox.setLayout(process_layout) pbar_frame = QFrame() pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) pbar_hbox = QHBoxLayout() pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16)) pbar_hbox.setSpacing(16) # Run and stop buttons hbox = QHBoxLayout() hbox.setSpacing(8) self.run_button = QPushButton() # is only enabled when validation passes self.run_button.setEnabled(False) self.run_button.setText("Run") self.run_button.setFixedWidth(100) run_icon = qta.icon('fa.play', color='green') self.run_button.setIcon(run_icon) self.run_button.clicked.connect(self._click_run) hbox.addWidget(self.run_button) self.stop_button = QPushButton() self.stop_button.setEnabled(False) self.stop_button.setText("Stop") self.stop_button.setFixedWidth(100) stop_icon = qta.icon('fa.stop', color='red') self.stop_button.setIcon(stop_icon) self.stop_button.clicked.connect(self._click_stop) hbox.addWidget(self.stop_button) self.progress_bar = QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setAlignment(QtCore.Qt.AlignCenter) self.progress_bar.setValue(0) self.progress_bar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) pbar_hbox.addLayout(hbox) pbar_hbox.addWidget(self.progress_bar) pbar_frame.setLayout(pbar_hbox) process_layout.addWidget(pbar_frame) self.warning_frame = QFrame() self.warning_frame.setVisible(False) self.warning_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() warning_icon_widget = qta.IconWidget('fa.warning', color='red') warning_icon_widget.setIconSize(QtCore.QSize(48, 48)) warning_icon_widget.update() hbox.addWidget(warning_icon_widget) warning_label = QLabel( "Grid Transformer did not complete successfully. Please refer to " "log output.") warning_label.setStyleSheet("QLabel { color: red; }") warning_label.setWordWrap(True) warning_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(warning_label) self.warning_frame.setLayout(hbox) process_layout.addWidget(self.warning_frame) self.success_frame = QFrame() self.success_frame.setVisible(False) self.success_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox = QHBoxLayout() success_icon_widget = qta.IconWidget('fa.check', color='green') success_icon_widget.setIconSize(QtCore.QSize(48, 48)) success_icon_widget.update() hbox.addWidget(success_icon_widget) success_label = QLabel("Grid Transformer completed successfully.") success_label.setStyleSheet("QLabel { color: green; }") success_label.setWordWrap(True) success_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) hbox.addWidget(success_label) self.success_frame.setLayout(hbox) process_layout.addWidget(self.success_frame) log_layout = QVBoxLayout() log_layout.setSpacing(4) log_label = QLabel("Log messages") log_label.setStyleSheet("QLabel { color: grey; }") log_layout.addWidget(log_label) self.log_messages = QPlainTextEdit() log_font = QFont("monospace") log_font.setStyleHint(QFont.TypeWriter) self.log_messages.setFont(log_font) self.log_messages.setReadOnly(True) self.log_messages.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # self.log_messages.sizePolicy.setVerticalStretch(1) log_layout.addWidget(self.log_messages) process_layout.addLayout(log_layout) self.layout.addWidget(process_groupbox)
class Snippets(QDialog): def __init__(self, parent=None): super(Snippets, self).__init__(parent) # Create widgets self.setWindowModality(Qt.ApplicationModal) self.title = QLabel(self.tr("Snippet Editor")) self.saveButton = QPushButton(self.tr("Save")) self.closeButton = QPushButton(self.tr("Close")) self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey")) self.setWindowTitle(self.title.text()) self.newFolderButton = QPushButton("New Folder") self.deleteSnippetButton = QPushButton("Delete") self.newSnippetButton = QPushButton("New Snippet") self.edit = QPlainTextEdit() self.edit.setPlaceholderText("python code") self.resetting = False self.columns = 3 self.keySequenceEdit = QKeySequenceEdit(self) self.currentHotkey = QKeySequence() self.currentHotkeyLabel = QLabel("") self.currentFileLabel = QLabel() self.currentFile = "" self.snippetDescription = QLineEdit() self.snippetDescription.setPlaceholderText("optional description") #Set Editbox Size font = getMonospaceFont(self) self.edit.setFont(font) font = QFontMetrics(font) self.edit.setTabStopWidth(4 * font.width(' ')) #TODO, replace with settings API #Files self.files = QFileSystemModel() self.files.setRootPath(snippetPath) self.files.setNameFilters(["*.py"]) #Tree self.tree = QTreeView() self.tree.setModel(self.files) self.tree.setSortingEnabled(True) self.tree.hideColumn(2) self.tree.sortByColumn(0, Qt.AscendingOrder) self.tree.setRootIndex(self.files.index(snippetPath)) for x in range(self.columns): #self.tree.resizeColumnToContents(x) self.tree.header().setSectionResizeMode( x, QHeaderView.ResizeToContents) treeLayout = QVBoxLayout() treeLayout.addWidget(self.tree) treeButtons = QHBoxLayout() treeButtons.addWidget(self.newFolderButton) treeButtons.addWidget(self.newSnippetButton) treeButtons.addWidget(self.deleteSnippetButton) treeLayout.addLayout(treeButtons) treeWidget = QWidget() treeWidget.setLayout(treeLayout) # Create layout and add widgets buttons = QHBoxLayout() buttons.addWidget(self.clearHotkeyButton) buttons.addWidget(self.keySequenceEdit) buttons.addWidget(self.currentHotkeyLabel) buttons.addWidget(self.closeButton) buttons.addWidget(self.saveButton) description = QHBoxLayout() description.addWidget(QLabel(self.tr("Description: "))) description.addWidget(self.snippetDescription) vlayoutWidget = QWidget() vlayout = QVBoxLayout() vlayout.addLayout(description) vlayout.addWidget(self.edit) vlayout.addLayout(buttons) vlayoutWidget.setLayout(vlayout) hsplitter = QSplitter() hsplitter.addWidget(treeWidget) hsplitter.addWidget(vlayoutWidget) hlayout = QHBoxLayout() hlayout.addWidget(hsplitter) self.showNormal() #Fixes bug that maximized windows are "stuck" self.settings = QSettings("Vector35", "Snippet Editor") if self.settings.contains("ui/snippeteditor/geometry"): self.restoreGeometry( self.settings.value("ui/snippeteditor/geometry")) else: self.edit.setMinimumWidth(80 * font.averageCharWidth()) self.edit.setMinimumHeight(30 * font.lineSpacing()) # Set dialog layout self.setLayout(hlayout) # Add signals self.saveButton.clicked.connect(self.save) self.closeButton.clicked.connect(self.close) self.clearHotkeyButton.clicked.connect(self.clearHotkey) self.tree.selectionModel().selectionChanged.connect(self.selectFile) self.newSnippetButton.clicked.connect(self.newFileDialog) self.deleteSnippetButton.clicked.connect(self.deleteSnippet) self.newFolderButton.clicked.connect(self.newFolder) #Read-only until new snippet self.readOnly(True) @staticmethod def registerAllSnippets(): for action in list( filter(lambda x: x.startswith("Snippets\\"), UIAction.getAllRegisteredActions())): if action == "Snippets\\Snippet Editor...": continue UIActionHandler.globalActions().unbindAction(action) Menu.mainMenu("Tools").removeAction(action) UIAction.unregisterAction(action) for snippet in includeWalk(snippetPath, ".py"): snippetKeys = None (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(snippet) if not snippetDescription: actionText = "Snippets\\" + os.path.basename(snippet).rstrip( ".py") else: actionText = "Snippets\\" + snippetDescription if snippetCode: if snippetKeys == None: UIAction.registerAction(actionText) else: UIAction.registerAction(actionText, snippetKeys) UIActionHandler.globalActions().bindAction( actionText, UIAction(makeSnippetFunction(snippetCode))) Menu.mainMenu("Tools").addAction(actionText, actionText) def clearSelection(self): self.keySequenceEdit.clear() self.currentHotkey = QKeySequence() self.currentHotkeyLabel.setText("") self.currentFileLabel.setText("") self.snippetDescription.setText("") self.edit.setPlainText("") self.currentFile = "" def reject(self): self.settings.setValue("ui/snippeteditor/geometry", self.saveGeometry()) if self.snippetChanged(): question = QMessageBox.question( self, self.tr("Discard"), self.tr("You have unsaved changes, quit anyway?")) if question != QMessageBox.StandardButton.Yes: return self.accept() def newFolder(self): (folderName, ok) = QInputDialog.getText(self, self.tr("Folder Name"), self.tr("Folder Name: ")) if ok and folderName: index = self.tree.selectionModel().currentIndex() selection = self.files.filePath(index) if QFileInfo(selection).isDir(): QDir(selection).mkdir(folderName) else: QDir(snippetPath).mkdir(folderName) def selectFile(self, new, old): if (self.resetting): self.resetting = False return newSelection = self.files.filePath(new.indexes()[0]) if QFileInfo(newSelection).isDir(): self.readOnly(True) self.tree.clearSelection() self.currentFile = "" return if old.length() > 0: oldSelection = self.files.filePath(old.indexes()[0]) if not QFileInfo(oldSelection).isDir() and self.snippetChanged(): question = QMessageBox.question( self, self.tr("Discard"), self.tr("Snippet changed. Discard changes?")) if question != QMessageBox.StandardButton.Yes: self.resetting = True self.tree.selectionModel().select( old, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) return False self.currentFile = newSelection self.loadSnippet() def loadSnippet(self): self.currentFileLabel.setText(QFileInfo(self.currentFile).baseName()) (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile) self.snippetDescription.setText( snippetDescription ) if snippetDescription else self.snippetDescription.setText("") self.keySequenceEdit.setKeySequence( snippetKeys ) if snippetKeys else self.keySequenceEdit.setKeySequence( QKeySequence("")) self.edit.setPlainText( snippetCode) if snippetCode else self.edit.setPlainText("") self.readOnly(False) def newFileDialog(self): (snippetName, ok) = QInputDialog.getText(self, self.tr("Snippet Name"), self.tr("Snippet Name: ")) if ok and snippetName: if not snippetName.endswith(".py"): snippetName += ".py" index = self.tree.selectionModel().currentIndex() selection = self.files.filePath(index) if QFileInfo(selection).isDir(): path = os.path.join(selection, snippetName) else: path = os.path.join(snippetPath, snippetName) self.readOnly(False) open(path, "w").close() self.tree.setCurrentIndex(self.files.index(path)) log_debug("Snippet %s created." % snippetName) def readOnly(self, flag): self.keySequenceEdit.setEnabled(not flag) self.snippetDescription.setReadOnly(flag) self.edit.setReadOnly(flag) if flag: self.snippetDescription.setDisabled(True) self.edit.setDisabled(True) else: self.snippetDescription.setEnabled(True) self.edit.setEnabled(True) def deleteSnippet(self): selection = self.tree.selectedIndexes()[::self.columns][ 0] #treeview returns each selected element in the row snippetName = self.files.fileName(selection) question = QMessageBox.question( self, self.tr("Confirm"), self.tr("Confirm deletion: ") + snippetName) if (question == QMessageBox.StandardButton.Yes): log_debug("Deleting snippet %s." % snippetName) self.clearSelection() self.files.remove(selection) self.registerAllSnippets() def snippetChanged(self): if (self.currentFile == "" or QFileInfo(self.currentFile).isDir()): return False (snippetDescription, snippetKeys, snippetCode) = loadSnippetFromFile(self.currentFile) if snippetKeys == None and not self.keySequenceEdit.keySequence( ).isEmpty(): return True if snippetKeys != None and snippetKeys != self.keySequenceEdit.keySequence( ).toString(): return True return self.edit.toPlainText() != snippetCode or \ self.snippetDescription.text() != snippetDescription def save(self): log_debug("Saving snippet %s" % self.currentFile) outputSnippet = open(self.currentFile, "w") outputSnippet.write("#" + self.snippetDescription.text() + "\n") outputSnippet.write("#" + self.keySequenceEdit.keySequence().toString() + "\n") outputSnippet.write(self.edit.toPlainText()) outputSnippet.close() self.registerAllSnippets() def clearHotkey(self): self.keySequenceEdit.clear()
class Notepad(QMainWindow): def __init__(self, *args, **kwargs): super(Notepad, self).__init__(*args, **kwargs) self.setWindowIcon(QIcon('arti.PNG')) self.setGeometry(200, 100, 700, 400) layout = QVBoxLayout() self.editor = QPlainTextEdit() self.editor.setFont(QFont('Roboto', 12)) # self.path holds the path of the currently open file. # If none, we haven't got a file open yet (or creating new). self.path = None layout.addWidget(self.editor) container = QWidget() container.setLayout(layout) self.setCentralWidget(container) self.status = QStatusBar() self.setStatusBar(self.status) file_toolbar = QToolBar("File") file_toolbar.setIconSize(QSize(14, 14)) self.addToolBar(file_toolbar) file_menu = self.menuBar().addMenu("&File") open_file_action = QAction(QIcon(), "Open file...", self) open_file_action.setStatusTip("Open file") open_file_action.triggered.connect(self.file_open) file_menu.addAction(open_file_action) file_toolbar.addAction(open_file_action) open_file_action.setShortcut(QKeySequence('Ctrl+O')) save_file_action = QAction(QIcon(), "Save", self) save_file_action.setStatusTip("Save current page") save_file_action.triggered.connect(self.file_save) file_menu.addAction(save_file_action) file_toolbar.addAction(save_file_action) save_file_action.setShortcut(QKeySequence('Ctrl+S')) saveas_file_action = QAction(QIcon(), "Save As...", self) saveas_file_action.setStatusTip("Save current page to specified file") saveas_file_action.triggered.connect(self.file_saveas) file_menu.addAction(saveas_file_action) file_toolbar.addAction(saveas_file_action) saveas_file_action.setShortcut(QKeySequence('Ctrl+Shift+S')) print_action = QAction(QIcon(), "Print...", self) print_action.setStatusTip("Print current page") print_action.triggered.connect(self.file_print) file_menu.addAction(print_action) file_toolbar.addAction(print_action) print_action.setShortcut(QKeySequence('Ctrl+P')) edit_toolbar = QToolBar("Edit") edit_toolbar.setIconSize(QSize(16, 16)) self.addToolBar(edit_toolbar) edit_menu = self.menuBar().addMenu("&Edit") undo_action = QAction(QIcon(), "Undo", self) undo_action.setStatusTip("Undo last change") undo_action.triggered.connect(self.editor.undo) edit_menu.addAction(undo_action) undo_action.setShortcut(QKeySequence('Ctrl+Z')) redo_action = QAction(QIcon(), "Redo", self) redo_action.setStatusTip("Redo last change") redo_action.triggered.connect(self.editor.redo) edit_toolbar.addAction(redo_action) edit_menu.addAction(redo_action) redo_action.setShortcut(QKeySequence('Ctrl+Y')) edit_menu.addSeparator() cut_action = QAction(QIcon(), "Cut", self) cut_action.setStatusTip("Cut selected text") cut_action.triggered.connect(self.editor.cut) edit_toolbar.addAction(cut_action) edit_menu.addAction(cut_action) cut_action.setShortcut(QKeySequence('Ctrl+X')) copy_action = QAction(QIcon(), "Copy", self) copy_action.setStatusTip("Copy selected text") copy_action.triggered.connect(self.editor.copy) edit_toolbar.addAction(copy_action) edit_menu.addAction(copy_action) copy_action.setShortcut(QKeySequence('Ctrl+C')) paste_action = QAction(QIcon(), "Paste", self) paste_action.setStatusTip("Paste from clipboard") paste_action.triggered.connect(self.editor.paste) edit_toolbar.addAction(paste_action) edit_menu.addAction(paste_action) paste_action.setShortcut(QKeySequence('Ctrl+V')) select_action = QAction(QIcon(), "Select all", self) select_action.setStatusTip("Select all text") select_action.triggered.connect(self.editor.selectAll) edit_menu.addAction(select_action) select_action.setShortcut(QKeySequence('Ctrl+A')) edit_menu.addSeparator() wrap_action = QAction(QIcon(), "Wrap text to window", self) wrap_action.setStatusTip("Toggle wrap text to window") wrap_action.setCheckable(True) wrap_action.setChecked(True) wrap_action.triggered.connect(self.edit_toggle_wrap) edit_menu.addAction(wrap_action) self.update_title() self.show() def dialog_critical(self, s): dlg = QMessageBox(self) dlg.setText(s) dlg.setIcon(QMessageBox.Critical) dlg.show() def file_open(self): path, _ = QFileDialog.getOpenFileName(self, "Open file", "", "Text documents (*.txt)") if path: try: with open(path, 'rU') as f: text = f.read() except Exception as e: self.dialog_critical(str(e)) else: self.path = path self.editor.setPlainText(text) self.update_title() def file_save(self): if self.path is None: return self.file_saveas() self._save_to_path(self.path) def file_saveas(self): path, _ = QFileDialog.getSaveFileName(self, "Save file", "", "Text documents (*.txt)") if not path: return self._save_to_path(path) def _save_to_path(self, path): text = self.editor.toPlainText() try: with open(path, 'w') as f: f.write(text) except Exception as e: self.dialog_critical(str(e)) else: self.path = path self.update_title() def file_print(self): dlg = QPrintDialog() if dlg.exec_(): self.editor.print_(dlg.printer()) def update_title(self): self.setWindowTitle("%s - Notepad" % (os.path.basename(self.path) if self.path else "Untitled")) def edit_toggle_wrap(self): self.editor.setLineWrapMode(1 if self.editor.lineWrapMode() == 0 else 0)
def __init__(self, parent=None): super(Snippets, self).__init__(parent) # Create widgets self.setWindowModality(Qt.ApplicationModal) self.title = QLabel(self.tr("Snippet Editor")) self.saveButton = QPushButton(self.tr("Save")) self.closeButton = QPushButton(self.tr("Close")) self.clearHotkeyButton = QPushButton(self.tr("Clear Hotkey")) self.setWindowTitle(self.title.text()) self.newFolderButton = QPushButton("New Folder") self.deleteSnippetButton = QPushButton("Delete") self.newSnippetButton = QPushButton("New Snippet") self.edit = QPlainTextEdit() self.edit.setPlaceholderText("python code") self.resetting = False self.columns = 3 self.keySequenceEdit = QKeySequenceEdit(self) self.currentHotkey = QKeySequence() self.currentHotkeyLabel = QLabel("") self.currentFileLabel = QLabel() self.currentFile = "" self.snippetDescription = QLineEdit() self.snippetDescription.setPlaceholderText("optional description") #Set Editbox Size font = getMonospaceFont(self) self.edit.setFont(font) font = QFontMetrics(font) self.edit.setTabStopWidth(4 * font.width(' ')) #TODO, replace with settings API #Files self.files = QFileSystemModel() self.files.setRootPath(snippetPath) self.files.setNameFilters(["*.py"]) #Tree self.tree = QTreeView() self.tree.setModel(self.files) self.tree.setSortingEnabled(True) self.tree.hideColumn(2) self.tree.sortByColumn(0, Qt.AscendingOrder) self.tree.setRootIndex(self.files.index(snippetPath)) for x in range(self.columns): #self.tree.resizeColumnToContents(x) self.tree.header().setSectionResizeMode( x, QHeaderView.ResizeToContents) treeLayout = QVBoxLayout() treeLayout.addWidget(self.tree) treeButtons = QHBoxLayout() treeButtons.addWidget(self.newFolderButton) treeButtons.addWidget(self.newSnippetButton) treeButtons.addWidget(self.deleteSnippetButton) treeLayout.addLayout(treeButtons) treeWidget = QWidget() treeWidget.setLayout(treeLayout) # Create layout and add widgets buttons = QHBoxLayout() buttons.addWidget(self.clearHotkeyButton) buttons.addWidget(self.keySequenceEdit) buttons.addWidget(self.currentHotkeyLabel) buttons.addWidget(self.closeButton) buttons.addWidget(self.saveButton) description = QHBoxLayout() description.addWidget(QLabel(self.tr("Description: "))) description.addWidget(self.snippetDescription) vlayoutWidget = QWidget() vlayout = QVBoxLayout() vlayout.addLayout(description) vlayout.addWidget(self.edit) vlayout.addLayout(buttons) vlayoutWidget.setLayout(vlayout) hsplitter = QSplitter() hsplitter.addWidget(treeWidget) hsplitter.addWidget(vlayoutWidget) hlayout = QHBoxLayout() hlayout.addWidget(hsplitter) self.showNormal() #Fixes bug that maximized windows are "stuck" self.settings = QSettings("Vector35", "Snippet Editor") if self.settings.contains("ui/snippeteditor/geometry"): self.restoreGeometry( self.settings.value("ui/snippeteditor/geometry")) else: self.edit.setMinimumWidth(80 * font.averageCharWidth()) self.edit.setMinimumHeight(30 * font.lineSpacing()) # Set dialog layout self.setLayout(hlayout) # Add signals self.saveButton.clicked.connect(self.save) self.closeButton.clicked.connect(self.close) self.clearHotkeyButton.clicked.connect(self.clearHotkey) self.tree.selectionModel().selectionChanged.connect(self.selectFile) self.newSnippetButton.clicked.connect(self.newFileDialog) self.deleteSnippetButton.clicked.connect(self.deleteSnippet) self.newFolderButton.clicked.connect(self.newFolder) #Read-only until new snippet self.readOnly(True)
result = f'{port}端口开放' sock.close() # 关闭连接 except Exception as e: result = f'{port}端口关闭' win.append(result) #QMessageBox.about(window,'扫描结果',result) app = QApplication([]) window = QMainWindow() window.resize(500, 270) window.move(300, 300) window.setWindowTitle('端口扫描') textEdit1 = QPlainTextEdit(window) #textEdit1.setPlaceholderText("输入IP") textEdit1.move(10, 50) textEdit1.resize(200, 40) textEdit2 = QPlainTextEdit(window) #textEdit2.setPlaceholderText("输入端口") textEdit2.move(10, 130) textEdit2.resize(200, 40) textEdit3 = QPlainTextEdit(window) #textEdit3.setPlaceholderText("超时(毫秒)") textEdit3.move(10, 210) textEdit3.resize(200, 40) label1 = QLabel(window)
def keyPressEvent(self, event): if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return: self.editing_finished(self.toPlainText()) self.last_text = self.toPlainText() else: QPlainTextEdit.keyPressEvent(self, event)
def focusOutEvent(self, event): txt = self.toPlainText() if txt != self.last_text: self.editing_finished(txt) self.last_text = txt QPlainTextEdit.focusOutEvent(self, event)
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.textEdit = QPlainTextEdit() self.initUI() def initUI(self): openAction = QAction('&Open...', self) openAction.setShortcut('Ctrl+O') openAction.setStatusTip('Open JSON file') openAction.triggered.connect(self.open) openLinkAction = QAction('&Open URL...', self) openLinkAction.setShortcut('Ctrl+L') openLinkAction.setStatusTip('Load JSON by URL') openLinkAction.triggered.connect(self.openLink) saveAction = QAction('&Save...', self) saveAction.setShortcut('Ctrl+S') saveAction.setStatusTip('Save JSON file') saveAction.triggered.connect(self.save) exitAction = QAction('&Quit', self) exitAction.setShortcut('Ctrl+Q') exitAction.setStatusTip('Exit application') exitAction.triggered.connect(self.close) self.statusBar() menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(openAction) fileMenu.addAction(openLinkAction) fileMenu.addAction(saveAction) fileMenu.addSeparator() fileMenu.addAction(exitAction) font = self.textEdit.font() font.setFamily("monospace") font.setPointSize(14) sb = self.textEdit.verticalScrollBar() sb.setValue(sb.maximum()) self.setCentralWidget(self.textEdit) self.resize(800, 600) self.setWindowTitle("JSON Editor") self.show() def open(self): fname, _ = QFileDialog.getOpenFileName(self, 'Open JSON file', '/home') if fname == '': return f = open(fname, 'r') with f: data = f.read() self.textEdit.setPlainText(data) def openLink(self): url, ok = QInputDialog.getText(self, 'Load JSON by URL', 'Enter URL:') if not ok: return try: with request.urlopen(url) as f: data = f.read() self.textEdit.setPlainText(str(data, 'utf-8')) except (ValueError, error.URLError, error.HTTPError): msgBox = QMessageBox() msgBox.setText("Can't load JSON data") msgBox.exec_() def save(self): try: json.loads(self.textEdit.toPlainText()) except json.JSONDecodeError: msgBox = QMessageBox() msgBox.setTitle("Error") msgBox.setText("Invalid JSON") msgBox.exec_() return fname, _ = QFileDialog.getSaveFileName(self, 'Save JSON to file') f = open(fname, "w") f.write(self.textEdit.toPlainText()) f.close()
def __init__(self): QMainWindow.__init__(self) self.textEdit = QPlainTextEdit() self.initUI()
def __init__(self, parent): super(Editor, self).__init__(parent) self.path = Path(__file__).parent / 'shaders' self.project = None self.programName = None self.vertexShader = '' self.fragmentShader = '' self.colorEditor = QLineEdit() self.colorEditor.setEnabled(False) self.colorEditor.textChanged.connect(self.updateColorHex) self.updateColor((0.5, 0.5, 0.5, 1.0)) self.pickButton = QPushButton('Pick') self.pickButton.setEnabled(False) self.pickButton.clicked.connect(self.pickColor) colorContainer = QWidget() colorContainer.setLayout(QHBoxLayout()) colorContainer.layout().setMargin(0) colorContainer.layout().addWidget(self.colorEditor) colorContainer.layout().addWidget(self.pickButton) self.displayRatioSlider = QSlider(Qt.Horizontal) self.displayRatioSlider.setRange(0, 1000) self.displayRatioSlider.setEnabled(False) self.displayRatioSlider.setSingleStep(1) self.displayRatioSlider.setPageStep(10) self.displayRatioSlider.valueChanged.connect(self.updateDisplayRatio) self.pointSizeSlider = QSlider(Qt.Horizontal) self.pointSizeSlider.setRange(0, 500) self.pointSizeSlider.setEnabled(False) self.pointSizeSlider.setSingleStep(1) self.pointSizeSlider.setPageStep(10) self.pointSizeSlider.valueChanged.connect(self.updatePointSize) self.distanceSlider = QSlider(Qt.Horizontal) self.distanceSlider.setRange(0, 1000) self.distanceSlider.setEnabled(False) self.distanceSlider.setSingleStep(1) self.distanceSlider.setPageStep(10) self.distanceSlider.valueChanged.connect(self.updateDistanceRange) self.vertexEditor = QPlainTextEdit() self.vertexEditor.setStyleSheet( "QPlainTextEdit { background: #393939; color: #b6dede; font: 1rem 'monospace'; }" ) self.vertexEditor.setLineWrapMode(QPlainTextEdit.NoWrap) self.vertexEditor.setWordWrapMode(QTextOption.NoWrap) self.vertexEditor.setTabStopWidth(2) self.vertexEditor.setTabChangesFocus(False) self.vertexEditor.setCenterOnScroll(True) self.vertexEditor.setEnabled(False) self.vertexEditor.textChanged.connect(self.saveVertex) self.fragmentEditor = QPlainTextEdit() self.fragmentEditor.setStyleSheet( "QPlainTextEdit { background: #393939; color: #b6dede; font: 1rem 'monospace'; }" ) self.fragmentEditor.setLineWrapMode(QPlainTextEdit.NoWrap) self.fragmentEditor.setWordWrapMode(QTextOption.NoWrap) self.fragmentEditor.setTabStopWidth(2) self.fragmentEditor.setTabChangesFocus(False) self.fragmentEditor.setCenterOnScroll(True) self.fragmentEditor.setEnabled(False) self.fragmentEditor.textChanged.connect(self.saveFragment) self.setLayout(QVBoxLayout()) self.layout().addWidget(QLabel("Display (%):")) self.layout().addWidget(self.displayRatioSlider) self.layout().addWidget(QLabel("Mask Point size (px):")) self.layout().addWidget(self.pointSizeSlider) self.layout().addWidget(QLabel("Mask Distance range:")) self.layout().addWidget(self.distanceSlider) self.layout().addWidget(QLabel("Clear color:")) self.layout().addWidget(colorContainer) self.layout().addWidget(QLabel("Vertex shader:")) self.layout().addWidget(self.vertexEditor) self.layout().addWidget(QLabel("Fragment shader:")) self.layout().addWidget(self.fragmentEditor)