Exemplo n.º 1
0
 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)
Exemplo n.º 3
0
    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)
Exemplo n.º 5
0
    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()
Exemplo n.º 6
0
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)
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
    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)
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
    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)
Exemplo n.º 14
0
    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)
Exemplo n.º 15
0
    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)
Exemplo n.º 16
0
    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())
Exemplo n.º 17
0
    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())
Exemplo n.º 18
0
    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)
Exemplo n.º 19
0
    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)
Exemplo n.º 20
0
    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)
Exemplo n.º 21
0
    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)
Exemplo n.º 22
0
    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)
Exemplo n.º 23
0
    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)
Exemplo n.º 24
0
    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()
Exemplo n.º 25
0
    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)
Exemplo n.º 27
0
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()
Exemplo n.º 28
0
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,
        )
Exemplo n.º 29
0
    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())
Exemplo n.º 30
0
 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")