def createRow(self, exercise, index): item = QHBoxLayout() label = QLabel(exercise.name) item.addWidget(label) item.setAlignment(label, Qt.Alignment.AlignCenter) button = QPushButton(exercise.assigned_key[0]) # button.installEventFilter(self) button.setStyleSheet(""" QPushButton { border: 1px solid grey; background-color: white; } """) button.clicked.connect(partial(self.openDialog, button)) self.buttons.append(button) item.addWidget(button) self.mainLayout.addLayout(item, index, 0) print(index, exercise.name, exercise.assigned_key)
def __init__( self, onValueChanged: Callable[[int], None], parent: Optional[QWidget] = None, *args: Tuple[Any, Any], **kwargs: Tuple[Any, Any], ) -> None: """ Slow/fast slider for maze solver agents speed """ super(MazeSolverSpeedControlView, self).__init__(parent=parent, *args, **kwargs) self.setContentsMargins(0, 0, 0, 0) layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) slider = QSlider(Qt.Orientations.Horizontal) # minimum of 1 op/s (0 would result in a divide by zero op and thus crash) slider.setMinimum(1) # maximum of 50 op/s slider.setMaximum(70) # initial value in the middle slider.setValue(35) # connect the onValueChange event to the method passed to this widget slider.valueChanged.connect(onValueChanged) # type: ignore # slow/fast horizontal labels view slowFastLabelsLayout = QHBoxLayout() slowFastLabelsLayout.setContentsMargins(0, 0, 0, 0) slowLabel = QLabel("Slow") fastLabel = QLabel("Fast") slowFastLabelsLayout.addWidget(slowLabel) slowFastLabelsLayout.addStretch() slowFastLabelsLayout.addWidget(fastLabel) layout.addWidget(slider) layout.addLayout(slowFastLabelsLayout) self.setLayout(layout)
def init_ui(self): layout = QVBoxLayout() self.setLayout(layout) self.text = QTextEdit() layout.addWidget(self.text) layout2 = QHBoxLayout() layout.addLayout(layout2) self.combo = QComboBox() self.combo.addItem('不自动加换行符') self.combo.addItem('结尾自动加\\r\\n') self.combo.addItem('结尾自动加\\r') self.combo.addItem('结尾自动加\\n') self.send_btn = QPushButton('发送') layout2.addWidget(self.combo) layout2.addWidget(self.send_btn)
def __init__(self, table_view): """ A simple class that inherits QWidget and acts as a container for items added to QTableView cells """ super().__init__() self.table_view = table_view self.setAutoFillBackground(True) view_button = QPushButton(QIcon("icons/view.png"), None) view_button.clicked.connect(self.displayItemValues) delete_button = QPushButton(QIcon("icons/trash.png"), None) delete_button.clicked.connect(self.deleteTableRows) # Create the layout for the buttons cell_layout = QHBoxLayout() cell_layout.setContentsMargins(0, 0, 0, 0) cell_layout.setSpacing(0) cell_layout.addWidget(view_button) cell_layout.addWidget(delete_button) self.setLayout(cell_layout)
def initUI(self): okButton = QPushButton("OK") cancelButton = QPushButton("Cancel") hbox = QHBoxLayout() hbox.addStretch(1) hbox.addWidget(okButton) hbox.addWidget(cancelButton) vbox = QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox) self.setLayout(vbox) self.setGeometry(300, 300, 350, 250) self.setWindowTitle('Buttons') self.show()
def makeTitle(): titleLayout = QHBoxLayout() # titleLayout.setSpacing(42) titleFont = QtGui.QFont("Times", 32, QtGui.QFont.Weight.Bold) title = QLabel(opts.timeclockOpts["title"]) title.setFixedWidth(820) title.setFont(titleFont) logo = QLabel() logoImage = QtGui.QPixmap("../data/assets/" + opts.timeclockOpts["logo"]) logoImage = logoImage.scaled(QtCore.QSize(100, 100)) logo.setPixmap(logoImage) if opts.timeclockOpts["darkTheme"]: logo.setStyleSheet("QLabel {background:white}") titleLayout.addWidget(title) titleLayout.addStretch() titleLayout.addWidget(logo) return titleLayout
def __init__(self, parent): super().__init__(parent) self.setWindowTitle('Cargar Fichero') self.dlg_v_layout = QVBoxLayout() form_layout = QFormLayout() self.load_file = QLineEdit() self.error_label = QLabel() form_layout.addRow('Ruta del archivo:', self.load_file) self.dlg_v_layout.addLayout(form_layout) self.dlg_v_layout.addWidget(self.error_label) buttons_h_layout = QHBoxLayout() button_cancel = QPushButton('Cancelar') self.button_ok = QPushButton('Aceptar') buttons_h_layout.addWidget(button_cancel) buttons_h_layout.addWidget(self.button_ok) self.dlg_v_layout.addLayout(buttons_h_layout) self.setLayout(self.dlg_v_layout) button_cancel.clicked.connect(self._clear) button_cancel.clicked.connect(self.close) self.button_ok.clicked.connect(self._load)
def createStaffTab(self): """Create the page to view the Staff table from the database.""" staff_sql_model = QSqlRelationalTableModel() staff_sql_model.setTable("Staff") staff_sql_model.select() # Populate the model with data staff_proxy_model = QSortFilterProxyModel() staff_proxy_model.setSourceModel(staff_sql_model) staff_table = QTableView() staff_table.setSortingEnabled(True) staff_table.setModel(staff_proxy_model) staff_table.setItemDelegateForColumn( staff_sql_model.fieldIndex("staff_id"), ReadOnlyDelegate()) staff_table.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeMode.Stretch) staff_h_box = QHBoxLayout() staff_h_box.addWidget(staff_table) self.staff_tab.setLayout(staff_h_box)
def createCategoriesTab(self): """Create the page to view the Categories table from the database.""" cat_sql_model = QSqlRelationalTableModel() cat_sql_model.setTable("Categories") cat_sql_model.select() # Populate the model with data cat_proxy_model = QSortFilterProxyModel() cat_proxy_model.setSourceModel(cat_sql_model) cat_table = QTableView() cat_table.setSortingEnabled(True) cat_table.setModel(cat_proxy_model) cat_table.setItemDelegateForColumn( cat_sql_model.fieldIndex("category_id"), ReadOnlyDelegate()) cat_table.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeMode.Stretch) cat_h_box = QHBoxLayout() cat_h_box.addWidget(cat_table) self.category_tab.setLayout(cat_h_box)
def __init__(self, *args): QFrame.__init__(self, *args) self.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Sunken) self.edit = QTextEdit() self.edit.setFrameStyle(QFrame.Shape.NoFrame) self.edit.setAcceptRichText(False) self.edit.setLineWrapMode(QTextEdit.LineWrapMode.NoWrap) self.number_bar = self.NumberBar() self.number_bar.set_text_edit(self.edit) hbox = QHBoxLayout(self) hbox.setSpacing(0) hbox.setContentsMargins(10,0,0,0) hbox.addWidget(self.number_bar) hbox.addWidget(self.edit) self.edit.installEventFilter(self) self.edit.viewport().installEventFilter(self)
def __init__( self, state: str, parent: Optional[QWidget] = None, *args: Tuple[Any, Any], **kwargs: Tuple[Any, Any], ) -> None: """ The horizontal box of the current state of the solver. """ super(CurrentStateBox, self).__init__(parent=parent, *args, **kwargs) self.setContentsMargins(0, 0, 0, 0) layout = QHBoxLayout() # add "State: " label to layout: layout.addWidget(QLabel("State: ")) # create current state label and add to layout: self.__currentStateLabel = QLabel(state) layout.addWidget(self.__currentStateLabel) self.setLayout(layout)
def createLayout(self): self.groupBox = QGroupBox("What Is Your Favorite Sport?") hboxlayout = QHBoxLayout() self.button = QPushButton("Football", self) self.button.setIcon(QtGui.QIcon("home.png")) self.button.setIconSize(QSize(40, 40)) self.button.setToolTip("This Is Click Me Button") self.button.setMinimumHeight(40) hboxlayout.addWidget(self.button) self.button1 = QPushButton("Cricket", self) self.button1.setIcon(QtGui.QIcon("home.png")) self.button1.setIconSize(QSize(40, 40)) self.button1.setMinimumHeight(40) self.button1.setToolTip("This Is Click Me Button") hboxlayout.addWidget(self.button1) self.button2 = QPushButton("Tennis", self) self.button2.setIcon(QtGui.QIcon("home.png")) self.button2.setIconSize(QSize(40, 40)) self.button2.setMinimumHeight(40) self.button2.setToolTip("This Is Click Me Button") hboxlayout.addWidget(self.button2) self.groupBox.setLayout(hboxlayout)
def createProductsTab(self): """Create the page to view the Products table from the database.""" prod_sql_model = QSqlRelationalTableModel() prod_sql_model.setTable("Products") prod_sql_model.setRelation( prod_sql_model.fieldIndex("category_id"), QSqlRelation("Categories", "category_id", "category_name")) prod_sql_model.select() # Populate the model with data prod_proxy_model = QSortFilterProxyModel() prod_proxy_model.setSourceModel(prod_sql_model) prod_table = QTableView() prod_table.setSortingEnabled(True) prod_table.setModel(prod_proxy_model) prod_table.setItemDelegate(SqlProxyDelegate(prod_table)) prod_table.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeMode.Stretch) prod_h_box = QHBoxLayout() prod_h_box.addWidget(prod_table) self.products_tab.setLayout(prod_h_box)
def displayTag(self, tagName): tagWidget = QWidget() tagWidget.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True) tagWidget.enterEvent = lambda e: self.setCursor( QCursor(Qt.CursorShape.PointingHandCursor)) tagWidget.leaveEvent = lambda e: self.setCursor( QCursor(Qt.CursorShape.ArrowCursor)) tagWidget.mouseReleaseEvent = lambda e: self.removeTag( self.flowLayout.indexOf(tagWidget), returnTag=False) self.renderStyleSheet(tagWidget) hBoxTag = QHBoxLayout() tagLabel = QLabel() tagLabel.setText(tagName) tagLabel.setStyleSheet(f''' QLabel {{ background-color: transparent; border: none; }} ''') hBoxTag.addWidget(tagLabel) crossIcon = QPixmap('MangoUI/TagBox/img/crossresized.png') crossIconLabel = QLabel() crossIconLabel.setPixmap(crossIcon) crossIconLabel.setStyleSheet(f''' QLabel {{ background-color: transparent; border: none; }} ''') hBoxTag.addWidget(crossIconLabel) hBoxTag.setContentsMargins(10, 6, 6, 6) tagWidget.setLayout(hBoxTag) self.flowLayout.addWidget(tagWidget)
def __init__(self): global serialPort, baud, fmt self.serialLogState = False self.fmts = ['bin', 'oct', 'dec', 'hex', 'csv', 'csv+', 'ascii'] self.baudList = [ 4800, 7200, 9600, 14400, 19200, 28800, 38400, 57600, 76800, 115200, 230400, 460800, 921600, 1000000, 2000000, 4000000 ] fmt = self.fmts.index(fmt) super().__init__() layoutA = QHBoxLayout() self.baudBox = QComboBox() self.getBaud() layoutA.addWidget(self.baudBox) self.formatBox = QComboBox() self.getFormat() layoutA.addWidget(self.formatBox) layoutB = QHBoxLayout() self.portBox = QComboBox() self.getPorts() layoutB.addWidget(self.portBox) parentLayout = QVBoxLayout() parentLayout.addLayout(layoutB) parentLayout.addLayout(layoutA) self.setLayout(parentLayout) self.portBox.currentTextChanged.connect(self.portSelected) self.portBox.setCurrentIndex(len(self.ports) - 1) self.baudBox.currentTextChanged.connect(self.baudSelected) try: self.baudBox.setCurrentIndex(self.baudList.index(baud)) except: self.baudBox.setCurrentIndex(-1) self.formatBox.currentTextChanged.connect(self.formatSelected) self.formatBox.setCurrentIndex(fmt) self.button1 = QPushButton() self.button1.setText("start") self.button1.released.connect(self.btn1Clicked) layoutA.addWidget(self.button1)
def __init__(self): app = QApplication(sys.argv) super().__init__() self.setWindowTitle('PyQt6 simple button example') self.setGeometry(100, 100, 360, 140) button = QPushButton('PyQt6 Push Button', self) button.setToolTip('Click button to change window status message.') # # Not too sure about setting the fixed size of the button. # But I did that to keep the button from stretching across the width of # the window. Must be a way to have the button fit the size of it's text. # button.clicked.connect(self.on_click) button.setFixedSize(150, 30) widget = QWidget() layout = QHBoxLayout(widget) layout.addWidget(button) self.setCentralWidget(widget) self.statusBar().showMessage('Operational') self.show() sys.exit(app.exec())
def __init__(self): app = QApplication(sys.argv) super().__init__() self.setWindowTitle('PyQt6 Message Box') self.setGeometry(100, 100, 320, 200) # # Create a button that when clicked will pop up our dialog. # Connect our function on_click so that it is called when # the button is clicked. # button = QPushButton('Click to Open Message Box', self) button.setToolTip('This opens an example message box') button.clicked.connect(self.on_click) # # Add the button to the center of our simple window. # widget = QWidget() layout = QHBoxLayout(widget) layout.addWidget(button) self.setCentralWidget(widget) self.show() sys.exit(app.exec())
def createCheckBox(self): hboxLayout = QHBoxLayout() self.checkBox1.toggled.connect(self.onCheckBox_Toggled) hboxLayout.addWidget(self.checkBox1) self.checkBox2.toggled.connect(self.onCheckBox_Toggled) hboxLayout.addWidget(self.checkBox2) self.checkBox3.toggled.connect(self.onCheckBox_Toggled) hboxLayout.addWidget(self.checkBox3) self.groupBox.setLayout(hboxLayout)
def radioButton(self): hbox = QHBoxLayout() self.radiobtn1.setChecked(True) self.radiobtn1.toggled.connect(self.OnRadioButton) hbox.addWidget(self.radiobtn1) self.radiobtn2.setChecked(False) self.radiobtn2.toggled.connect(self.OnRadioButton) hbox.addWidget(self.radiobtn2) self.radiobtn3.setChecked(False) self.radiobtn2.toggled.connect(self.OnRadioButton) hbox.addWidget(self.radiobtn3) self.groupBox.setLayout(hbox)
def init_ui(self): layout = QHBoxLayout() self.setLayout(layout) self.ports_list_combobox = QComboBox() layout.addWidget(self.ports_list_combobox) self.baud_rate_combobox = QComboBox() self.baud_rate_combobox.addItems([ '300', '600', '1200', '2400', '4800', '9600', '19200', '38400', '43000', '56000', '57600', '115200' ]) self.baud_rate_combobox.setCurrentText('115200') self.baud_rate_combobox.setEditable(True) layout.addWidget(self.baud_rate_combobox) self.open_btn = QPushButton('打开') self.open_btn.clicked.connect(self.handle_open_port) layout.addWidget(self.open_btn) self.refresh_btn = QPushButton('刷新') self.refresh_btn.clicked.connect(self.add_ports) layout.addWidget(self.refresh_btn)
def __init__( self, minimum: XY, maximum: XY, initialValue: XY, parent: Optional[QWidget] = None, label: str = "by", *args: Tuple[Any, Any], **kwargs: Tuple[Any, Any], ) -> None: """ A horizontal dual spin box widget designed for the XY size of a maze. """ valid = True if (initialValue.x < minimum.x) or (initialValue.y > maximum.y): valid = False elif (initialValue.x < minimum.x) or (initialValue.y > maximum.y): valid = False if not valid: raise ValueError( f"Initial value for XYPicker must be between {minimum} and {maximum}." ) super(XYPicker, self).__init__(parent=parent, *args, **kwargs) self.setContentsMargins(0, 0, 0, 0) mazeSizePickerLayout = QHBoxLayout() mazeSizePickerLayout.setContentsMargins(0, 0, 0, 0) self.__xSpinBox = QSpinBox() self.__ySpinBox = QSpinBox() self.__xSpinBox.setMinimum(minimum.x) self.__ySpinBox.setMinimum(minimum.y) self.__xSpinBox.setMaximum(maximum.x) self.__ySpinBox.setMaximum(maximum.y) self.__xSpinBox.setValue(initialValue.x) self.__ySpinBox.setValue(initialValue.y) mazeSizePickerLayout.addWidget(self.__xSpinBox) mazeSizePickerLayout.addWidget(QLabel(label)) mazeSizePickerLayout.addWidget(self.__ySpinBox) self.setLayout(mazeSizePickerLayout)
def CreateHorizontalLayout(self): self.horizontalGroupBox = QGroupBox("What is your favorite color?") layout = QHBoxLayout() buttonBlue = QPushButton('Blue', self) buttonBlue.clicked.connect(lambda: self.on_click(buttonBlue)) layout.addWidget(buttonBlue) buttonRed = QPushButton('Red', self) buttonRed.clicked.connect(lambda: self.on_click(buttonRed)) layout.addWidget(buttonRed) buttonGreen = QPushButton('Green', self) buttonGreen.clicked.connect(lambda: self.on_click(buttonGreen)) layout.addWidget(buttonGreen) self.horizontalGroupBox.setLayout(layout)
def initUI(self): self.setWindowTitle("合并文件") self.setWindowIcon(QIcon(SRC_DIR + "upload.ico")) self.logo = QLabel() self.logo.setPixmap(QPixmap(SRC_DIR + "logo3.gif")) self.logo.setStyleSheet("background-color:rgb(0,153,255);") self.logo.setAlignment(Qt.AlignmentFlag.AlignCenter) # lable self.choose_lb = QLabel("选择文件夹") # folder self.choose_folder = MyLineEdit(self) self.choose_folder.setObjectName("choose_folder") self.choose_folder.clicked.connect(self.slot_choose_folder) self.status = QLabel(self) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Orientation.Horizontal) self.buttonBox.setStandardButtons( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setText("提取") self.buttonBox.button( QDialogButtonBox.StandardButton.Cancel).setText("关闭") self.buttonBox.setStyleSheet(btn_style) vbox = QVBoxLayout() hbox_head = QHBoxLayout() hbox_button = QHBoxLayout() hbox_head.addWidget(self.choose_lb) hbox_head.addWidget(self.choose_folder) hbox_button.addWidget(self.buttonBox) vbox.addWidget(self.logo) vbox.addStretch(1) vbox.addWidget(self.status) vbox.addLayout(hbox_head) vbox.addStretch(1) vbox.addLayout(hbox_button) self.setLayout(vbox) self.setMinimumWidth(350) # 设置信号 self.buttonBox.accepted.connect(self.slot_btn_ok) self.buttonBox.rejected.connect(self.slot_btn_no) self.buttonBox.rejected.connect(self.reject)
def initUI(self): self.setWindowTitle(self.title) self.setMinimumHeight(self.height) self.setMinimumWidth(self.width) bar = self.menuBar() about = bar.addMenu("About") config = bar.addMenu("Configuration") info = QAction("App Information", self) about.triggered[QAction].connect(self.aboutThis) about.addAction(info) configAction = QAction("System configuration", self) config.triggered[QAction].connect(self.configWindow) config.addAction(configAction) self.setGeometry(self.left, self.top, self.width, self.height) self.setCentralWidget(self.table_widget) widget = QWidget() container = QHBoxLayout() icon = self.style().standardIcon( QStyle.StandardPixmap.SP_MessageBoxInformation) self.iconLabel.setPixmap(icon.pixmap(QSize(16, 16))) self.restartProcessButton.clicked.connect(self.restartProcess) container.setSpacing(5) container.addWidget(self.iconLabel) container.addWidget(self.informationLabel) if self.classifyExercises is None: self.informationLabel.setText( 'Myo Connect is not running!Please start process.') container.addWidget(self.restartProcessButton) widget.setLayout(container) self.statusBar.addWidget(widget) self.setStatusBar(self.statusBar) self.show()
def displayFilesDock(self): """Dock widget that displays the movie file location in a QLineEdit widget, provides a button for opening directories with images and GIFs, and shows the media from the selected folder in a QTreeWidget.""" self.files_dock = QDockWidget() self.files_dock.setWindowTitle("Media Folder") self.files_dock.setAllowedAreas(Qt.DockWidgetArea.LeftDockWidgetArea) folder_label = QLabel("Media Location:") # The QLineEdit widget is set to read-only as a quick way to display # the folder path self.folder_line = QLineEdit() self.folder_line.setMinimumWidth(100) self.folder_line.setReadOnly(True) open_button = QPushButton("Open...") open_button.clicked.connect(self.openDirectory) folder_h_box = QHBoxLayout() folder_h_box.addWidget(folder_label) folder_h_box.addWidget(self.folder_line) folder_h_box.addWidget(open_button) self.files_tree = QTreeWidget() self.files_tree.setHeaderLabel("Media Files") self.files_tree.setColumnCount(1) # Set up the dock's layout dock_v_box = QVBoxLayout() dock_v_box.addLayout(folder_h_box) dock_v_box.addWidget(self.files_tree) dock_container = QWidget() dock_container.setLayout(dock_v_box) self.files_dock.setWidget(dock_container) self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, self.files_dock)
def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) # region Create CartPole instance and load initial settings # Create CartPole instance self.initial_state = create_cartpole_state() self.CartPoleInstance = CartPole(initial_state=self.initial_state) # Set timescales self.CartPoleInstance.dt_simulation = dt_simulation self.CartPoleInstance.dt_controller = controller_update_interval self.CartPoleInstance.dt_save = save_interval # set other settings self.CartPoleInstance.set_controller(controller_init) self.CartPoleInstance.stop_at_90 = stop_at_90_init self.set_random_experiment_generator_init_params() # endregion # region Decide whether to save the data in "CartPole memory" or not self.save_history = save_history_init self.show_experiment_summary = show_experiment_summary_init if self.save_history or self.show_experiment_summary: self.CartPoleInstance.save_data_in_cart = True else: self.CartPoleInstance.save_data_in_cart = False # endregion # region Other variables initial values as provided in gui_default_parameters.py # Start user controlled experiment/ start random experiment/ load and replay - on start button self.simulator_mode = simulator_mode_init self.slider_on_click = slider_on_click_init # Update slider on click/update slider while hoovering over it self.speedup = speedup_init # Default simulation speed-up # endregion # region Initialize loop-timer # This timer allows to relate the simulation time to user time # And (if your computer is fast enough) run simulation # slower or faster than real-time by predefined factor (speedup) self.looper = loop_timer( dt_target=(self.CartPoleInstance.dt_simulation / self.speedup)) # endregion # region Variables controlling the state of various processes (DO NOT MODIFY) self.terminate_experiment_or_replay_thread = False # True: gives signal causing thread to terminate self.pause_experiment_or_replay_thread = False # True: gives signal causing the thread to pause self.run_set_labels_thread = True # True if gauges (labels) keep being repeatedly updated # Stop threads by setting False # Flag indicating if the "START! / STOP!" button should act as start or as stop when pressed. # Can take values "START!" or "STOP!" self.start_or_stop_action = "START!" # Flag indicating whether the pause button should pause or unpause. self.pause_or_unpause_action = "PAUSE" # Flag indicating that saving of experiment recording to csv file has finished self.experiment_or_replay_thread_terminated = False self.user_time_counter = 0 # Measures the user time # Slider instant value (which is draw in GUI) differs from value saved in CartPole instance # if the option updating slider "on-click" is enabled. self.slider_instant_value = self.CartPoleInstance.slider_value self.noise = 'OFF' self.CartPoleInstance.NoiseAdderInstance.noise_mode = self.noise # endregion # region Create GUI Layout # region - Create container for top level layout layout = QVBoxLayout() # endregion # region - Change geometry of the main window self.setGeometry(300, 300, 2500, 1000) # endregion # region - Matplotlib figures (CartPole drawing and Slider) # Draw Figure self.fig = Figure( figsize=(25, 10) ) # Regulates the size of Figure in inches, before scaling to window size. self.canvas = FigureCanvas(self.fig) self.fig.AxCart = self.canvas.figure.add_subplot(211) self.fig.AxSlider = self.canvas.figure.add_subplot(212) self.fig.AxSlider.set_ylim(0, 1) self.CartPoleInstance.draw_constant_elements(self.fig, self.fig.AxCart, self.fig.AxSlider) # Attach figure to the layout lf = QVBoxLayout() lf.addWidget(self.canvas) # endregion # region - Radio buttons selecting current controller self.rbs_controllers = [] for controller_name in self.CartPoleInstance.controller_names: self.rbs_controllers.append(QRadioButton(controller_name)) # Ensures that radio buttons are exclusive self.controllers_buttons_group = QButtonGroup() for button in self.rbs_controllers: self.controllers_buttons_group.addButton(button) lr_c = QVBoxLayout() lr_c.addStretch(1) for rb in self.rbs_controllers: rb.clicked.connect(self.RadioButtons_controller_selection) lr_c.addWidget(rb) lr_c.addStretch(1) self.rbs_controllers[self.CartPoleInstance.controller_idx].setChecked( True) # endregion # region - Create central part of the layout for figures and radio buttons and add it to the whole layout lc = QHBoxLayout() lc.addLayout(lf) lc.addLayout(lr_c) layout.addLayout(lc) # endregion # region - Gauges displaying current values of various states and parameters (time, velocity, angle,...) # First row ld = QHBoxLayout() # User time self.labTime = QLabel("User's time (s): ") self.timer = QTimer() self.timer.setInterval(100) # Tick every 1/10 of the second self.timer.timeout.connect(self.set_user_time_label) self.timer.start() ld.addWidget(self.labTime) # Speed, angle, motor power (Q) self.labSpeed = QLabel('Speed (m/s):') self.labAngle = QLabel('Angle (deg):') self.labMotor = QLabel('') self.labTargetPosition = QLabel('') ld.addWidget(self.labSpeed) ld.addWidget(self.labAngle) ld.addWidget(self.labMotor) ld.addWidget(self.labTargetPosition) layout.addLayout(ld) # Second row of labels # Simulation time, Measured (real) speed-up, slider-value ld2 = QHBoxLayout() self.labTimeSim = QLabel('Simulation Time (s):') ld2.addWidget(self.labTimeSim) self.labSpeedUp = QLabel('Speed-up (measured):') ld2.addWidget(self.labSpeedUp) self.labSliderInstant = QLabel('') ld2.addWidget(self.labSliderInstant) layout.addLayout(ld2) # endregion # region - Buttons "START!" / "STOP!", "PAUSE", "QUIT" self.bss = QPushButton("START!") self.bss.pressed.connect(self.start_stop_button) self.bp = QPushButton("PAUSE") self.bp.pressed.connect(self.pause_unpause_button) bq = QPushButton("QUIT") bq.pressed.connect(self.quit_application) lspb = QHBoxLayout() # Sub-Layout for Start/Stop and Pause Buttons lspb.addWidget(self.bss) lspb.addWidget(self.bp) # endregion # region - Sliders setting initial state and buttons for kicking the pole # Sliders setting initial position and angle lb = QVBoxLayout() # Layout for buttons lb.addLayout(lspb) lb.addWidget(bq) ip = QHBoxLayout() # Layout for initial position sliders self.initial_position_slider = QSlider( orientation=Qt.Orientation.Horizontal) self.initial_position_slider.setRange( -int(float(1000 * TrackHalfLength)), int(float(1000 * TrackHalfLength))) self.initial_position_slider.setValue(0) self.initial_position_slider.setSingleStep(1) self.initial_position_slider.valueChanged.connect( self.update_initial_position) self.initial_angle_slider = QSlider( orientation=Qt.Orientation.Horizontal) self.initial_angle_slider.setRange(-int(float(100 * np.pi)), int(float(100 * np.pi))) self.initial_angle_slider.setValue(0) self.initial_angle_slider.setSingleStep(1) self.initial_angle_slider.valueChanged.connect( self.update_initial_angle) ip.addWidget(QLabel("Initial position:")) ip.addWidget(self.initial_position_slider) ip.addWidget(QLabel("Initial angle:")) ip.addWidget(self.initial_angle_slider) ip.addStretch(0.01) # Slider setting latency self.LATENCY_SLIDER_RANGE_INT = 1000 self.latency_slider = QSlider(orientation=Qt.Orientation.Horizontal) self.latency_slider.setRange(0, self.LATENCY_SLIDER_RANGE_INT) self.latency_slider.setValue( int(self.CartPoleInstance.LatencyAdderInstance.latency * self.LATENCY_SLIDER_RANGE_INT / self.CartPoleInstance.LatencyAdderInstance.max_latency)) self.latency_slider.setSingleStep(1) self.latency_slider.valueChanged.connect(self.update_latency) ip.addWidget(QLabel("Latency:")) ip.addWidget(self.latency_slider) self.labLatency = QLabel('Latency (ms): {:.1f}'.format( self.CartPoleInstance.LatencyAdderInstance.latency * 1000)) ip.addWidget(self.labLatency) # Buttons activating noise self.rbs_noise = [] for mode_name in ['ON', 'OFF']: self.rbs_noise.append(QRadioButton(mode_name)) # Ensures that radio buttons are exclusive self.noise_buttons_group = QButtonGroup() for button in self.rbs_noise: self.noise_buttons_group.addButton(button) lr_n = QHBoxLayout() lr_n.addWidget(QLabel('Noise:')) for rb in self.rbs_noise: rb.clicked.connect(self.RadioButtons_noise_on_off) lr_n.addWidget(rb) self.rbs_noise[1].setChecked(True) ip.addStretch(0.01) ip.addLayout(lr_n) ip.addStretch(0.01) # Buttons giving kick to the pole kick_label = QLabel("Kick pole:") kick_left_button = QPushButton() kick_left_button.setText("Left") kick_left_button.adjustSize() kick_left_button.clicked.connect(self.kick_pole) kick_right_button = QPushButton() kick_right_button.setText("Right") kick_right_button.adjustSize() kick_right_button.clicked.connect(self.kick_pole) ip.addWidget(kick_label) ip.addWidget(kick_left_button) ip.addWidget(kick_right_button) lb.addLayout(ip) layout.addLayout(lb) # endregion # region - Text boxes and Combobox to provide settings concerning generation of random experiment l_generate_trace = QHBoxLayout() l_generate_trace.addWidget(QLabel('Random experiment settings:')) l_generate_trace.addWidget(QLabel('Length (s):')) self.textbox_length = QLineEdit() l_generate_trace.addWidget(self.textbox_length) l_generate_trace.addWidget(QLabel('Turning Points (m):')) self.textbox_turning_points = QLineEdit() l_generate_trace.addWidget(self.textbox_turning_points) l_generate_trace.addWidget(QLabel('Interpolation:')) self.cb_interpolation = QComboBox() self.cb_interpolation.addItems( ['0-derivative-smooth', 'linear', 'previous']) self.cb_interpolation.currentIndexChanged.connect( self.cb_interpolation_selectionchange) self.cb_interpolation.setCurrentText( self.CartPoleInstance.interpolation_type) l_generate_trace.addWidget(self.cb_interpolation) layout.addLayout(l_generate_trace) # endregion # region - Textbox to provide csv file name for saving or loading data l_text = QHBoxLayout() textbox_title = QLabel('CSV file name:') self.textbox = QLineEdit() l_text.addWidget(textbox_title) l_text.addWidget(self.textbox) layout.addLayout(l_text) # endregion # region - Make strip of layout for checkboxes l_cb = QHBoxLayout() # endregion # region - Textbox to provide the target speed-up value l_text_speedup = QHBoxLayout() tx_speedup_title = QLabel('Speed-up (target):') self.tx_speedup = QLineEdit() l_text_speedup.addWidget(tx_speedup_title) l_text_speedup.addWidget(self.tx_speedup) self.tx_speedup.setText(str(self.speedup)) l_cb.addLayout(l_text_speedup) self.wrong_speedup_msg = QMessageBox() self.wrong_speedup_msg.setWindowTitle("Speed-up value problem") self.wrong_speedup_msg.setIcon(QMessageBox.Icon.Critical) # endregion # region - Checkboxes # region -- Checkbox: Save/don't save experiment recording self.cb_save_history = QCheckBox('Save results', self) if self.save_history: self.cb_save_history.toggle() self.cb_save_history.toggled.connect(self.cb_save_history_f) l_cb.addWidget(self.cb_save_history) # endregion # region -- Checkbox: Display plots showing dynamic evolution of the system as soon as experiment terminates self.cb_show_experiment_summary = QCheckBox('Show experiment summary', self) if self.show_experiment_summary: self.cb_show_experiment_summary.toggle() self.cb_show_experiment_summary.toggled.connect( self.cb_show_experiment_summary_f) l_cb.addWidget(self.cb_show_experiment_summary) # endregion # region -- Checkbox: Block pole if it reaches +/-90 deg self.cb_stop_at_90_deg = QCheckBox('Stop-at-90-deg', self) if self.CartPoleInstance.stop_at_90: self.cb_stop_at_90_deg.toggle() self.cb_stop_at_90_deg.toggled.connect(self.cb_stop_at_90_deg_f) l_cb.addWidget(self.cb_stop_at_90_deg) # endregion # region -- Checkbox: Update slider on click/update slider while hoovering over it self.cb_slider_on_click = QCheckBox('Update slider on click', self) if self.slider_on_click: self.cb_slider_on_click.toggle() self.cb_slider_on_click.toggled.connect(self.cb_slider_on_click_f) l_cb.addWidget(self.cb_slider_on_click) # endregion # endregion # region - Radio buttons selecting simulator mode: user defined experiment, random experiment, replay # List available simulator modes - constant self.available_simulator_modes = [ 'Slider-Controlled Experiment', 'Random Experiment', 'Replay' ] self.rbs_simulator_mode = [] for mode_name in self.available_simulator_modes: self.rbs_simulator_mode.append(QRadioButton(mode_name)) # Ensures that radio buttons are exclusive self.simulator_mode_buttons_group = QButtonGroup() for button in self.rbs_simulator_mode: self.simulator_mode_buttons_group.addButton(button) lr_sm = QHBoxLayout() lr_sm.addStretch(1) lr_sm.addWidget(QLabel('Simulator mode:')) for rb in self.rbs_simulator_mode: rb.clicked.connect(self.RadioButtons_simulator_mode) lr_sm.addWidget(rb) lr_sm.addStretch(1) self.rbs_simulator_mode[self.available_simulator_modes.index( self.simulator_mode)].setChecked(True) l_cb.addStretch(1) l_cb.addLayout(lr_sm) l_cb.addStretch(1) # endregion # region - Add checkboxes to layout layout.addLayout(l_cb) # endregion # region - Create an instance of a GUI window w = QWidget() w.setLayout(layout) self.setCentralWidget(w) self.show() self.setWindowTitle('CartPole Simulator') # endregion # endregion # region Open controller-specific popup windows self.open_additional_controller_widget() # endregion # region Activate functions capturing mouse movements and clicks over the slider # This line links function capturing the mouse position on the canvas of the Figure self.canvas.mpl_connect("motion_notify_event", self.on_mouse_movement) # This line links function capturing the mouse position on the canvas of the Figure click self.canvas.mpl_connect("button_press_event", self.on_mouse_click) # endregion # region Introducing multithreading # To ensure smooth functioning of the app, # the calculations and redrawing of the figures have to be done in a different thread # than the one capturing the mouse position and running the animation self.threadpool = QThreadPool() # endregion # region Starts a thread repeatedly redrawing gauges (labels) of the GUI # It runs till the QUIT button is pressed worker_labels = Worker(self.set_labels_thread) self.threadpool.start(worker_labels) # endregion # region Start animation repeatedly redrawing changing elements of matplotlib figures (CartPole drawing and slider) # This animation runs ALWAYS when the GUI is open # The buttons of GUI only decide if new parameters are calculated or not self.anim = self.CartPoleInstance.run_animation(self.fig)
class Window(QMainWindow): def __init__(self): super().__init__() self.width = 500 self.height = 500 self.xPos = 600 self.yPos = 400 self.initUI() def initUI(self): self.setGeometry(self.xPos, self.yPos, self.width, self.height) self.vBoxLayout = QVBoxLayout() self.slider = Slider( direction=Qt.Orientation.Horizontal, duration=750, animationType=QEasingCurve.Type.OutQuad, wrap=False, ) self.label1 = QLabel() self.label1.setText('First Slide') self.label1.setAlignment(Qt.AlignmentFlag.AlignCenter) self.label1.setStyleSheet( 'QLabel{background-color: rgb(245, 177, 66); color: rgb(21, 21, 21); font: 25pt;}' ) self.slider.addWidget(self.label1) self.label2 = QLabel() self.label2.setText('Second Slide') self.label2.setAlignment(Qt.AlignmentFlag.AlignCenter) self.label2.setStyleSheet( 'QLabel{background-color: rgb(21, 21, 21); color: rgb(245, 177, 66); font: 25pt;}' ) self.slider.addWidget(self.label2) self.label3 = QLabel() self.label3.setText('Third Slide') self.label3.setAlignment(Qt.AlignmentFlag.AlignCenter) self.label3.setStyleSheet( 'QLabel{background-color: rgb(93, 132, 48); color: rgb(245, 177, 66); font: 25pt;}' ) self.slider.addWidget(self.label3) self.buttonPrevious = QPushButton() self.buttonPrevious.setText('Previous Slide') self.buttonPrevious.clicked.connect(self.slider.slidePrevious) self.buttonNext = QPushButton() self.buttonNext.setText('Next Slide') self.buttonNext.clicked.connect(self.slider.slideNext) self.buttonLayout = QHBoxLayout() self.buttonLayout.addWidget(self.buttonPrevious) self.buttonLayout.addWidget(self.buttonNext) self.vBoxLayout.addWidget(self.slider) self.vBoxLayout.addLayout(self.buttonLayout) self.centralWidget = QWidget(self) self.centralWidget.setLayout(self.vBoxLayout) self.setCentralWidget(self.centralWidget) self.show()
class Window(QMainWindow): """ Main Window.""" def __init__(self, parent=None): """Initializer.""" super().__init__(parent) self.setWindowTitle("RP Contacts") self.resize(550, 250) self.centralWidget = QWidget() self.setCentralWidget(self.centralWidget) self.layout = QHBoxLayout() self.centralWidget.setLayout(self.layout) self.ContactsModel = ContactsModel() self.setupUI() def setupUI(self): """Setup the main window's GUI.""" # Create the table view widget self.table = QTableView() self.table.setModel(self.contactsModel.model) self.table.setSelectionBehavior(QAbstractItemView.SelectRows) self.table.resizeColumnsToContents() # Create buttons self.addButton = QPushButton("Add...") self.addButton.clicked.connect(self.openAddDialog) self.deleteButton = QPushButton("Delete") self.deleteButton.clicked.connect(self.deleteContact) self.clearAllButton = QPushButton("Clear All") self.clearAllButton.clicked.connect(self.clearContacts) # Lay out the GUI layout = QVBoxLayout() layout.addWidget(self.addButton) layout.addWidget(self.deleteButton) layout.addStretch() layout.addWidget(self.clearAllButton) self.layout.addWidget(self.table) self.layout.addLayout(layout) def openAddDialog(self): """Open the Add Contact dialog.""" dialog = AddDialog(self) if dialog.exec() == QDialog.Accepted: self.ContactsModel.addContact(dialog.data) self.table.resizeColumnsToContents() def deleteContact(self): row = self.table.currentIndex().row() if row < 0: return messageBox = QMessageBox.warning( self, "Warning!", "Do you want to remove the selected contact?", QMessageBox.Ok | QMessageBox.Cancel, ) if messageBox == QMessageBox.Ok: self.contactsModel.deleteContact(row) def clearContacts(self): """Remove all contacts from the database.""" messageBox = QMessageBox.warning( self, "Warning!", "Do you want to remove all your contacts?" QMessageBox.Ok | QMessageBox.Cancel, )
def setUpMainWindow(self): """Create and arrange widgets in the main window.""" # Create the container widget for each of the pages # in the tab widget self.customer_tab = QWidget() self.orders_tab = QWidget() self.category_tab = QWidget() self.products_tab = QWidget() # Add or insert the tabs into the tab widget self.tabs = QTabWidget() self.tabs.setDocumentMode(True) self.tabs.addTab(self.customer_tab, "Customers") self.tabs.addTab(self.orders_tab, "Orders") self.tabs.addTab(self.category_tab, "Categories") self.tabs.addTab(self.products_tab, "Products") if self.admin_or_not == 1: self.staff_tab = QWidget() self.tabs.insertTab(0, self.staff_tab, "Staff") self.createStaffTab() self.tabs.setCurrentIndex(1) # Set tab to Customers tab self.tabs.currentChanged.connect(self.updateWidgetsAndStates) # Call the methods to construct each page self.createCustomersTab() self.createOrdersTab() self.createCategoriesTab() self.createProductsTab() # Create the widgets in the sidebar for filtering table content self.table_name_label = QLabel("<b>Customers</b>") self.table_name_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.filter_pattern_line = QLineEdit() self.filter_pattern_line.setClearButtonEnabled(True) self.filter_pattern_line.textChanged.connect(self.filterRegExpChanged) self.filter_regex_combo = QComboBox() filter_options = ["Default", "Wildcard", "Fixed String"] self.filter_regex_combo.addItems(filter_options) self.filter_regex_combo.currentIndexChanged.connect( self.filterRegExpChanged) self.filter_field_combo = QComboBox() self.updateWidgetsAndStates( 1) # Initialize the values in filter_field_combo self.filter_field_combo.currentIndexChanged.connect( self.selectTableColumn) filter_case_sensitivity_cb = QCheckBox("Filter with Case Sensitivity") filter_case_sensitivity_cb.toggled.connect(self.toggleCaseSensitivity) filter_case_sensitivity_cb.toggle() # Layout for the sidebar filter_v_box = QVBoxLayout() filter_v_box.addWidget(self.table_name_label) filter_v_box.addWidget(QLabel("Filter Pattern")) filter_v_box.addWidget(self.filter_pattern_line) filter_v_box.addWidget(QLabel("Filter filter")) filter_v_box.addWidget(self.filter_regex_combo) filter_v_box.addWidget(QLabel("Select Table Column")) filter_v_box.addWidget(self.filter_field_combo) filter_v_box.addWidget(filter_case_sensitivity_cb) filter_v_box.addStretch(2) self.filter_group = QGroupBox("Filtering") self.filter_group.setMaximumWidth(260) self.filter_group.setLayout(filter_v_box) # Arrange the containers in the main window main_h_box = QHBoxLayout() main_h_box.addWidget(self.tabs) main_h_box.addWidget(self.filter_group) main_container = QWidget() main_container.setLayout(main_h_box) self.setCentralWidget(main_container) # Create status bar self.setStatusBar(QStatusBar())
def __init__(self): super().__init__() self.logger = logging.getLogger(__name__) formatter = logging.Formatter( fmt="%(asctime)s-%(levelname)s-%(message)s", datefmt="%Y-%m-%d %H:%M:%S") filehandler = logging.FileHandler(filename="logs.log", mode="w", encoding="utf-8") handler = QLogger(update_signal=self.update_signal) handler.setLevel(logging.INFO) filehandler.setLevel(logging.INFO) self.logger.setLevel(logging.INFO) if os.path.exists("config.json") == False: self.gen_conf() with open(file="config.json", mode="r", encoding="utf-8") as conf_reader: conf = json.loads(conf_reader.read()) debug = bool(conf["debug"]) if debug == True: handler.setLevel(logging.DEBUG) filehandler.setLevel(logging.DEBUG) self.logger.setLevel(logging.DEBUG) handler.setFormatter(formatter) filehandler.setFormatter(formatter) self.logger.addHandler(handler) self.logger.addHandler(filehandler) self.logger.debug("当前调试状态:%s" % debug) self.resize(1024, 768) self.setWindowOpacity(0.9) self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) self.setWindowFlag(Qt.WindowFlags.FramelessWindowHint) self.setAutoFillBackground(True) self.work = Work(show_qr_signal=self.show_qr_signal, finish_signal=self.finish_signal, close_qr_signal=self.close_qr_signal) self.work_thread = QThread() self.work.moveToThread(self.work_thread) self.main_layout = QGridLayout() self.setLayout(self.main_layout) self.title = QLabel("ChinaUniOnlineGUI") self.title.setStyleSheet( "QLabel{border:none;border-radius:5px;background:transparent;color:#9AD3BC;font-size:60px;}" ) self.title.setAlignment(Qt.Alignment.AlignCenter) handler.widget.setStyleSheet( "QPlainTextEdit{font-family:Microsoft YaHei;background:#F3EAC2;border:none;border-radius:5px;}QScrollBar:vertical,QScrollBar::handle:vertical{background:#F3EAC2;border:none;border-radius:8px;width:16px;}QScrollBar::handle:vertical:hover{background:#F5B461;}QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical{background:#FFFDF9;border:none;border-radius:8px;width:16px;}QScrollBar::down-arrow:vertical,QScrollBar::up-arrow:vertical{background:#F5B461;border:none;border-radius:8px;width:16px;height:16px;}QScrollBar::sub-line:vertical,QScrollBar::add-line:vertical{background:transparent;border:none;}" ) self.control = QVBoxLayout() self.control_close = QPushButton() self.control_close.setToolTip("关闭") self.control_close.setStyleSheet( "QPushButton{background:#FFE3ED;border-radius:5px;border:none;}QPushButton:hover{background:#EC524B;}" ) self.contron_max = QPushButton() if self.isMaximized() == False: self.contron_max.setToolTip("最大化") else: self.contron_max.setToolTip("还原") self.contron_max.setStyleSheet( "QPushButton{background:#FFFDF9;border-radius:5px;border:none;}QPushButton:hover{background:#F5B461;}" ) self.control_min = QPushButton() self.control_min.setToolTip("最小化") self.control_min.setStyleSheet( "QPushButton{background:#BEEBE9;border-radius:5px;border:none;}QPushButton:hover{background:#F3EAC2;}" ) self.start_button = QPushButton("开始(&S)") self.start_button.setStyleSheet( "QPushButton{background:#9BE3DE;border:none;border-radius:5px;font-size:20px;font-family:DengXian;}QPushButton:hover{background:#9AD3BC;}" ) self.start_button.setToolTip("开始") self.start_button.setFixedSize(120, 60) self.start_button.setDefault(True) setting_button = QPushButton("设置") setting_button.setToolTip("设置") setting_button.setFixedSize(60, 60) setting_button.setStyleSheet( "QPushButton{background:#9BE3DE;border:none;border-radius:5px;font-size:20px;font-family:DengXian;}QPushButton:hover{background:#9AD3BC;}" ) setting_button.clicked.connect(self.setting_callback) start = QHBoxLayout() start.addWidget(self.start_button, 2) start.addWidget(setting_button, 1) self.control_close.clicked.connect(self.close) self.control_min.clicked.connect(self.min_callback) self.contron_max.clicked.connect(self.max_callback) self.start_button.clicked.connect(self.start_callback) self.work_thread.started.connect(self.work.start) self.finish_signal.connect(self.finish_callback) self.close_qr_signal.connect(self.close_qr) self.control.addWidget(self.control_min) self.control.addWidget(self.contron_max) self.control.addWidget(self.control_close) self.main_layout.addLayout(self.control, 0, 0) self.main_layout.addWidget(self.title, 0, 1) self.main_layout.addLayout(start, 0, 2) self.main_layout.addWidget(handler.widget, 1, 1) self.update_signal.connect(handler.widget.appendPlainText) handler.widget.textChanged.connect(handler.scroll_widget_to_bottom) self.show_qr_signal.connect(self.show_qr) self.logger.debug("已初始化UI")