class LayersList(QWidget):
    '''
    LayerList class which acts as collapsable list.
    '''
    def __init__(self, name, layers, filter, expand=True):
        super().__init__()
        self.setWindowModality(QtCore.Qt.WindowModal)
        self.currently_expanded = True
        self.main_layout = QVBoxLayout()
        self.main_layout.setMargin(0)
        self.main_layout.setSpacing(0)
        self.main_layout.setContentsMargins(0, 0, 0, 0)

        self.expand_button = QPushButton(name)
        self.expand_button.setToolTip(f"List of {name} Layers")
        self.expand_button.setIcon(
            QIcon(os.path.join(PATH, 'LayersList_Down.png')))

        self.layer_list = QListView()
        self.layer_list.setDragEnabled(True)
        self.layer_list.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.layer_list.setWrapping(False)
        self.layer_list.setViewMode(self.layer_list.ListMode)

        self.container_model = QStandardItemModel()
        self.model = QSortFilterProxyModel()
        self.model.setSourceModel(self.container_model)
        self.model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        #self.model.cas
        filter.textChanged.connect(self.filter_model)

        for l in layers:
            self.container_model.appendRow(
                QStandardItem(
                    QIcon(os.path.join(PATH, 'LayersList_Layer_Icon.png')), l))

        self.layer_list.setModel(self.model)

        self.main_layout.addWidget(self.expand_button, 0, Qt.AlignTop)
        self.main_layout.addWidget(self.layer_list, 0, Qt.AlignTop)
        self.expand_button.clicked.connect(self.expand)

        self.setLayout(self.main_layout)
        self.resized_size = len(layers) * (self.layer_list.sizeHintForRow(0) +
                                           self.layer_list.frameWidth())

        self.layer_list.setMaximumHeight(self.resized_size)
        self.layer_list.setMinimumHeight(self.resized_size)

        self.setMinimumWidth(self.layer_list.frameWidth())

        self.set_styling()

        if not expand:
            self.expand()

    @QtCore.Slot()
    def expand(self):
        if self.currently_expanded:
            self.layer_list.setMinimumHeight(0)
            self.currently_expanded = False
            self.expand_button.setIcon(
                QIcon(os.path.join(PATH, 'LayersList_Up2.png')))
            self.layer_list.setMaximumHeight(0)
        else:
            self.layer_list.setMinimumHeight(self.resized_size)
            self.currently_expanded = True
            self.expand_button.setIcon(
                QIcon(os.path.join(PATH, 'LayersList_Down.png')))
            self.layer_list.setMaximumHeight(self.resized_size)

    def set_styling(self):
        self.setStyleSheet('''
                           background-color:white;
                           ''')
        self.expand_button.setStyleSheet('''
                                        background-color:#d6d2d2;
                                        text-align:left;
                                        ''')

    @QtCore.Slot()
    def filter_model(self, text):
        self.show()
        self.model.setFilterRegExp(QRegExp(text, QtCore.Qt.CaseInsensitive))
        if not self.currently_expanded:
            self.expand()
        if self.model.rowCount() == 0:
            self.hide()
Ejemplo n.º 2
0
    def _create_reg(self, width, cmp_switches, ign_switches):
        # Create a widget to hold the register's bits
        reg_widget = QWidget(self)
        reg_layout = QVBoxLayout(reg_widget)
        reg_widget.setLayout(reg_layout)
        reg_layout.setSpacing(0)
        reg_layout.setMargin(0)

        # Create a widget to hold the register's value and ignore textboxes
        values = QWidget(reg_widget)
        v_layout = QHBoxLayout(values)
        values.setLayout(v_layout)
        v_layout.setSpacing(1)
        v_layout.setMargin(0)
        reg_layout.addWidget(values)
        reg_layout.setAlignment(values, Qt.AlignRight)

        # Create textboxes to show the register's value and ignore mask in octal
        n_digits = int((width + 2) / 3)
        if n_digits == 1:
            value_width = 25
        elif n_digits == 2:
            value_width = 30
        else:
            value_width = 45

        reg_value = QLineEdit(values)
        reg_value.setMaximumSize(value_width, 32)
        reg_value.setText(n_digits * '0')
        reg_value.setAlignment(Qt.AlignCenter)
        reg_value.setValidator(RegValidator(2**width - 1))
        reg_value.setMaxLength(n_digits)
        reg_value.returnPressed.connect(
            lambda b=reg_value, s=cmp_switches: self._update_switches(b, s))
        v_layout.addWidget(reg_value)

        ign_value = QLineEdit(values)
        ign_value.setMaximumSize(value_width, 32)
        ign_value.setText(n_digits * '0')
        ign_value.setAlignment(Qt.AlignCenter)
        ign_value.setValidator(RegValidator(2**width - 1))
        ign_value.setMaxLength(n_digits)
        ign_value.returnPressed.connect(
            lambda b=ign_value, s=ign_switches: self._update_switches(b, s))
        v_layout.addWidget(ign_value)

        font = QFont('Monospace')
        font.setStyleHint(QFont.TypeWriter)
        font.setPointSize(10)
        reg_value.setFont(font)
        ign_value.setFont(font)

        # Create a frame to hold the register's bits
        bit_frame = QFrame(reg_widget)
        bit_layout = QGridLayout(bit_frame)
        bit_layout.setSpacing(1)
        bit_layout.setMargin(0)
        bit_frame.setLayout(bit_layout)
        bit_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)

        # Add indicators for each bit in the register, from MSB to LSB
        col = 0
        for i in range(width, 0, -1):
            check = QCheckBox(bit_frame)
            check.setFixedSize(20, 20)
            check.setStyleSheet(
                'QCheckBox::indicator{subcontrol-position:center;}')
            check.stateChanged.connect(
                lambda state, b=reg_value, s=cmp_switches: self.
                _update_reg_box(state, b, s))
            bit_layout.addWidget(check, 0, col)
            bit_layout.setAlignment(check, Qt.AlignCenter)
            cmp_switches.append(check)

            check = QCheckBox(bit_frame)
            check.setFixedSize(20, 20)
            check.setStyleSheet(
                'QCheckBox::indicator{subcontrol-position:center;}')
            check.stateChanged.connect(
                lambda state, b=ign_value, s=ign_switches: self.
                _update_reg_box(state, b, s))
            bit_layout.addWidget(check, 1, col)
            bit_layout.setAlignment(check, Qt.AlignCenter)
            ign_switches.append(check)

            col += 1

            # Add separators between each group of 3 bits
            if (i > 1) and ((i % 3) == 1):
                sep = QFrame(bit_frame)
                sep.setFrameStyle(QFrame.VLine | QFrame.Raised)
                bit_layout.addWidget(sep, 0, col, 2, 1)
                col += 1

        reg_layout.addWidget(bit_frame)

        return reg_widget, reg_value, ign_value
Ejemplo n.º 3
0
class SteamAccountSwitcherGui(QMainWindow, Accounts, DialogAccount,
                              DialogImportAccount, DialogSteamapiKey, Settings,
                              SystemTray):
    account_dialog_window: QDialog
    submit_button: QPushButton
    tray_menu: QMenu

    def __init__(self):
        QMainWindow.__init__(self)
        signal.signal(signal.SIGINT, self.exit_app)
        self.setWindowTitle("Steam Account Switcher")
        self.setMinimumSize(300, 200)
        self.resize(300, 300)

        # Logo
        self.switcher_logo = QIcon("logo.png")
        self.setWindowIcon(self.switcher_logo)
        if platform.system() == "Windows":  # windows taskbar app icon fix
            import ctypes
            win_appid = 'github.tommis.steam_account_switcher'
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
                win_appid)

        from steamswitcher import SteamSwitcher

        self.switcher = SteamSwitcher()
        self.args = self.switcher.args
        self.main_widget = QWidget()

        if self.args.gui or self.switcher.settings.get(
                "show_on_startup", True) and not self.args.no_gui:
            self.show()
        elif self.args.no_gui and self.args.no_tray:
            self.exit_app()

        self.menu_bar = self.menuBar()
        self.file_menu = self.menu_bar.addMenu(_("File"))
        self.settings_menu = self.menu_bar.addMenu(_("Settings"))
        self.size_menu = self.menu_bar.addMenu(_("Size"))

        refresh_action = QAction(_("Refresh"), self)
        import_action = QAction(_("Import accounts"), self)
        open_skinsdir_action = QAction(_("Skins dir"), self)
        about_action = QAction(_("About"), self)
        exit_action = QAction(_("Exit"), self)

        refresh_action.triggered.connect(Accounts.steamapi_refresh)
        import_action.triggered.connect(
            lambda: DialogImportAccount.import_accounts_dialog(self))
        open_skinsdir_action.triggered.connect(self.open_skinsdir)
        about_action.triggered.connect(lambda: DialogAbout.about_dialog(self))
        exit_action.triggered.connect(self.exit_app)

        refresh_action.setShortcut("F5")
        exit_action.setShortcut("Ctrl+Q")

        self.file_menu.addActions([
            refresh_action, import_action, open_skinsdir_action, about_action
        ])
        self.file_menu.addSeparator()
        self.file_menu.addAction(exit_action)

        set_steamapi_key = QAction(_("Set steamapi key"), self)
        show_avatars = QAction(_("Show avatars"), self, checkable=True)
        use_systemtray = QAction(_("Use systemtray"), self, checkable=True)

        after_login_menu = QMenu(_("After login"))

        after_login_behaviour_group = QActionGroup(after_login_menu)
        nothing_behaviour = QAction(_('Nothing'),
                                    after_login_behaviour_group,
                                    checkable=True,
                                    data="nothing")
        close_behaviour = QAction(_('Close'),
                                  after_login_behaviour_group,
                                  checkable=True,
                                  data="close")
        minimize_behaviour = QAction(_('Minimize to taskbar'),
                                     after_login_behaviour_group,
                                     checkable=True,
                                     data="minimize")
        minimize_tray_behaviour = QAction(_('Minimize to tray'),
                                          after_login_behaviour_group,
                                          checkable=True,
                                          data="minimize_tray")

        after_login_menu.addActions([
            nothing_behaviour, close_behaviour, minimize_behaviour,
            minimize_tray_behaviour
        ])

        behaviour_switcher = {
            "close": lambda: close_behaviour.setChecked(True),
            "minimize": lambda: minimize_behaviour.setChecked(True),
            "minimize_tray": lambda: minimize_tray_behaviour.setChecked(True)
        }
        behaviour_switcher.get(self.switcher.settings["behavior_after_login"],
                               lambda: nothing_behaviour.setChecked(True))()

        after_login_menu.triggered.connect(self.set_after_login_action)

        self.systemtray(self.main_widget)

        set_steamapi_key.triggered.connect(lambda: self.steamapi_key_dialog())
        show_avatars.triggered.connect(lambda: self.set_show_avatars())
        use_systemtray.triggered.connect(lambda: self.set_use_systemtray())

        self.settings_menu.addAction(set_steamapi_key)
        self.settings_menu.addSeparator()
        self.settings_menu.addActions([show_avatars, use_systemtray])
        self.settings_menu.addMenu(after_login_menu)

        show_avatars.setChecked(self.switcher.settings.get("show_avatars"))
        use_systemtray.setChecked(self.switcher.settings.get("use_systemtray"))

        set_size_small = QAction(_("Small"), self)
        set_size_medium = QAction(_("Medium"), self)
        set_size_large = QAction(_("Large"), self)
        set_size_small.triggered.connect(lambda: self.set_size("small"))
        set_size_medium.triggered.connect(lambda: self.set_size("medium"))
        set_size_large.triggered.connect(lambda: self.set_size("large"))
        self.size_menu.addActions(
            [set_size_small, set_size_medium, set_size_large])

        set_size_small.setShortcut("Ctrl+1")
        set_size_medium.setShortcut("Ctrl+2")
        set_size_large.setShortcut("Ctrl+3")

        self.add_button = QPushButton(_("Add account"))
        self.edit_button = QPushButton(_("Edit account"))
        self.edit_button.setDisabled(True)

        self.buttons = QHBoxLayout()
        self.buttons.addWidget(self.add_button)
        self.buttons.addWidget(self.edit_button)

        self.layout = QVBoxLayout()
        self.main_widget.setLayout(self.layout)

        self.accounts_list = QListWidget()
        self.accounts_list.setDragDropMode(QAbstractItemView.InternalMove)
        self.layout.addWidget(self.accounts_list)
        self.layout.addLayout(self.buttons)

        self.layout.setSpacing(10)
        self.accounts_list.setSpacing(1)

        self.import_accounts_window = QDialog()

        self.load_accounts()

        def edit_button_enabled():
            if self.accounts_list.selectedItems():
                self.edit_button.setEnabled(True)
            else:
                self.edit_button.setEnabled(False)

        # Signals and Slots
        self.add_button.clicked.connect(lambda: self.account_dialog(True))
        self.edit_button.clicked.connect(lambda: self.account_dialog(False))
        self.accounts_list.itemSelectionChanged.connect(edit_button_enabled)
        self.accounts_list.doubleClicked.connect(lambda: self.steam_login(
            self.accounts_list.currentIndex().data(5)))
        self.accounts_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.accounts_list.customContextMenuRequested.connect(
            lambda: RightClickMenu.show_rightclick_menu(self))
        #self.accounts_list.layoutChanged.connect(lambda: self.account_reordered)
        #self.accounts_list.dropEvent(self.dropEvent(QDropEvent))

        self.setCentralWidget(self.main_widget)

        if self.args.no_tray:
            print("test")
        elif self.switcher.settings.get("use_systemtray") or self.args.tray:
            self.tray_icon.show()

        if self.switcher.first_run or self.args.first_run:
            self.steamapi_key_dialog()
        elif not self.switcher.first_run and \
             not self.is_valid_steampi_key(self.switcher.settings["steam_api_key"]):
            self.tray_icon.showMessage("No api key",
                                       "Set the steam web api key.",
                                       self.switcher_logo)

    def exit_app(self):
        self.tray_icon.hide()
        QApplication.quit()

    def open_steam_profile(
        self,
        account,
    ):
        webbrowser.open(account["steam_user"].get("profileurl"))

    def open_skinsdir(self):
        if self.switcher.system_os == "Windows":
            os.startfile(self.switcher.skins_dir)
        elif self.switcher.system_os == "Linux":
            subprocess.Popen(["xdg-open", self.switcher.skins_dir])

    def dropEvent(self, event):
        print("hallo")

    def set_stay_on_top(self):
        pass
    def __init__(self):
        super(IpSubnetCalculation, self).__init__()

        # Use language settings
        self.ml = ManageLng()

        # App attributes
        self.network_ip = None
        self.needed_networks = None
        self.subnet_bits = None
        self.default_networkbits = None
        self.calculation_worker = None

        main_layout = QVBoxLayout()
        main_layout.setSpacing(10)
        main_layout.setAlignment(Qt.AlignTop)
        self.setLayout(main_layout)

        top_bar = QGridLayout()

        # Left, top, right and bottom margins
        top_bar.setContentsMargins(40, 15, 40, 15)
        top_bar.setHorizontalSpacing(40)
        main_layout.addLayout(top_bar)

        self.starting_network_address_label = QLabel(self.ml.get_tr_text("tab_ipsubnet_starting_net"))
        self.number_of_subnets_label = QLabel(self.ml.get_tr_text("tab_ipsubnet_required_subnet_num"))

        self.starting_network_address_input = QLineEdit()
        self.starting_network_address_input.returnPressed.connect(self.calculation_action)
        self.number_of_subnets_input = QLineEdit()
        self.number_of_subnets_input.returnPressed.connect(self.calculation_action)

        top_bar.addWidget(self.starting_network_address_label, 0, 0)
        top_bar.addWidget(self.starting_network_address_input, 0, 1)
        top_bar.addWidget(self.number_of_subnets_label, 1, 0)
        top_bar.addWidget(self.number_of_subnets_input, 1, 1)

        self.calculation_button = QPushButton(self.ml.get_tr_text("tab_ipsubnet_calc_btn"))
        self.calculation_button.clicked.connect(self.calculation_action)
        self.calculation_button.setIcon(QIcon("static/images/get_info.png"))
        main_layout.addWidget(self.calculation_button, alignment=Qt.AlignCenter)

        self.table = QTableWidget()
        self.table.itemDoubleClicked.connect(copy_text_action)
        self.table.setColumnCount(6)

        self.table_column_names = [self.ml.get_tr_text("table_column_network_add"),
                                   self.ml.get_tr_text("table_column_ip_range"),
                                   self.ml.get_tr_text("table_column_broadcast_add"),
                                   self.ml.get_tr_text("table_column_subnet_mask"),
                                   self.ml.get_tr_text("table_column_prefix"),
                                   self.ml.get_tr_text("table_column_addressable_host")]

        self.table.setHorizontalHeaderLabels(self.table_column_names)

        # Automatic resizing of the columns to the content
        self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch)

        # Set table text align of vertical header
        self.table.verticalHeader().setDefaultAlignment(Qt.AlignCenter)

        # Fixed height of table rows
        self.table.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)

        main_layout.addWidget(self.table)

        # Bottom bar
        bottom_bar = QHBoxLayout()

        # Create progressbar
        self.progressbar = QProgressBar()
        self.progressbar.setVisible(False)

        # Create cancel button
        self.cancel_btn = QPushButton(self.ml.get_tr_text("tab_ipsubnet_cancel_btn"))
        self.cancel_btn.setVisible(False)
        self.cancel_btn.clicked.connect(self.terminate_calculation)

        bottom_bar.addWidget(self.progressbar)
        bottom_bar.addWidget(self.cancel_btn)
        main_layout.addLayout(bottom_bar)
Ejemplo n.º 5
0
class ManuelleEingabeAufsichtsperson(QWidget):
    def __init__(self, parent, data_object: datatypes.Aufsichtsperson = None):
        super(ManuelleEingabeAufsichtsperson, self).__init__(parent)

        self.data_object = data_object

        parent.label_title.setText("Neuer Eintrag: Aufsichtsperson")

        self.layout = QVBoxLayout(self)
        self.layout_name = QHBoxLayout(self)

        self.layout.setSpacing(10)

        self.layout_name.setMargin(0)

        # create inputs
        self.input_name = new_text_input(self, "Name", "Name")
        self.input_vorname = new_text_input(self, "", "Vorname (optional)")
        self.input_kuerzel = new_text_input(self, "Namens-Kürzel",
                                            "Namens-Kürzel", False)
        self.input_verfuegbarkeit = new_text_input(self, "Verfügbarkeit",
                                                   "in Minuten", True)
        self.input_time = new_time_input(self, "Uhrzeit")
        self.input_date = new_date_input(self, "Datum")

        # add to layout
        self.layout_name.addWidget(self.input_name)
        self.layout_name.addWidget(self.input_vorname)

        self.layout.addLayout(self.layout_name)
        self.layout.addWidget(self.input_kuerzel)
        self.layout.addWidget(self.input_verfuegbarkeit)
        self.layout.addWidget(self.input_time)
        self.layout.addWidget(self.input_date)

        self.setLayout(self.layout)

        # if edit add old data
        if not data_object is None:
            self.input_name.text_edit.setText(str(data_object.name))
            self.input_vorname.text_edit.setText(str(data_object.vorname))
            self.input_kuerzel.text_edit.setText(str(data_object.kuerzel))
            self.input_verfuegbarkeit.text_edit.setText(
                str(data_object.verfuegbarkeit))

            datetime = datatypes.timestamp_to_datetime(data_object.timestamp)
            time = QTime(datetime.hour, datetime.minute)
            date = QDate(datetime.year, datetime.month, datetime.day)

            self.input_time.time_input.setTime(time)
            self.input_date.date_input.setDate(date)

    def clear_inputs(self):
        self.input_name.text_edit.clear()
        self.input_vorname.text_edit.clear()
        self.input_kuerzel.text_edit.clear()
        self.input_verfuegbarkeit.text_edit.clear()

    def create_object(self):
        """
        creates data_object
        :return:
        """
        if self.input_name.text_edit.empty() \
                or self.input_kuerzel.text_edit.empty() \
                or self.input_verfuegbarkeit.text_edit.empty():
            return False  # failed
        else:
            timestamp = self.input_date.date_input.dateTime(
            ).toMSecsSinceEpoch() + self.input_time.time_input.time(
            ).msecsSinceStartOfDay()

            return datatypes.Aufsichtsperson(
                self.input_name.text_edit.text(),
                self.input_vorname.text_edit.text(),
                self.input_kuerzel.text_edit.text(),
                int(self.input_verfuegbarkeit.text_edit.text()), timestamp)
Ejemplo n.º 6
0
class Collection(basicCollection.BasicCollection):
    """
    This class represents the property editor view of a collection.
    """
    def __init__(self, item, parent):
        # parent.treeView is a weakref.
        self.treeView = parent.treeView

        # Base class calls preSelector(), which for this class requires the
        # selector UI builder, so create it first.
        self._selectorUI = selectorFactory.create(item().model.getSelector())

        super(Collection, self).__init__(item, parent)

        # Observe data model selector changes.
        self.item().model.addItemObserver(self.dataModelChanged)

        self.postSelector()

    def postSelector(self):
        cmds.setParent(self._layoutName)

        form = cmds.formLayout(numberOfDivisions=100)

        buttonWidth = 50

        # Buttons to select and to view the selector output.
        selectAllBtn = cmds.button(label=kSelectAll,
                                   width=buttonWidth,
                                   annotation=kSelectAllTooltip,
                                   command=partial(Collection._selectAllCb,
                                                   self))

        viewAllBtn = cmds.button(label=kViewAll,
                                 width=buttonWidth,
                                 annotation=kViewAllTooltip,
                                 command=partial(Collection._viewAllCb, self))

        separator = cmds.separator()

        self._menu = cmds.optionMenu(label=kAddOverride,
                                     width=200,
                                     annotation=kAddOverrideTooltipStr,
                                     changeCommand=partial(
                                         Collection._menuCb, self))
        cmds.menuItem(label=renderSetup.CollectionProxy.NO_OVERRIDE)
        cmds.menuItem(label=renderSetup.CollectionProxy.ABSOLUTE_OVERRIDE)
        cmds.menuItem(label=renderSetup.CollectionProxy.RELATIVE_OVERRIDE)
        cmds.optionMenu(self._menu,
                        edit=True,
                        value=self.item()._getValueOverrideMode())

        self._dropBox = cmds.iconTextStaticLabel(
            style='iconAndTextVertical',
            i1='RS_drop_box.png',
            label=kDragAttributesFromAE,
            dropCallback=partial(Collection._dropCb, self),
            visible=self._isDropBoxVisible())

        cmds.formLayout(form,
                        edit=True,
                        attachForm=[(selectAllBtn, 'top', 0),
                                    (selectAllBtn,
                                     'right', hSpc + buttonWidth),
                                    (viewAllBtn, 'top', 0),
                                    (separator, 'left', hSpc),
                                    (separator, 'right', hSpc),
                                    (self._menu, 'left', hSpc),
                                    (self._dropBox, 'left', hSpc),
                                    (self._dropBox, 'right', hSpc)],
                        attachControl=[
                            (viewAllBtn, 'right', hSpc, selectAllBtn),
                            (separator, 'top', vSpc, selectAllBtn),
                            (self._menu, 'top', vSpc, separator),
                            (self._dropBox, 'top', vSpc, self._menu)
                        ])

        cmds.setParent('..')

    def __del__(self):
        if self.item() is not None:
            self.item().model.removeItemObserver(self.dataModelChanged)

    def dataModelChanged(self, *posArgs, **kwArgs):
        if 'selectorChanged' in kwArgs:
            # Clear existing selector UI, create a new one.
            self._clearSelectorWidgets()
            self._selectorUI = selectorFactory.create(self.getModelSelector())
            self._selectorUI.build(self._selectorLayout)

        # Unconditionally update the selector display type
        self._syncSelectorDisplay()

    def _clearSelectorWidgets(self):
        # Code in main.PropertyEditor.clearWidgets() causes
        # RuntimeError: 'Internal C++ object (PySide.QtGui.QVBoxLayout) already deleted.
        # The following from
        # http://stackoverflow.com/questions/4528347/clear-all-widgets-in-a-layout-in-pyqt
        for i in reversed(xrange(self._selectorLayout.count())):
            self._selectorLayout.itemAt(i).widget().setParent(None)

    def _syncSelectorDisplay(self):
        # Selector display type not being shown in UI as of 21-Apr-2016.
        pass

    def preSelector(self):
        """Create UI displayed above selector UI."""

        # Nothing to display as of 21-Apr-2016.
        pass

    def _selectAllCb(self, data):
        cmds.select(list(self.getModelSelector().names()))

    def _viewAllCb(self, data):
        """On view button click, show modal window with list of objects."""

        cmds.layoutDialog(ui=self.buildViewObjects,
                          title=kViewCollectionObjects)

    def getModelSelector(self):
        return self.item().model.getSelector()

    def setupSelector(self, layout):
        self._selectorGroupBox = QGroupBox(parent=self)
        self._selectorGroupBox.setContentsMargins(0, 0, 0, 0)
        self._selectorLayout = QVBoxLayout()
        self._selectorLayout.setContentsMargins(0, 0, 0, 0)
        self._selectorLayout.setSpacing(utils.dpiScale(2))
        self._selectorLayout.setObjectName('collection_selector_layout')
        self._selectorGroupBox.setLayout(self._selectorLayout)

        self._selectorUI.build(self._selectorLayout)

        layout.addWidget(self._selectorGroupBox)

    def _isDropBoxVisible(self):
        return cmds.optionMenu(self._menu, query=True, value=True) != \
            renderSetup.CollectionProxy.NO_OVERRIDE

    def isAbsoluteMode(self):
        return self.item()._getValueOverrideMode() == \
            renderSetup.CollectionProxy.ABSOLUTE_OVERRIDE

    def _setDropBoxVisibility(self):
        cmds.iconTextStaticLabel(self._dropBox,
                                 edit=True,
                                 visible=self._isDropBoxVisible())

    def _menuCb(self, mode):
        self.item()._setValueOverrideMode(mode)
        self._setDropBoxVisibility()

    def _dropCb(self, dragControl, dropControl, messages, x, y, dragType):
        # Create override.  We are expecting a node.plug string as the
        # first element of the messages list.
        if not messages or not isinstance(messages[0], basestring):
            return

        tokens = messages[0].split('.')
        attrName = tokens[-1]
        nodeName = tokens[0]

        model = self.item().model
        relative = not self.isAbsoluteMode()

        ov = model.createRelativeOverride(nodeName, attrName) if relative \
             else model.createAbsoluteOverride(nodeName, attrName)

        if relative and isinstance(ov, override.AbsOverride):
            # We asked for relative, got absolute.  Warn the user.
            rsPlug = modelPlug.Plug(nodeName, attrName)
            msg = kRelativeWarning % (attrName, rsPlug.localizedTypeString())
            cmds.warning(msg)

    def populateFields(self):
        self._selectorUI.populateFields()

    def buildViewObjects(self):

        # Get the layoutDialog's formLayout.
        #
        form = cmds.setParent(q=True)

        # layoutDialog's are unfortunately not resizable, so hard code a size
        # here, to make sure all UI elements are visible.
        #
        cmds.formLayout(form, e=True, width=500)

        objects = list(self.getModelSelector().names())
        objects.sort()

        nbObjects = cmds.text(label=(kNbObjects % len(objects)))

        textField = cmds.scrollField(editable=False, text='\n'.join(objects))

        okBtn = cmds.button(label=kOK,
                            command=partial(self.onOKButton, msg='ok'))

        cmds.formLayout(form,
                        edit=True,
                        attachForm=[(nbObjects, 'top', vSpc),
                                    (nbObjects, 'left', hSpc),
                                    (textField, 'left', hSpc),
                                    (textField, 'right', hSpc),
                                    (okBtn, 'bottom', vSpc),
                                    (okBtn, 'right', hSpc)],
                        attachControl=[(textField, 'top', vSpc, nbObjects),
                                       (textField, 'bottom', vSpc, okBtn)])

    def onOKButton(self, data, msg):
        cmds.layoutDialog(dismiss=msg)

    def highlight(self, names):
        self._selectorUI.highlight(names)
Ejemplo n.º 7
0
class FeatureSetupWidget(QWidget):

    def __init__(self, app, parent):
        super().__init__(parent)

        self.app = app
        self.parent = parent
        self.features = FeaturesSetup()

        self.layout = QVBoxLayout()

        self.title = QLabel("Brightness", self)
        myFont = self.title.font()
        myFont.setBold(True)
        self.title.setFont(myFont)
        self.title.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter)
        self.title.setAlignment(QtCore.Qt.AlignCenter)

        self.leftButton = QPushButton(u"\U00002190 Info", self)
        self.leftButton.setFlat(True)
        self.leftButton.setStyleSheet("QPushButton { text-align: left; }")
        self.leftButton.clicked.connect(self.previous)
        self.title_layout = QHBoxLayout()
        self.title_layout.addWidget(self.leftButton, 1)
        self.rightButton = QPushButton(u"Contrast \U00002192", self)
        self.rightButton.setFlat(True)
        self.rightButton.setStyleSheet("QPushButton { text-align: right; }")
        self.rightButton.clicked.connect(self.next)
        self.title_layout.addWidget(
            self.title, 1, QtCore.Qt.AlignVCenter | QtCore.Qt.AlignCenter)
        self.title_layout.addWidget(self.rightButton, 1)
        self.title_layout.setContentsMargins(0, 0, 0, 0)
        self.title_layout.setSpacing(0)

        self.info_frame = QtWidgets.QFrame(self)
        self.info_layout = QVBoxLayout()
        self.info_layout.setContentsMargins(0, 0, 0, 0)
        self.info_layout.setSpacing(0)
        self.info_frame.setLayout(self.info_layout)

        # Initialize tab screen
        self.infos = QTabWidget(self.info_frame)
        self.info_layout.addWidget(self.infos, 1)

        self.setup_frame = QtWidgets.QFrame(self)
        self.setup_layout = QVBoxLayout()
        self.setup_layout.setContentsMargins(0, 0, 0, 0)
        self.setup_layout.setSpacing(0)
        self.setup_frame.setLayout(self.setup_layout)

        self.slider = QSlider(QtCore.Qt.Horizontal, self)

        slider_color = Application.Application.getAccentColor()
        self.slider.setStyleSheet(
            "QSlider::handle:horizontal {background-color: " + slider_color.name() + ";}")

        self.slider.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.slider.setTickPosition(QSlider.TicksBothSides)
        self.slider.setRange(0, 100)
        self.slider.setTickInterval(10)
        self.slider.setPageStep(10)
        self.slider.setSingleStep(1)
        self.slider.valueChanged.connect(self.value_change)

        self.calibration = QLabel('{}:'.format("  Calibration"), self)
        self.title.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)

        # Initialize tab screen
        self.calibrations = QTabWidget(self.setup_frame)
        self.calibration1 = QWidget(self.calibrations)
        self.calibration2 = QWidget(self.calibrations)

        # Add calibrations
        self.calibrations.addTab(self.calibration1, "1: CMN")
        self.calibrations.addTab(self.calibration2, "2: HPN")

        self.tab_style_options = QtWidgets.QStyleOptionTabWidgetFrame()
        # self.calibrations.initStyleOption(self.tab_style_options)
        self.tab_style_options.initFrom(self.calibrations)
        print("TabColor Window        {}".format(
            self.tab_style_options.palette.color(QtGui.QPalette.Window).name()))
        print("TabColor Base          {}".format(
            self.tab_style_options.palette.color(QtGui.QPalette.Base).name()))
        print("TabColor AlternateBase {}".format(
            self.tab_style_options.palette.color(QtGui.QPalette.AlternateBase).name()))
        print("TabColor Button        {}".format(
            self.tab_style_options.palette.color(QtGui.QPalette.Button).name()))
        print("TabColor Mid           {}".format(
            self.tab_style_options.palette.color(QtGui.QPalette.Mid).name()))
        print("TabColor Midlight      {}".format(
            self.tab_style_options.palette.color(QtGui.QPalette.Midlight).name()))
        print("TabColor Light         {}".format(
            self.tab_style_options.palette.color(QtGui.QPalette.Light).name()))
        print("TabColor Highlight     {}".format(
            self.tab_style_options.palette.color(QtGui.QPalette.Highlight).name()))

        self.tabbar_style_options = QtWidgets.QStyleOptionTab()
        # self.calibrations.tabBar().initStyleOption(self.tabbar_style_options, 0)
        self.tabbar_style_options.initFrom(self.calibrations.tabBar())
        print("TabbarColor Window        {}".format(
            self.tabbar_style_options.palette.color(QtGui.QPalette.Window).name()))
        print("TabbarColor Base          {}".format(
            self.tabbar_style_options.palette.color(QtGui.QPalette.Base).name()))
        print("TabbarColor AlternateBase {}".format(
            self.tabbar_style_options.palette.color(QtGui.QPalette.AlternateBase).name()))
        print("TabbarColor Button        {}".format(
            self.tabbar_style_options.palette.color(QtGui.QPalette.Button).name()))
        print("TabbarColor Mid           {}".format(
            self.tabbar_style_options.palette.color(QtGui.QPalette.Mid).name()))
        print("TabbarColor Midlight      {}".format(
            self.tabbar_style_options.palette.color(QtGui.QPalette.Midlight).name()))
        print("TabbarColor Light         {}".format(
            self.tabbar_style_options.palette.color(QtGui.QPalette.Light).name()))
        print("TabbarColor Highlight     {}".format(
            self.tabbar_style_options.palette.color(QtGui.QPalette.Highlight).name()))

        groupbox = QtWidgets.QGroupBox()
        self.groupbox_style_options = QtWidgets.QStyleOptionGroupBox()
        groupbox.initStyleOption(self.groupbox_style_options)
        # self.groupbox_style_options.initFrom(groupbox)
        print("GroupBox Window        {}".format(
            self.groupbox_style_options.palette.color(QtGui.QPalette.Window).name()))
        print("GroupBox Base          {}".format(
            self.groupbox_style_options.palette.color(QtGui.QPalette.Base).name()))
        print("GroupBox AlternateBase {}".format(
            self.groupbox_style_options.palette.color(QtGui.QPalette.AlternateBase).name()))
        print("GroupBox Button        {}".format(
            self.groupbox_style_options.palette.color(QtGui.QPalette.Button).name()))
        print("GroupBox Mid           {}".format(
            self.groupbox_style_options.palette.color(QtGui.QPalette.Mid).name()))
        print("GroupBox Midlight      {}".format(
            self.groupbox_style_options.palette.color(QtGui.QPalette.Midlight).name()))
        print("GroupBox Light         {}".format(
            self.groupbox_style_options.palette.color(QtGui.QPalette.Light).name()))
        print("GroupBox Highlight     {}".format(
            self.groupbox_style_options.palette.color(QtGui.QPalette.Highlight).name()))

        r = float(self.groupbox_style_options.palette.color(
            QtGui.QPalette.Button).redF())
        print("tab_base_color        r  {}".format(r))

        r += (0.5 * float(self.groupbox_style_options.palette.color(QtGui.QPalette.Base).redF()))
        g = float(self.groupbox_style_options.palette.color(
            QtGui.QPalette.Button).greenF())
        g += (0.5 * float(self.groupbox_style_options.palette.color(QtGui.QPalette.Base).greenF()))
        b = float(self.groupbox_style_options.palette.color(
            QtGui.QPalette.Button).blueF())
        b += (0.5 * float(self.groupbox_style_options.palette.color(QtGui.QPalette.Base).blueF()))

        print("tab_base_color        rgb {} {} {}".format(r, g, b))
        self.tab_base_color = QtGui.QColor(r*255, g*255, b*255)
        print("tab_base_color          {}".format(
            self.tab_base_color.name()))
        # sys.exit()

        # Create first tab
        self.calibration1.layout = QVBoxLayout()
        self.pushButton1 = QPushButton("PySide2 button", self)
        self.calibration1.layout.addWidget(self.pushButton1)
        self.calibration1.setLayout(self.calibration1.layout)

        # Add calibrations to widget
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)
        self.layout.addLayout(self.title_layout)
        self.layout.addWidget(self.info_frame, 1)
        self.layout.addWidget(self.setup_frame, 1)

        self.setup_layout.addWidget(self.slider)
        self.setup_layout.addWidget(self.calibration)
        self.setup_layout.addWidget(self.calibrations)

        self.info_frame.hide()

        self.setLayout(self.layout)

        self.init()

    def init(self):
        self.feature = self.features.get_next(None)
        self.set_feature(self.feature)

    def clear(self):
        while(self.infos.count() > 0):
            self.infos.removeTab(0)

    def value_change(self):
        value = self.slider.value()
        print('FeatureSetupWidget {} value change {}'.format(
            self.feature.name, value))
        if (self.feature.name == "Contrast"):
            self.app.contrast(value)
        if (self.feature.name == "Brightness"):
            self.app.brightness(value)

    def set_contrast(self, value):
        # to gui
        if (self.feature.name == "Contrast"):
            self.slider.blockSignals(True)
            self.slider.setValue(value)
            self.slider.blockSignals(False)

    def set_brightness(self, value):
        # to gui
        if (self.feature.name == "Brightness"):
            self.slider.blockSignals(True)
            self.slider.setValue(value)
            self.slider.blockSignals(False)

    def set_feature(self, feature_setup):
        self.info_frame.setVisible(
            self.features.get_next(None) == feature_setup)
        self.setup_frame.setVisible(
            self.features.get_next(None) != feature_setup)

        self.title.setText(feature_setup.name)
        self.leftButton.setText(u"\U00002190 {}".format(feature_setup.next))
        self.rightButton.setText(
            u"{} \U00002192".format(feature_setup.previous))

        value = None
        if (self.feature.name == "Contrast"):
            self.set_contrast_tabs()
            value = self.app.monitors.get_contrast()
        if (self.feature.name == "Brightness"):
            self.set_brightness_tabs()
            value = self.app.monitors.get_brightness()
        print('FeatureSetupWidget {} value set {}'.format(
            self.feature.name, value))
        if (value is not None):
            self.slider.blockSignals(True)
            self.slider.setValue(value)
            self.slider.blockSignals(False)

    def next(self):
        self.feature = self.features.get_next(self.feature)
        self.set_feature(self.feature)

    def previous(self):
        self.feature = self.features.get_previous(self.feature)
        self.set_feature(self.feature)

    # @ pyqtSlot()
    # def on_click(self):
    #    print("\n")
    #    for currentQTableWidgetItem in self.tableWidget.selectedItems():
    #        print(currentQTableWidgetItem.row(),
    #              currentQTableWidgetItem.column(), currentQTableWidgetItem.text())

    def set_infos(self, monitors):
        self.monitors = monitors

        while(self.infos.count() > 0):
            self.infos.removeTab(0)

        index = 0
        monitor = self.monitors.get_monitor(index)
        while (monitor is not None):

            info_widget = QWidget(self.infos)

            info_layout = QVBoxLayout()
            info_grid = QGridLayout()
            info_grid.setColumnStretch(0, 1)
            info_grid.setColumnStretch(1, 3)
            row = 0
            for key, value in monitor._monitor.info.items():
                variableLabel = QLabel(key)
                valueLabel = QLabel(value)

                info_grid.addWidget(variableLabel, row, 0)
                info_grid.addWidget(valueLabel, row, 1)

                row += 1

            info_layout.addLayout(info_grid)
            info_layout.addStretch(1)

            info_widget.setLayout(info_layout)

            self.infos.addTab(
                info_widget, tab_name(index, monitor._monitor.info))

            index += 1
            monitor = self.monitors.get_monitor(index)

    def update_cal_data(self, datas, values):
        print("-> update_cal_data {} : {}".format(datas, values))
        id = datas[0]
        monitor = self.monitors.get_monitor_by_id(id)
        type = datas[1]
        x_values = values[0]
        y_values = values[1]

        calibration = monitor._calibration.get(type)
        if (calibration is not None):
            calibration._set(values)

    def set_brightness_tabs(self):
        while(self.calibrations.count() > 0):
            self.calibrations.removeTab(0)

        index = 0
        monitor = self.monitors.get_monitor(index)
        while (monitor is not None):
            if (monitor._monitor.brightness is not None):

                type = Display.Display.BRIGHTNESS
                calibration_scaler = monitor._calibration.get(type)
                if (calibration_scaler is not None):

                    back_color = self.calibrations.palette().color(QtGui.QPalette.Base)
                    text_color = self.calibrations.palette().color(QtGui.QPalette.WindowText)
                    line_color = Application.Application.getAccentColor()

                    calibration_widget = CalibrationWidget.CalibrationWidget(self,
                                                                             calibration_scaler._scaling, self.update_cal_data,
                                                                             [monitor._monitor._device_name, type],
                                                                             self.tab_base_color, text_color, line_color)

                    self.calibrations.addTab(
                        calibration_widget, tab_name(index, monitor._monitor.info))

            index += 1
            monitor = self.monitors.get_monitor(index)

    def set_contrast_tabs(self):
        while(self.calibrations.count() > 0):
            self.calibrations.removeTab(0)

        index = 0
        monitor = self.monitors.get_monitor(index)
        while (monitor is not None):
            if (monitor._monitor.contrast is not None):

                type = Display.Display.CONTRAST
                calibration_scaler = monitor._calibration.get(type)

                if (calibration_scaler is not None):

                    back_color = self.calibrations.palette().color(QtGui.QPalette.Base)
                    text_color = self.calibrations.palette().color(QtGui.QPalette.WindowText)
                    line_color = Application.Application.getAccentColor()

                    calibration_widget = CalibrationWidget.CalibrationWidget(self,
                                                                             calibration_scaler._scaling, self.update_cal_data,
                                                                             [monitor._monitor._device_name, type],
                                                                             self.tab_base_color, text_color, line_color)

                    self.calibrations.addTab(
                        calibration_widget, tab_name(index, monitor._monitor.info))

            index += 1
            monitor = self.monitors.get_monitor(index)
Ejemplo n.º 8
0
class ModernWindow(QDialog):
    """
    Implements a modern window-frame.
    Notes:
        * Except for macOS, the OS will not add a shadow to the window. On Windows and Linux this
          class will add QGraphicsDropShadowEffect to the entire window.
    """
    __double_clicked = Signal()

    def __init__(self, window: Any, parent: Optional[Any],
                 style: Optional[Any], title_bar: bool,
                 transparent_window: bool, titlebar_height: Optional[int],
                 titlebar_color: Optional[QColor],
                 titlebar_nofocus_color: Optional[QColor],
                 titlebar_text_color: Optional[QColor],
                 titlebar_widget: Optional[Union[QWidget, QTabWidget]],
                 window_buttons_position: Optional[str]) -> None:
        """
        Constructor.
        Parameters:
         * window: Qt widget that should be wrapped
         * window_style: choose from one of the pre-defined styles, e.g. 'APL', 'WOW'
         * title_bar: display a traditional titlebar or not
         * titlebar_height: height of the titlebar in pixel
         * titlebar_color: override background color of the titlebar
         * titlebar_nofocus_color: override background color of the titlebar when the window is out of focus
         * titlebar_text_color: override color for the window title text
         * window_button_position: positions the window close/min/max buttons left (macOS) or right of the window title
           (Windows, Gnome, KDE, etc.)
         * transparent_window: turns off window transparency. This ensures compatibility with certain widgets and draw
           modes, such as QMediaWidget on Windows. Drawbacks: when transparent_window is False, window drop shadow
           effects will be disabled, except for operating systems that automatically add a drop shadow to all windows.
        """
        def expose_msgbox_methods() -> None:
            """ensure Qt methods of wrapped children are exposed"""
            assert self.__window is not None
            self.setText = self.__window.setText
            self.setInformativeText = self.__window.setInformativeText
            self.setDetailedText = self.__window.setDetailedText

        def add_window_buttons() -> None:
            """create window widget buttons"""
            button_size_policy = QSizePolicy(QSizePolicy.Fixed,
                                             QSizePolicy.Fixed)
            if not isinstance(self.__window, QDIALOG_TYPES):
                self._minimize_button = QToolButton(self)
                self._minimize_button.setObjectName('btnMinimize')
                self._minimize_button.setSizePolicy(button_size_policy)
                self._minimize_button.clicked.connect(
                    self.__on_minimize_button_clicked)  # pylint: disable=no-member
                self._restore_button = QToolButton(self)
                self._restore_button.setObjectName('btnRestore')
                self._restore_button.setSizePolicy(button_size_policy)
                self._restore_button.clicked.connect(
                    self.__on_restore_button_clicked)  # pylint: disable=no-member
                self._maximize_button = QToolButton(self)
                self._maximize_button.setObjectName('btnMaximize')
                self._maximize_button.setSizePolicy(button_size_policy)
                self._maximize_button.clicked.connect(
                    self.__on_maximize_button_clicked)  # pylint: disable=no-member
            self._close_button = QToolButton(self)
            self._close_button.setObjectName('btnClose')
            self._close_button.setSizePolicy(button_size_policy)
            self._close_button.clicked.connect(self.__on_close_button_clicked)  # pylint: disable=no-member
            self.__move_window_buttons()  # place buttons

        def set_window_properties(titlebar_height: int) -> None:
            """Sets Qt Properties for the wrapper window"""
            assert self.__window is not None
            self.setStyleSheet(self.__style.get_window_stylesheet())
            self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint
                                | Qt.WindowSystemMenuHint
                                | Qt.WindowCloseButtonHint
                                | Qt.WindowMinimizeButtonHint
                                | Qt.WindowMaximizeButtonHint)
            if sys.platform not in ["darwin"] and self.__transparent_window:
                self.setAttribute(Qt.WA_TranslucentBackground,
                                  True)  # no need for translucency on macOS
            if sys.platform == 'win32':
                self.setAttribute(
                    Qt.WA_OpaquePaintEvent,
                    True)  # avoid flickering on window resize on Windows
            else:
                self.setAttribute(Qt.WA_OpaquePaintEvent, False)
            self.setAttribute(Qt.WA_NoSystemBackground, True)
            self.setWindowTitle(self.__window.windowTitle())
            self.setGeometry(self.__window.geometry())
            height = titlebar_height
            if self.__use_shadow:
                height += self.__style.window.SHADOW_RADIUS_PX * 2
            self.setMinimumHeight(self.__window.minimumSizeHint().height() +
                                  height)
            self.setMinimumWidth(self.__window.minimumSizeHint().width())

        def add_window_drop_shadow() -> None:
            """Adds a drop-shadow behind the window"""
            if self.__use_shadow:
                self.layout().setMargin(self.__style.window.SHADOW_RADIUS_PX)
                drop_shadow_effect = QGraphicsDropShadowEffect(self)
                drop_shadow_effect.setEnabled(True)
                drop_shadow_effect.setBlurRadius(
                    self.__style.window.SHADOW_RADIUS_PX)
                color = QColor(self.__style.window.SHADOW_COLOR_RGB)
                color.setAlpha(self.__style.window.SHADOW_OPACITY_HEX)
                drop_shadow_effect.setColor(color)
                drop_shadow_effect.setOffset(0)
                self.setGraphicsEffect(drop_shadow_effect)

        def adjust_wrapped_window_object() -> None:
            """Adding attribute to clean up the parent window when the child is closed"""
            assert self.__window is not None
            self.__window.wrapper = self
            self.__window.setAttribute(Qt.WA_DeleteOnClose, True)
            self.__window.destroyed.connect(self.__child_was_closed)

        def add_resizers() -> None:
            """Adds resizer widgets, which act as resize handles, to the window wrapper"""
            if isinstance(window, QDIALOG_TYPES):
                assert self.__window is not None
                self.__window.installEventFilter(self)
            else:
                self.resizer_top = Resizer(
                    self, Resizer.TOP, self.__style.window.SHADOW_RADIUS_PX)
                self.resizer_bot = Resizer(
                    self, Resizer.BOTTOM, self.__style.window.SHADOW_RADIUS_PX)
                self.resizer_lef = Resizer(
                    self, Resizer.LEFT, self.__style.window.SHADOW_RADIUS_PX)
                self.resizer_rig = Resizer(
                    self, Resizer.RIGHT, self.__style.window.SHADOW_RADIUS_PX)
                self.resizer_tl = Resizer(self, Resizer.TOP_LEFT,
                                          self.__style.window.SHADOW_RADIUS_PX)
                self.resizer_tr = Resizer(self, Resizer.TOP_RIGHT,
                                          self.__style.window.SHADOW_RADIUS_PX)
                self.resizer_br = Resizer(self, Resizer.BOTTOM_RIGHT,
                                          self.__style.window.SHADOW_RADIUS_PX)
                self.resizer_bl = Resizer(self, Resizer.BOTTOM_LEFT,
                                          self.__style.window.SHADOW_RADIUS_PX)

        def get_window_frame_widget(
                window_buttons_position: str) -> WindowFrame:
            """Returns a widget which acts as Qt 'windowFrame' element"""
            window_frame_widget = WindowFrame(
                titlebar_height=self.__titlebar_height,
                titlebar_color=self.__titlebar_color,
                background_color=self.__style.window.WINDOW_BACKGROUND_RGB,
                corner_radius=self.__style.window.WINDOW_CORNER_RADIUS_PX,
                parent=self)
            if not isinstance(window, QDIALOG_TYPES):
                window_frame_widget.double_clicked.connect(
                    self.__on_title_bar_double_clicked)  # type: ignore
            window_frame_widget.setObjectName('windowFrame')
            self.__vbox_frame_layout = QVBoxLayout(window_frame_widget)
            self.__vbox_frame_layout.setContentsMargins(0, 0, 0, 0)
            self.__vbox_frame_layout.setSpacing(0)
            if self.__title_bar:  # add optional titlebar
                tcolor = QColor(self.__style.window.TITLE_BAR_FONT_COLOR_RGB)
                if titlebar_text_color is not None:
                    tcolor = titlebar_text_color
                self.__title_widget = WindowTitleLabel(
                    text='',
                    height=self.__titlebar_height,
                    color=tcolor,
                    window_buttons_position=window_buttons_position,
                    margin=self.__style.window.
                    TITLE_BAR_TITLE_TEXT_RIGHT_MARGIN_PX,
                    button_bar_width=self.window_buttons_width +
                    self.window_buttons_margin,
                    minimum_width=self.__style.window.
                    TITLE_LABEL_MINIMUM_WIDTH_PX,
                    parent=None)
                self.__title_widget.setMinimumHeight(self.__titlebar_height)
                self.__vbox_frame_layout.addWidget(self.__title_widget)
            else:  # no title-bar; add dummy widget to create a margin
                self.__title_widget = QWidget()
                self.__title_widget.setGeometry(
                    0, 0, 1, self.__style.window.TITLE_BAR_TOP_MARGIN_PX)
                self.__title_widget.setMinimumHeight(
                    self.__style.window.TITLE_BAR_TOP_MARGIN_PX)
                self.__vbox_frame_layout.addWidget(self.__title_widget)
            assert self.__window is not None
            self.__vbox_frame_layout.addWidget(self.__window)
            return window_frame_widget

        QDialog.__init__(self, parent)
        self.__style: Any = style
        if titlebar_height is None:
            titlebar_height = self.__style.window.TITLE_BAR_HEIGHT_PX
        assert window_buttons_position in [
            None, WINDOW_BUTTONS_LEFT, WINDOW_BUTTONS_RIGHT
        ]
        if window_buttons_position is None:
            window_buttons_position = WINDOW_BUTTONS_LEFT if sys.platform == 'darwin' else WINDOW_BUTTONS_RIGHT
        self.__window: Optional[QWidget] = window
        self.__title_bar: bool = True if isinstance(
            self.__window, QDIALOG_TYPES) else title_bar
        self.__titlebar_height: int = titlebar_height
        self.__transparent_window: bool = transparent_window  # True if window uses WA_TranslucentBackground
        self.__use_shadow: bool = sys.platform != 'darwin' and transparent_window
        self.__maximized: bool = False
        self.__drag_move_enabled: bool = True
        self.__mouse_pressed: bool = False
        self.__mouse_pos: Optional[QPoint] = None
        self.__window_pos: Optional[QPoint] = None
        self.__window_buttons_width: int = 0
        self.__window_buttons_position: str = window_buttons_position
        # create main contaner layout
        self.__vbox_master_layout = QGridLayout(self)
        self.__vbox_master_layout.setContentsMargins(0, 0, 0, 0)
        if titlebar_color is None:
            self.__titlebar_color: QColor = QColor(
                self.__style.window.TITLE_BAR_COLOR_RGB)
        else:
            self.__titlebar_color = titlebar_color
        if titlebar_nofocus_color is None:
            self.__titlebar_nofocus_color: QColor = QColor(
                self.__style.window.TITLE_BAR_NOFOCUS_COLOR_RGB)
        else:
            self.__titlebar_nofocus_color = titlebar_nofocus_color
        self.__window_frame_widget: WindowFrame = get_window_frame_widget(
            window_buttons_position=self.__window_buttons_position)
        self.__vbox_master_layout.addWidget(self.__window_frame_widget, 0, 0)
        # run window initialization methods
        add_resizers()
        if isinstance(self.__window, QMessageBox):
            expose_msgbox_methods()
        adjust_wrapped_window_object()
        add_window_drop_shadow()
        add_window_buttons()
        set_window_properties(self.__titlebar_height)
        # connect slot to detect if window/app loses focus
        app = QApplication.instance()
        app.focusChanged.connect(self.__app_focus_changed_slot)
        self.setFocus()
        self.layout().setSizeConstraint(
            QLayout.SetMinimumSize
        )  # ensure widgets cannot be resized below their min size
        # attributes for title-bar tab widget
        self.__tab_widget_dummy_close_button: Optional[QWidget] = None
        self.__tab_widget_filter: Optional[TabFilter] = None
        self.__tab_widget: Optional[QTabWidget] = None
        if titlebar_widget is not None:
            self.__adjust_title_tabwidget(titlebar_widget)

    def keyPressEvent(self, event: QKeyEvent) -> None:
        """Ignore Escape key as it closes the window"""
        if event.key() != Qt.Key_Escape:
            super().keyPressEvent(event)

    # def keyPressEvent(self, e: QKeyPressEvent) -> None:
    #     """
    #     Example code for moving a window that has no titlebar between 2 screens with different
    #     scaling factors on Windows without any graphical artifacts.
    #     """
    #     scr = QApplication.instance().screens()
    #     if e.key() == Qt.Key_1:
    #         s = scr[0].availableSize()
    #         o = 0
    #     elif e.key() == Qt.Key_2:
    #         s = scr[1].availableSize()
    #         o = scr[1].availableSize().width()
    #     else:
    #         return
    #     size = self.size()
    #     pos = QPoint(s.width()/2 - self.width()/2 + o, s.height()/2 - self.height()/2)
    #     self.showMinimized()
    #     self.setGeometry(pos.x(), pos.y(), size.width(), size.height())
    #     self.showNormal()
    #     self.resize(size)

    def setWindowIcon(self, icon: Union[QIcon, QPixmap]) -> None:
        """Sets the window's window icon"""
        super().setWindowIcon(icon)
        if sys.platform == 'win32':  # make icon show up in taskbar on Windows
            import ctypes  # pylint: disable=import-outside-toplevel
            myappid: str = 'mycompany.qtmodern.redux.version'  # arbitrary string
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
                myappid)

    # ############################################################
    # Properties
    # ############################################################

    def get_style(self) -> Any:
        """returns the class (static) which holds all the style's properties"""
        return self.__style

    @property
    def use_shadow(self) -> bool:
        """returns true if the window features a drop-shadow not generated by the OS or window manager"""
        return self.__use_shadow

    @property
    def maximized(self) -> bool:
        """Returns true if the window is maximzed"""
        return self.__maximized

    @property
    def titlebar_height(self) -> int:
        """Returns the title bar's height in pixels"""
        return self.__titlebar_height

    @property
    def window_buttons_width(self) -> int:
        """Returns the width of the area taken up by the titlebar buttons"""
        diameter: int = self.__style.window.TITLE_BAR_BUTTON_DIAMETER_PX
        spacing: int = self.__style.window.TITLE_BAR_BUTTON_SPACING_PX - diameter
        if not isinstance(self.__window, QDIALOG_TYPES):
            return spacing * 2 + diameter * 3
        return diameter

    @property
    def window_buttons_margin(self) -> int:
        """
        Returns the distance of the titlebar buttons from the left window edge.
        The maximum value is the distance of the buttons from the top edge, the minimum distance is defined in the
        window style. This value changes depending on the size of the window.
        """
        margin_y: int = int(
            (self.__titlebar_height -
             self.__style.window.TITLE_BAR_BUTTON_DIAMETER_PX) / 2)
        min_margin: int = round(
            self.__style.window.TITLE_BAR_BUTTON_MIN_X_MARGIN_PX if margin_y <
            self.__style.window.TITLE_BAR_BUTTON_MIN_X_MARGIN_PX else margin_y)
        return min_margin

    # ############################################################
    # Overloaded Qt methods
    # ############################################################

    def resizeEvent(self, r: QResizeEvent) -> None:
        """
        Qt Resize Event - does two things:
        1) applies rounded corners if window transparency has been disabled
        2) ensures resizer widgets and titlebar buttons stay in place
        TODO: the 'rounded_corner_px' value is harcoded. It relates to in '.TitleTabBar::tab' in
              widgetstyle/tabwidget_titlebar.py (border-width and border-image QSS attribute).
              Action: investigate a way so that this value doesn't have to be hard-coded.
        """
        # if transparency is turned off, set a mask for some basic rounded corners:
        if not self.__transparent_window and self.__style.window.WINDOW_CORNER_RADIUS_PX > 0:
            path = QPainterPath()
            path.addRoundedRect(
                QRectF(self.rect()),
                self.__style.window.WINDOW_CORNER_RADIUS_PX +
                1,  # add 1 to avoid drawing artifacts
                self.__style.window.WINDOW_CORNER_RADIUS_PX + 1)
            reg = QRegion(path.toFillPolygon().toPolygon())
            self.setMask(reg)
        # adjust window button positions
        if not isinstance(self.__window, QDIALOG_TYPES):
            self.resizer_bl.adjust_resizers(self.geometry(
            ))  # adjusting one resizer adjusts all other resizers too
        if self.__window_buttons_position == WINDOW_BUTTONS_RIGHT:
            self.__move_window_buttons()
        # if a titlebar tab widget is set, mask it so that the empty area can be used to drag the window
        if self.__tab_widget is not None:
            width = 0
            tab_bar = self.__tab_widget.tabBar()
            for i in range(0,
                           tab_bar.count() -
                           1):  # don't count invisible tab at end
                if tab_bar.isTabVisible(i):
                    width += tab_bar.tabRect(i).width()
            rounder_corner_px = 8  # TODO  # related to hardcoded border-image value in widgetstyle/tabwidget_titlebar.py
            r = QRect(0, 0, width + rounder_corner_px, self.__titlebar_height)
            self.__tab_widget.tabBar().setMask(r)

    def showEvent(self, _: QShowEvent) -> None:
        """
        Qt Show Event:
        * ensures resizers stay in place
        * ensures window is centered on screen or relative to their parent window
        """
        if not isinstance(self.__window, QDIALOG_TYPES):
            self.resizer_bl.adjust_resizers(self.geometry(
            ))  # adjusting one resizer adjusts all other resizers too
        parent = self.parent()
        # center MainWindow on screen
        if CENTER_MAINWINDOW:
            if parent is None:
                self.move(
                    QApplication.desktop().screenGeometry(self).center() -
                    self.rect().center())  # type: ignore
        # center dialogs relative to parent window
        if ALIGN_CHILD_WINDOWS and parent is not None:
            try:
                pos = parent.wrapper.pos(
                )  # parent is wrapped in a QtModernRedux window
                width = parent.wrapper.width()
                height = parent.wrapper.height()
            except AttributeError:
                pos = parent.pos()  # parent isn't wrapped
                width = parent.width()
                height = parent.height()
            x = pos.x() + (width / 2 - self.width() / 2)
            y = pos.y() + (height / 2 - self.height() / 2)
            self.move(x, y)

    def closeEvent(self, event: QCloseEvent) -> None:
        """Qt Close Event: Window close & cleanup"""
        if not self.__window:
            event.accept()
        else:
            self.__window.close()
            event.setAccepted(self.__window.isHidden())

    def eventFilter(self, target: QObject, event: QEvent) -> bool:
        """Qt Event Filter: This event filter is used when display QDialogs, such as message boxes."""
        # FOR MESSAGEBOX:
        if isinstance(event, QResizeEvent):
            assert self.__window is not None
            geometry = self.__window.geometry()
            if sys.platform in ['darwin']:
                self.setFixedSize(
                    geometry.width() + self.__style.window.SHADOW_RADIUS_PX *
                    2,  # macOS, Windows (?)
                    geometry.height() +
                    self.__style.window.SHADOW_RADIUS_PX * 2)
            else:
                self.setFixedSize(
                    geometry.width() +
                    self.__style.window.SHADOW_RADIUS_PX * 2,
                    geometry.height() +
                    self.__style.window.SHADOW_RADIUS_PX * 2 +
                    self.__titlebar_height)
            return True
        return QObject.eventFilter(self, target, event)

    def setIcon(self, icon: Any) -> None:
        """Qt setIcon: sets custom icons from the theme for QMessageBox"""
        if isinstance(self.__window,
                      QMessageBox) and icon != QMessageBox.NoIcon:
            icons = {
                QMessageBox.Information:
                self.__style.window.MSGBOX_ICON_INFORMATION,
                QMessageBox.Question: self.__style.window.MSGBOX_ICON_QUESTION,
                QMessageBox.Warning: self.__style.window.MSGBOX_ICON_WARNING,
                QMessageBox.Critical: self.__style.window.MSGBOX_ICON_CRITICAL,
            }
            self.__window.setIconPixmap(self.__load_svg(icons[icon]))

    def setWindowTitle(self, title: str) -> None:
        """Qt setWindowTitle: ensures the titlebar displays the window title"""
        super().setWindowTitle(title)
        if self.__title_bar:
            self.__title_widget.setWindowTitle(title)

    def setWindowFlag(self, flag: Any, on: bool = True) -> None:
        """Qt setWindowFlag"""
        button_hints = [
            Qt.WindowCloseButtonHint, Qt.WindowMinimizeButtonHint,
            Qt.WindowMaximizeButtonHint
        ]
        if flag in button_hints:
            self.__set_window_button_state(flag, on)
        else:
            QWidget.setWindowFlag(self, flag, on)

    def setWindowFlags(self, flags: Any) -> None:
        """Qt setWindowFlags"""
        button_hints = [
            Qt.WindowCloseButtonHint, Qt.WindowMinimizeButtonHint,
            Qt.WindowMaximizeButtonHint
        ]
        for hint in button_hints:
            self.__set_window_button_state(hint, bool(flags & hint))
        QWidget.setWindowFlags(self, flags)

    def mousePressEvent(self, event: QMouseEvent) -> None:
        """Qt Mouse-Press Event: Window dragging"""
        if not self.__drag_move_enabled:
            return
        radius = self.__style.window.SHADOW_RADIUS_PX if self.__use_shadow else 0
        ep = event.pos()
        if radius <= ep.y() <= self.__titlebar_height + radius + 1:
            epx = ep.x()
            if radius < epx < self.width() - radius:
                self.__mouse_pressed = True
                self.__mouse_pos = event.globalPos()
                self.__window_pos = self.pos()
                # self.__os = self.size()  # use when dragging between screens with different scale factors

    def mouseMoveEvent(self, event: QMouseEvent) -> None:
        """Qt Mouse-Move Event: Window dragging"""
        if self.__mouse_pressed and self.__drag_move_enabled:
            # CODE TO DETECT DISPLAY CHANGE
            # display = self.screen().virtualSiblingAt(event.globalPos()).name()
            # if display != self.__old_display:
            #     print('DISPLAY CHANGED TO %s' % display, self.__old_size)
            #     self.__old_display = display
            self.move(self.__window_pos +
                      (event.globalPos() - self.__mouse_pos))

    def mouseReleaseEvent(self, _: QMouseEvent) -> None:
        """Qt Mouse-Release Event: Window dragging"""
        self.__mouse_pressed = False
        # self.resize(self.__os)  # use when dragging between screens with different scale factors

    # ############################################################
    # PRIVATE Custom methods
    # ############################################################

    def __move_window_buttons(self) -> None:
        """
        MacOS:
            * buttons are on the right side of the titlebar
            * order (left to right): close, minimize/restore, maximize
        Windows and most Linux:
            * buttons are on the left side of the titlebar
            * order (left to right): minimize/restore, maximize, close
        """
        # determine shadow radius
        radius: int = self.__style.window.SHADOW_RADIUS_PX
        if self.__use_shadow is False or self.__maximized:
            radius = 0
        # determine combined button width
        diameter = self.__style.window.TITLE_BAR_BUTTON_DIAMETER_PX
        spacing = self.__style.window.TITLE_BAR_BUTTON_SPACING_PX - diameter
        buttons_width: int = self.window_buttons_width
        # determine individual button positions
        margin_y: int = int((self.__titlebar_height - diameter) / 2)
        min_margin = self.window_buttons_margin
        if self.__window_buttons_position == WINDOW_BUTTONS_RIGHT:
            ofs_min = 0
            ofs_max = diameter + spacing
            if not isinstance(self.__window, QDIALOG_TYPES):
                ofs_close = (diameter + spacing) * 2
            else:
                ofs_close = 0
            margin_x: int = self.width() - buttons_width - min_margin - radius
        else:
            ofs_close = 0
            ofs_min = diameter + spacing
            ofs_max = (diameter + spacing) * 2
            margin_x = min_margin + radius
        # move buttons
        self._close_button.move(margin_x + ofs_close, margin_y + radius)
        if not isinstance(self.__window, QDIALOG_TYPES
                          ):  # no additional window buttons for message-boxes
            self._minimize_button.move(margin_x + ofs_min, margin_y + radius)
            self._restore_button.move(margin_x + ofs_max, margin_y + radius)
            self._maximize_button.move(margin_x + ofs_max, margin_y + radius)

    def __load_svg(self, svg_file: str) -> QPixmap:
        """Loads a SVG file and scales it correctly for High-DPI screens"""
        svg_renderer = QSvgRenderer(svg_file)
        pixmap = QPixmap(svg_renderer.defaultSize() * self.devicePixelRatio())
        pixmap.fill(Qt.transparent)
        painter = QPainter()
        painter.begin(pixmap)
        svg_renderer.render(painter)
        painter.end()
        pixmap.setDevicePixelRatio(self.devicePixelRatio())
        return pixmap

    def __show_resizers(self, show: bool) -> None:
        """Shows / hides the resizer widgets"""
        self.resizer_top.setVisible(show)
        self.resizer_bot.setVisible(show)
        self.resizer_lef.setVisible(show)
        self.resizer_rig.setVisible(show)
        self.resizer_tl.setVisible(show)
        self.resizer_tr.setVisible(show)
        self.resizer_bl.setVisible(show)
        self.resizer_br.setVisible(show)

    def __child_was_closed(self) -> None:
        """Wrapped window was closed"""
        self.__window = None  # The child was deleted, remove the reference to it and close the parent window
        self.close()

    def __set_window_button_state(self, hint: Any, state: Any) -> None:  # pylint: disable=too-many-branches
        """Adjusts button state (enabled/disabled) based on window status"""
        buttons = {Qt.WindowCloseButtonHint: self._close_button}
        if not isinstance(self.__window, QDIALOG_TYPES):
            buttons[Qt.WindowMinimizeButtonHint] = self._minimize_button
            buttons[Qt.WindowMaximizeButtonHint] = self._maximize_button
        button = buttons.get(hint)
        maximized = bool(self.windowState() & Qt.WindowMaximized)
        if not isinstance(self.__window, QDIALOG_TYPES):
            if button == self._maximize_button:  # special rules for max/restore
                self._restore_button.setEnabled(state)
                self._maximize_button.setEnabled(state)
                if maximized:
                    self._restore_button.setVisible(state)
                    self._maximize_button.setVisible(False)
                else:
                    self._maximize_button.setVisible(state)
                    self._restore_button.setVisible(False)
            elif button is not None:
                button.setEnabled(state)
        elif button is not None:
            button.setEnabled(state)
        all_buttons = [self._close_button]
        if not isinstance(self.__window, QDIALOG_TYPES):
            all_buttons.append(self._minimize_button)
            all_buttons.append(self._maximize_button)
            all_buttons.append(self._restore_button)
        if True in [button.isEnabled() for button in all_buttons]:
            for button in all_buttons:
                button.setVisible(True)
            if not isinstance(self.__window, QDIALOG_TYPES):
                if maximized:
                    self._maximize_button.setVisible(False)
                else:
                    self._restore_button.setVisible(False)
        else:
            for button in all_buttons:
                button.setVisible(False)

    @Slot()  # type: ignore
    def __on_minimize_button_clicked(self) -> None:
        """
        macOS workaround: Frameless windows cannot be minimized on macOS, therefore we need
        to reinstate the titlebar before we minimize the window. Once the window minimize
        command has been issued, we can hide the titlebar again.
        """
        if sys.platform == 'darwin':
            self.setWindowFlags(Qt.Window | Qt.WindowSystemMenuHint
                                | Qt.WindowCloseButtonHint
                                | Qt.WindowMinimizeButtonHint
                                | Qt.WindowMaximizeButtonHint)
            self.show()
        self.setWindowState(Qt.WindowMinimized)
        self._minimize_button.setAttribute(
            Qt.WA_UnderMouse, False)  # prevent hover state form getting stuck
        if sys.platform == 'darwin':
            self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint
                                | Qt.WindowSystemMenuHint
                                | Qt.WindowCloseButtonHint
                                | Qt.WindowMinimizeButtonHint
                                | Qt.WindowMaximizeButtonHint)
            self.show()

    @Slot()  # type: ignore
    def __on_restore_button_clicked(self) -> None:
        """Restore button clicked"""
        if self._maximize_button.isEnabled() or self._restore_button.isEnabled(
        ):
            self._restore_button.setVisible(False)
            self._restore_button.setEnabled(False)
            self._maximize_button.setVisible(True)
            self._maximize_button.setEnabled(True)
        self.__maximized = False
        if self.__use_shadow:
            self.layout().setMargin(self.__style.window.SHADOW_RADIUS_PX
                                    )  # adjust window for drop-shadow margin
            self.__show_resizers(True)
            self.__drag_move_enabled = True
        self.__move_window_buttons()  # adjust window for drop-shadow margin
        self.setWindowState(Qt.WindowNoState)
        self._maximize_button.setAttribute(
            Qt.WA_UnderMouse, False)  # prevent hover state form getting stuck
        self._restore_button.setAttribute(Qt.WA_UnderMouse, False)

    @Slot()  # type: ignore
    def __on_maximize_button_clicked(self) -> None:
        """Maximize button clicked"""
        if self._maximize_button.isEnabled() or self._restore_button.isEnabled(
        ):
            self._restore_button.setVisible(True)
            self._restore_button.setEnabled(True)
            self._maximize_button.setVisible(False)
            self._maximize_button.setEnabled(False)
        self.__maximized = True
        if self.__use_shadow:
            self.layout().setMargin(0)
            self.__show_resizers(False)
            self.__drag_move_enabled = False
        self.__move_window_buttons()  # adjust window for drop-shadow margin
        self.setWindowState(
            Qt.WindowMaximized)  # adjust window for drop-shadow margin
        self._maximize_button.setAttribute(
            Qt.WA_UnderMouse, False)  # prevent hover state form getting stuck
        self._restore_button.setAttribute(Qt.WA_UnderMouse, False)

    @Slot()  # type: ignore
    def __on_close_button_clicked(self) -> None:
        """Close button clicked"""
        self.close()

    @Slot()  # type: ignore
    def __on_title_bar_double_clicked(self) -> None:
        """Maximize / Restore window on titlebar double click"""
        if not bool(self.windowState() & Qt.WindowMaximized):
            self.__on_maximize_button_clicked()
        else:
            self.__on_restore_button_clicked()

    def __get_title_tabwidget_style(self, background: QColor) -> str:
        """Gets the QSS for the TabBar widget and adjusts margins"""
        margin_top_px = self.__style.window.TITLE_BAR_TOP_MARGIN_PX
        top_bottom_border_px = (
            self.__style.window.TITLE_BAR_TAB_CSS_TOP_BORDER_PX +
            self.__style.window.TITLE_BAR_TAB_CSS_BOTTOM_BORDER_PX)
        height_px = self.titlebar_height - margin_top_px - top_bottom_border_px
        style: str = self.__style.get_title_tabwidget_stylesheet()
        style = style.replace('{TITLEBAR_HEIGHT}', str(height_px))
        button_margin = str(
            self.window_buttons_margin + self.window_buttons_width +
            self.__style.window.TITLE_BAR_BUTTON_MIN_X_MARGIN_PX)
        if self.__window_buttons_position == WINDOW_BUTTONS_RIGHT:
            style = style.replace('{WINDOW_BUTTON_MARGIN_LEFT}', str(0))
            style = style.replace('{WINDOW_BUTTON_MARGIN_RIGHT}',
                                  button_margin)
        else:
            style = style.replace('{WINDOW_BUTTON_MARGIN_LEFT}', button_margin)
            style = style.replace('{WINDOW_BUTTON_MARGIN_RIGHT}', str(0))
        style = style.replace('{BACKGROUND_COLOR}', background.name())
        return style

    @Slot()  # type: ignore
    def __app_focus_changed_slot(self) -> None:
        """Changes the titlebar's background color when the window acquires/loses focus"""
        if self.isActiveWindow():
            self.__window_frame_widget.set_background_color(
                self.__titlebar_color)
        else:
            self.__window_frame_widget.set_background_color(
                self.__titlebar_nofocus_color)
        self.__window_frame_widget.update()

        if self.__tab_widget is not None:
            if self.isActiveWindow():
                self.__tab_widget.setStyleSheet(
                    self.__get_title_tabwidget_style(self.__titlebar_color))
            else:
                self.__tab_widget.setStyleSheet(
                    self.__get_title_tabwidget_style(
                        self.__titlebar_nofocus_color))

    def __adjust_title_tabwidget(self, tab_widget: QTabWidget) -> None:
        """
        Adjusts a TabWidget to work as a Google Chrome style tab bar in the window's title bar.
        TODO: to properly center the Widget (doesn't apply to TabWidgets) a bottom margin of 2px is needed;
              why is that? Action: track down source for this offset in the QSS definitions and figure out the
              proper calculation of this value.
        """
        # add properties to ensure style is only applied tabwidget in titlebar
        if isinstance(tab_widget, QTabWidget):
            self.__tab_widget = tab_widget
            tab_widget.setProperty("class", "TitleTabWidget")  # type: ignore
            tab_widget.tabBar().setProperty("class",
                                            "TitleTabBar")  # type: ignore
            tab_widget.setStyleSheet(
                self.__get_title_tabwidget_style(self.__titlebar_color))
            # insert empty disabled tab for rounded effect on last tab
            idx = tab_widget.addTab(QWidget(), "")
            tab_widget.setTabEnabled(idx, False)
            self.__tab_widget_dummy_close_button = QWidget()
            self.__tab_widget_dummy_close_button.setGeometry(0, 0, 1, 1)
            # remove close button for last widget
            tab_widget.tabBar().setTabButton(
                idx, QTabBar.RightSide, self.__tab_widget_dummy_close_button)
            self.__tab_widget_filter = TabFilter(tab_widget.tabBar())
            tab_widget.tabBar().installEventFilter(self.__tab_widget_filter)
            tab_widget.tabBar().setDocumentMode(True)
            tab_widget.tabBar().setExpanding(False)
        else:
            margin_top_px: int = self.__style.window.TITLE_BAR_TOP_MARGIN_PX  # type: ignore
            margin_bottom_px: int = self.__style.window.TITLE_BAR_TAB_CSS_BOTTOM_BORDER_PX
            height_px: int = self.titlebar_height - margin_top_px - margin_bottom_px
            button_margin: int = (
                self.window_buttons_margin + self.window_buttons_width +
                self.__style.window.TITLE_BAR_BUTTON_MIN_X_MARGIN_PX)
            non_button_margin: int = self.__style.window.TITLE_BAR_BUTTON_MIN_X_MARGIN_PX
            if self.__window_buttons_position == WINDOW_BUTTONS_RIGHT:
                tab_widget.layout().setContentsMargins(non_button_margin, 2,
                                                       button_margin,
                                                       0)  # TODO: why 2?
            else:
                tab_widget.layout().setContentsMargins(button_margin, 2,
                                                       non_button_margin,
                                                       0)  # TODO: why 2?
            tab_widget.setMaximumHeight(height_px)
            tab_widget.setMinimumHeight(height_px)
class Ui_SplashScreen(object):
    def setupUi(self, SplashScreen):
        if SplashScreen.objectName():
            SplashScreen.setObjectName(u"SplashScreen")
        SplashScreen.resize(680, 400)
        self.centralwidget = QWidget(SplashScreen)
        self.centralwidget.setObjectName(u"centralwidget")
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.verticalLayout.setContentsMargins(10, 10, 10, 10)
        self.dropShadowFrame = QFrame(self.centralwidget)
        self.dropShadowFrame.setObjectName(u"dropShadowFrame")
        self.dropShadowFrame.setStyleSheet(
            u"QFrame {\n"
            "background-color: rgb(56, 58, 89);\n"
            "color: rgb(220, 220, 220);\n"
            "border-radius: 10px;\n"
            "}")
        self.dropShadowFrame.setFrameShape(QFrame.StyledPanel)
        self.dropShadowFrame.setFrameShadow(QFrame.Raised)

        self.label_title = QLabel(self.dropShadowFrame)
        self.label_title.setObjectName(u"label_title")
        self.label_title.setGeometry(QRect(0, 90, 661, 61))
        font = QFont()
        font.setFamily(u"Segoe UI")
        font.setPointSize(40)
        self.label_title.setFont(font)
        self.label_title.setStyleSheet(u"color: rgb(254, 121, 199);")
        self.label_title.setAlignment(Qt.AlignCenter)
        self.label_description = QLabel(self.dropShadowFrame)
        self.label_description.setObjectName(u"label_description")
        self.label_description.setGeometry(QRect(0, 150, 661, 31))
        font1 = QFont()
        font1.setFamily(u"Segoe UI")
        font1.setPointSize(14)
        self.label_description.setFont(font1)
        self.label_description.setStyleSheet(u"color: rgb(98, 114, 164);")
        self.label_description.setAlignment(Qt.AlignCenter)
        self.progressBar = QProgressBar(self.dropShadowFrame)
        self.progressBar.setObjectName(u"progressBar")
        self.progressBar.setGeometry(QRect(50, 280, 561, 23))
        self.progressBar.setStyleSheet(
            u"QProgressBar {\n"
            "background-color: rgb(98, 114, 164);\n"
            "color: rgb(200, 200, 200);\n"
            "border-style: none;\n"
            "border-radius: 10px;\n"
            "text-align: center;\n"
            "}\n"
            "QProgressBar::chunk{\n"
            "border-radius: 10px;\n"
            "background-color: "
            "qlineargradient(spread:pad, x1:0, y1:0.511364, x2:1, y2:0.523, stop:0 "
            "rgba(254, 121, 199, 255), stop:1 rgba(170, 85, 255, 255));\n"
            "}")
        self.progressBar.setValue(24)
        self.label_loading = QLabel(self.dropShadowFrame)
        self.label_loading.setObjectName(u"label_loading")
        self.label_loading.setGeometry(QRect(0, 320, 661, 21))
        font2 = QFont()
        font2.setFamily(u"Segoe UI")
        font2.setPointSize(12)
        self.label_loading.setFont(font2)
        self.label_loading.setStyleSheet(u"color: rgb(98, 114, 164);")
        self.label_loading.setAlignment(Qt.AlignCenter)
        self.label_credits = QLabel(self.dropShadowFrame)
        self.label_credits.setObjectName(u"label_credits")
        self.label_credits.setGeometry(QRect(20, 350, 621, 21))
        font3 = QFont()
        font3.setFamily(u"Segoe UI")
        font3.setPointSize(10)
        self.label_credits.setFont(font3)
        self.label_credits.setStyleSheet(u"color: rgb(98, 114, 164);")
        self.label_credits.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                        | Qt.AlignVCenter)

        self.verticalLayout.addWidget(self.dropShadowFrame)

        SplashScreen.setCentralWidget(self.centralwidget)

        self.retranslateUi(SplashScreen)

        QMetaObject.connectSlotsByName(SplashScreen)

    def retranslateUi(self, SplashScreen):
        SplashScreen.setWindowTitle(
            QCoreApplication.translate("SplashScreen",
                                       u"Cria Card no Trello de Movidesk",
                                       None))
        self.label_title.setText(
            QCoreApplication.translate(
                "SplashScreen",
                u"<strong>Movidesk</strong> to <strong>Trello</strong>", None))
        self.label_description.setText(
            QCoreApplication.translate(
                "SplashScreen", u"<strong>Cria</strong> cards no Trelo", None))
        self.label_loading.setText(
            QCoreApplication.translate("SplashScreen", u"carregando...", None))
        self.label_credits.setText(
            QCoreApplication.translate("SplashScreen", u"<strong></strong>",
                                       None))
Ejemplo n.º 10
0
class Window(QWidget):
    def __init__(self, app, parent=None):

        print("Window init")

        super().__init__(parent)

        # self.win_event_filter = WinEventFilter("window")
        # self.installNativeEventFilter(self.win_event_filter)

        self.app = app

        self.window_size = QtCore.QSize(400, 250)
        self.window_size_offset = QtCore.QSize(0, 150)
        self.window_position = QtCore.QPoint(0, 0)
        self.window_position_offset = QtCore.QPoint(0, 0)

        # self.setWindowFlags(
        #    QtCore.Qt.Window |
        #    QtCore.Qt.CustomizeWindowHint |
        #    QtCore.Qt.WindowTitleHint |
        #    QtCore.Qt.WindowCloseButtonHint |
        #    QtCore.Qt.WindowStaysOnTopHint
        # )

        self.setWindowFlags(self.windowFlags() |
                            QtCore.Qt.FramelessWindowHint)
        self.setWindowFlags(self.windowFlags() |
                            QtCore.Qt.WindowStaysOnTopHint)

        self.setWindowFlags(
            QtCore.Qt.FramelessWindowHint |
            QtCore.Qt.WindowStaysOnTopHint |
            QtCore.Qt.Tool)
        # hlayout = QHBoxLayout()
        # hlayout.setMargin(0)
        # hlayout.setContentsMargins(0, 0, 0, 0)
        # hlayout.setSpacing(0)

        # buttonslayout = QVBoxLayout()

        self.labels = []

        self.menuButton = QPushButton(u"\U00002261")
        self.menuLabel = QLabel("Menu")
        myFontBold = self.menuLabel.font()
        myFontBold.setBold(True)
        # buttons
        myFont = self.menuButton.font()
        myFont2 = self.menuButton.font()
        if (myFont.pointSize() > 0):
            myFont.setPointSizeF(1.25 * myFont.pointSizeF())
            myFont2.setPointSizeF(1.4 * myFont.pointSizeF())
        else:
            myFont.setPixelSize(1.25 * myFont.pixelSize())
            myFont2.setPixelSize(1.4 * myFont.pixelSize())
        self.menuLabel.setFont(myFontBold)
        width = self.menuButton.fontMetrics().boundingRect("OO").width() + 7
        height = width  # okButton.height()
        self.menuButton.setFont(myFont2)
        self.menuButton.setMaximumWidth(width)
        self.menuButton.setMinimumWidth(width)
        self.menuButton.setFlat(True)
        self.menuButton.clicked.connect(self.menuPressed)

        mainButton = QPushButton(u"\U0000239A")
        mainLabel = QLabel("Main")
        width = mainButton.fontMetrics().boundingRect("OO").width() + 7
        height = width  # okButton.height()
        mainButton.setFont(myFont2)
        mainButton.setMaximumWidth(width)
        mainButton.setMinimumWidth(width)
        mainButton.clicked.connect(self.main)
        mainButton.setFlat(True)
        setupButton = QPushButton(u"\U0001F527")
        setupLabel = QLabel("Setup")
        setupButton.setFont(myFont)
        setupButton.setFlat(True)
        setupButton.setMaximumWidth(width)
        setupButton.setMinimumWidth(width)
        setupButton.clicked.connect(self.setup)

        identifyButton = QPushButton(u"\U00002755")
        identifyLabel = QLabel("Identify")
        identifyButton.setFont(myFont)
        identifyButton.setFlat(True)
        identifyButton.setMaximumWidth(width)
        identifyButton.setMinimumWidth(width)
        identifyButton.clicked.connect(self.identify)

        self.refreshButton = QPushButton(u"\U000021BB")
        self.refreshLabel = QLabel("Detect")
        self.refreshButton.setFont(myFont)
        self.refreshButton.setFlat(True)
        self.refreshButton.setMaximumWidth(width)
        self.refreshButton.setMinimumWidth(width)
        self.refreshButton.clicked.connect(self.refreshPressed)

        aboutButton = QPushButton(u"\U00002754")
        aboutLabel = QLabel("About")
        aboutButton.setFont(myFont)
        aboutButton.setFlat(True)
        aboutButton.setMaximumWidth(width)
        aboutButton.setMinimumWidth(width)
        aboutButton.clicked.connect(self.about)

        # closeButton = QPushButton(u"\U00002573")
        closeButton = QPushButton(u"\U000026CC")
        closeLabel = QLabel("Close")
        closeButton.setFont(myFont)
        closeButton.setFlat(True)
        closeButton.setMaximumWidth(width)
        closeButton.setMinimumWidth(width)
        closeButton.clicked.connect(self.close_)

        buttongrid = QGridLayout()
        buttongrid.addWidget(self.menuButton, 0, 0)
        buttongrid.addWidget(mainButton, 1, 0)
        buttongrid.addWidget(setupButton, 2, 0)
        buttongrid.addWidget(self.refreshButton, 3, 0)
        buttongrid.addWidget(identifyButton, 4, 0)
        buttongrid.addWidget(aboutButton, 6, 0)
        buttongrid.addWidget(closeButton, 7, 0)

        buttongrid.addWidget(self.menuLabel, 0, 1)
        buttongrid.addWidget(mainLabel, 1, 1)
        buttongrid.addWidget(setupLabel, 2, 1)
        buttongrid.addWidget(self.refreshLabel, 3, 1)
        buttongrid.addWidget(identifyLabel, 4, 1)
        buttongrid.addWidget(aboutLabel, 6, 1)
        buttongrid.addWidget(closeLabel, 7, 1)
        self.labels.append(self.menuLabel)
        self.labels.append(mainLabel)
        self.labels.append(setupLabel)
        self.labels.append(self.refreshLabel)
        self.labels.append(identifyLabel)
        self.labels.append(aboutLabel)
        self.labels.append(closeLabel)
        self.menuLabel .mousePressEvent = self.menuLabelPressed
        mainLabel .mousePressEvent = self.mainLabel
        setupLabel.mousePressEvent = self.setupLabel
        self.refreshLabel.mousePressEvent = self.refreshLabelPressed
        identifyLabel.mousePressEvent = self.identifyLabel
        aboutLabel.mousePressEvent = self.aboutLabel
        closeLabel.mousePressEvent = self.closeLabel

        buttongrid.setRowStretch(0, 0)
        buttongrid.setRowStretch(1, 0)
        buttongrid.setRowStretch(2, 0)
        buttongrid.setRowStretch(3, 0)
        buttongrid.setRowStretch(4, 0)
        buttongrid.setRowStretch(5, 1)
        buttongrid.setRowStretch(6, 0)
        buttongrid.setRowStretch(7, 0)
        self.labels_set_visible(False)

        self.layout = QHBoxLayout()

        # buttonslayout.addWidget(mainButton)
        # buttonslayout.addWidget(setupButton)
        # buttonslayout.addStretch(1)
        # buttonslayout.addWidget(aboutButton)
        # hlayout.addLayout(buttonslayout)
        # hlayout.addLayout(buttongrid)

        # grid.addLayout(hlayout, 1, 1)
        buttongrid.setSpacing(0)

        self.layout.addLayout(buttongrid)

        self.body_layout = QVBoxLayout()
        self.body_layout.setContentsMargins(0, 0, 0, 1)
        self.body_layout.setSpacing(0)

        self.title_layout = QHBoxLayout()
        self.title_layout.setContentsMargins(0, 0, 0, 0)
        self.title_layout.setSpacing(0)
        self.titleLabel = QLabel("Monitor Control")
        self.titleLabel.setWordWrap(True)
        self.titleLabel.setSizeIncrement(10, 10)
        myFont = self.titleLabel.font()
        myFont.setBold(True)
        self.titleLabel.setFont(myFont)
        width = self.titleLabel.fontMetrics().boundingRect("OO").width() + 7
        height = width  # okButton.height()
        self.titleLabel.mousePressEvent = self.mainLabel

        self.backButton = QPushButton(u"\U00002190", self)
        myFont = self.backButton.font()
        myFont.setBold(True)
        self.backButton.setFont(myFont)
        self.backButton.setMaximumWidth(width)
        self.backButton.setMinimumWidth(width)
        self.backButton.setFlat(True)
        self.backButton.clicked.connect(self.main)
        self.titleLabel.setMinimumHeight(self.backButton.height())

        self.title_layout.addWidget(self.backButton, 0, QtCore.Qt.AlignVCenter)
        self.title_layout.addSpacing(20)
        self.title_layout.addWidget(self.titleLabel, 1, QtCore.Qt.AlignVCenter)
        # self.backButton.setAlignment(Qt.AlignTop)
        self.title_layout.setAlignment(QtCore.Qt.AlignTop)

        self.body_layout.addLayout(self.title_layout)

        self.main_frame = QtWidgets.QFrame(self)
        self.main_layout = QVBoxLayout()
        self.feature_brightness = FeatureWidget(
            self.main_frame, "Brightness", self.app.brightness)
        self.feature_contrast = FeatureWidget(
            self.main_frame, "Contrast", self.app.contrast)
        self.main_layout.addWidget(self.feature_brightness)
        self.main_layout.addWidget(self.feature_contrast)
        self.main_layout.addStretch(1)
        self.main_frame.setLayout(self.main_layout)
        self.main_frame.hide()
        self.body_layout.addWidget(self.main_frame, 1)

        self.setup_frame = QtWidgets.QFrame(self)

        leftButton = QPushButton("<", self.setup_frame)
        width = leftButton.fontMetrics().boundingRect("<").width() + 7
        leftButton.setFlat(True)
        leftButton.setMaximumWidth(width)
        leftButton.setMinimumWidth(width)
        leftButton.setSizePolicy(QtWidgets.QSizePolicy(
            QSizePolicy.Fixed, QSizePolicy.Expanding))

        self.setup_layout = QHBoxLayout()
        self.setup_layout.addWidget(leftButton)
        self.feature_setup_widget = FeatureSetupWidget(
            self.app, self.setup_frame)
        # hlayout.addWidget(self.feature_setup_widget, 1)
        self.feature_setup_widget.setSizePolicy(
            QSizePolicy.Expanding, QSizePolicy.Expanding)
        rightButton = QPushButton(">", self.setup_frame)
        rightButton.setFlat(True)
        rightButton.setMaximumWidth(width)
        rightButton.setMinimumWidth(width)
        rightButton.setSizePolicy(QtWidgets.QSizePolicy(
            QSizePolicy.Fixed, QSizePolicy.Expanding))
        self.setup_layout.addWidget(self.feature_setup_widget, 1)
        self.setup_layout.addWidget(rightButton)
        self.setup_layout.setContentsMargins(0, 0, 0, 0)
        self.setup_layout.setSpacing(0)
        leftButton.clicked.connect(self.feature_setup_widget.previous)
        rightButton.clicked.connect(self.feature_setup_widget.next)

        self.setup_frame.setLayout(self.setup_layout)

        # self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(10)
        self.body_layout.addWidget(self.setup_frame, 1)

        self.layout.addLayout(self.body_layout, 1)

        self.about_frame = QtWidgets.QFrame(self)
        self.about_layout = QVBoxLayout()
        self.aboutLabel1 = QLabel("About", self.about_frame)
        self.aboutLabel1.setWordWrap(True)
        myFont = self.aboutLabel1.font()
        myFont.setBold(True)
        self.aboutLabel1.setFont(myFont)
        about = "©️ ™️ Juno\n\nMonitor Control synchronizes your monitor hardware properties like brightness and contrast.\nThese properties can be changed by the software sliders, or monitor buttons. These changes are monitored and read, and subsequently set to the other monitors using a calibration. This will ensure an input change has the same result on all monitors.\n"
        self.aboutLabel2 = QLabel("{}".format(about), self.about_frame)
        self.aboutLabel2.setAlignment(
            QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
        self.aboutLabel2.setWordWrap(True)
        self.about_layout.addWidget(self.aboutLabel1)
        self.about_layout.addWidget(self.aboutLabel2, 1)
        self.about_frame.setLayout(self.about_layout)
        self.about_frame.hide()
        self.body_layout.addWidget(self.about_frame, 1)

        # self.layout.setSizeConstraint(QtGui.QLayout.setFixedSize)

        self.setLayout(self.layout)

        self.setWindowIcon(QtGui.QIcon('artifacts/icon.png'))
        # set the title
        self.setWindowTitle("Monitors Control")

        self.main()

        self.setFixedSize(400, 250)

    def labels_set_visible(self, visible):
        for label in self.labels:
            if (self.refreshLabel == label) and visible:
                self.refreshLabel.setVisible(self.refreshButton.isVisible())
            else:
                label.setVisible(visible)

    def refresh_visible(self, visible):
        if (visible):
            self.refreshButton.setVisible(visible)
            self.refreshLabel.setVisible(self.menuLabel.isVisible())
        else:
            self.refreshLabel.setVisible(visible)
            self.refreshButton.setVisible(visible)

    def focusOutEvent(self, event):
        print('Lost focus')

    def menuLabelPressed(self, event):
        self.menuPressed()

    def menuPressed(self):
        print("Menu")
        self.labels_set_visible(not self.labels[0].isVisible())

    def aboutLabel(self, event):
        self.about()

    def about(self):
        print("About")
        self.setupUpdate()

        self.setMinimumSize(200, 130)

        # self.feature_setup_widget.hide()
        self.setup_frame.hide()
        self.main_frame.hide()
        self.refresh_visible(False)
        self.backButton.show()
        self.about_frame.show()

        self.move(self.window_position)
        self.setFixedSize(self.window_size)

    def closeLabel(self, event):
        self.close_()

    def close_(self):
        print("Close {}".format(len(self.app.identifyWindows)))
        self.setupUpdate()
        if (len(self.app.identifyWindows) == 0):
            self.hide()

    def setupLabel(self, event):
        self.setup()

    def setup(self):
        print("Setup")
        self.move(self.window_position + self.window_position_offset)
        self.setFixedSize(self.window_size + self.window_size_offset)

        self.app.monitors._calibrations.loadYaml()

        self.feature_setup_widget.init()
        self.backButton.show()

        self.main_frame.hide()
        self.about_frame.hide()
        self.refresh_visible(True)
        self.setup_frame.show()

        self.setMinimumSize(200, 130)

    def setupUpdate(self):
        if (self.setup_frame.isVisible()):
            self.app.monitors._calibrations.saveYaml()

    def mainLabel(self, event):
        self.main()

    def main(self):
        print("Main")

        self.setMinimumSize(200, 130)
        self.setupUpdate()

        self.refresh_visible(False)
        self.backButton.hide()
        # self.feature_setup_widget.hide()
        self.setup_frame.hide()
        self.about_frame.hide()
        self.main_frame.hide()

        self.move(self.window_position)
        self.setFixedSize(self.window_size)

        self.main_frame.show()

    def identifyLabel(self, event):
        self.identify()

    def identify(self):
        print("Identify")

        self.app.identify()

    def refreshLabelPressed(self, event):
        self.refreshPressed()

    def refreshPressed(self):
        QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
        print("detect")
        self.feature_setup_widget.clear()
        self.app.detect()
        self.setup()
        self.feature_setup_widget.set_infos(self.app.monitors)
        self.feature_setup_widget.init()

        self.app.list_monitors()

        QApplication.restoreOverrideCursor()

    def position_show(self):
        print("position_show")
        self.app.position_next_to_tray()
        self.main()
        self.show()
        # self.requestActivate()
        # QtCore.Qt.ActiveWindowFocusReason
        self.activateWindow()
        self.setFocus(QtCore.Qt.PopupFocusReason)

    def contrast(self, value):
        # from gui
        self.app.contrast(value)

    def brightness(self, value):
        # from gui
        self.app.brightness(value)

    def set_contrast(self, value):
        # to gui
        self.feature_contrast.set_value(value)
        self.feature_setup_widget.set_contrast(value)

    def set_brightness(self, value):
        # to gui
        self.feature_brightness.set_value(value)
        self.feature_setup_widget.set_brightness(value)

    def show(self):
        # to gui
        value = self.app.monitors.get_contrast()
        if (value is not None):
            self.set_contrast(value)

        value = self.app.monitors.get_brightness()
        if (value is not None):
            self.set_brightness(value)

        self.feature_setup_widget.set_infos(self.app.monitors)

        super().show()
Ejemplo n.º 11
0
class EECalculator(QMainWindow):
    def __init__(self, parent):
        QMainWindow.__init__(self)
        # TODO:use framelesswindow
        # self.setWindowFlags(Qt.FramelessWindowHint)
        self.InitUI()

    def RefreshWidgets(self,target,name):
        while target.count():
            Child = target.takeAt(0)
            if Child.widget():
                Child.widget().deleteLater()
        if name==modules[0]:
            target.addWidget(homepage.MainWidget())
        if name==modules[1]:
            target.addWidget(rc.MainWidget())
        if name==modules[2]:
            target.addWidget(tcap.MainWidget())
        if name==modules[3]:
            target.addWidget(ne555.MainWidget())
            
        
    def InitUI(self):
        # Set Window Size
        self.resize(800, 600)
        self.setMinimumSize(QSize(800, 600))
        # Set Window Titile
        self.setWindowTitle("EE Calculator")

        # Create Main Widgets
        self.MainWidget = QWidget()
        self.MainLayout = QHBoxLayout(self.MainWidget)
        # Create Display Widgets
        self.DisplayWidget = QWidget(self.MainWidget)
        self.DisplayLayout = QGridLayout(self.DisplayWidget)
        # Create Menu Area&Widgets
        self.MenuScrollArea = QScrollArea(self.MainWidget)
        self.MenuScrollAreaContents = QWidget()
        self.MenuScrollAreaLayout = QVBoxLayout(self.MenuScrollAreaContents)

        ButtonList=[]
        i = 0
        for module in modules:
            ButtonList.append(QPushButton(module))
            ButtonList[i].setFixedWidth(198)
            ButtonList[i].setFixedHeight(66)
            ButtonList[i].clicked.connect(partial(self.RefreshWidgets,self.DisplayLayout,module))
            self.MenuScrollAreaLayout.addWidget(ButtonList[i])
            i += 1
        self.MenuScrollAreaLayout.addStretch(1)

        # Setup Widget&LAyout
        self.MenuScrollArea.setFixedWidth(200)
        self.MenuScrollAreaLayout.setMargin(0)
        self.MenuScrollAreaLayout.setSpacing(0)
        self.DisplayLayout.setMargin(0)
        self.MainLayout.setMargin(0)
        self.MenuScrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.MenuScrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.MenuScrollArea.setWidget(self.MenuScrollAreaContents)

        self.DisplayLayout.addWidget(homepage.MainWidget())

        self.MainLayout.addWidget(self.MenuScrollArea)
        self.MainLayout.addWidget(self.DisplayWidget)
        self.setCentralWidget(self.MainWidget)
Ejemplo n.º 12
0
 def init_ui(self):
     layout = QVBoxLayout()
     layout.addWidget(self.informations_list)
     layout.setSpacing(0)
     layout.setContentsMargins(0, 0, 0, 0)
     self.setLayout(layout)
Ejemplo n.º 13
0
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        if not Dialog.objectName():
            Dialog.setObjectName(u"Dialog")
        Dialog.resize(450, 235)
        Dialog.setMinimumSize(QSize(450, 235))
        Dialog.setMaximumSize(QSize(450, 235))
        Dialog.setStyleSheet(u"QDialog {\n" "	background:rgb(51,51,51);\n" "}")
        self.verticalLayout = QVBoxLayout(Dialog)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.frame_2 = QFrame(Dialog)
        self.frame_2.setObjectName(u"frame_2")
        self.frame_2.setStyleSheet(u"background:rgb(51,51,51);")
        self.frame_2.setFrameShape(QFrame.NoFrame)
        self.frame_2.setFrameShadow(QFrame.Plain)
        self.verticalLayout_2 = QVBoxLayout(self.frame_2)
        self.verticalLayout_2.setSpacing(0)
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.verticalLayout_2.setContentsMargins(2, 2, 2, 2)
        self.frame_top = QFrame(self.frame_2)
        self.frame_top.setObjectName(u"frame_top")
        self.frame_top.setMinimumSize(QSize(0, 55))
        self.frame_top.setMaximumSize(QSize(16777215, 55))
        self.frame_top.setStyleSheet(u"background:rgb(91,90,90);")
        self.frame_top.setFrameShape(QFrame.NoFrame)
        self.frame_top.setFrameShadow(QFrame.Plain)
        self.horizontalLayout = QHBoxLayout(self.frame_top)
        self.horizontalLayout.setSpacing(0)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.lab_heading = QLabel(self.frame_top)
        self.lab_heading.setObjectName(u"lab_heading")
        font = QFont()
        font.setFamily(u"Segoe UI")
        font.setPointSize(14)
        self.lab_heading.setFont(font)
        self.lab_heading.setStyleSheet(u"color:rgb(255,255,255);")
        self.lab_heading.setAlignment(Qt.AlignCenter)

        self.horizontalLayout.addWidget(self.lab_heading)

        self.bn_min = QPushButton(self.frame_top)
        self.bn_min.setObjectName(u"bn_min")
        self.bn_min.setMinimumSize(QSize(55, 55))
        self.bn_min.setMaximumSize(QSize(55, 55))
        self.bn_min.setStyleSheet(u"QPushButton {\n"
                                  "	border: none;\n"
                                  "	background-color: rgb(51,51,51);\n"
                                  "}\n"
                                  "QPushButton:hover {\n"
                                  "	background-color: rgb(0,143,150);\n"
                                  "}\n"
                                  "QPushButton:pressed {	\n"
                                  "	background-color: rgb(51,51,51);\n"
                                  "}")
        icon = QIcon()
        icon.addFile(u"icons/1x/hideAsset 53.png", QSize(), QIcon.Normal,
                     QIcon.Off)
        self.bn_min.setIcon(icon)
        self.bn_min.setIconSize(QSize(22, 12))
        self.bn_min.setAutoDefault(False)
        self.bn_min.setFlat(True)

        self.horizontalLayout.addWidget(self.bn_min)

        self.bn_close = QPushButton(self.frame_top)
        self.bn_close.setObjectName(u"bn_close")
        self.bn_close.setMinimumSize(QSize(55, 55))
        self.bn_close.setMaximumSize(QSize(55, 55))
        self.bn_close.setStyleSheet(u"QPushButton {\n"
                                    "	border: none;\n"
                                    "	background-color: rgb(51,51,51);\n"
                                    "}\n"
                                    "QPushButton:hover {\n"
                                    "	background-color: rgb(0,143,150);\n"
                                    "}\n"
                                    "QPushButton:pressed {	\n"
                                    "	background-color: rgb(51,51,51);\n"
                                    "}")
        icon1 = QIcon()
        icon1.addFile(u"icons/1x/closeAsset 43.png", QSize(), QIcon.Normal,
                      QIcon.Off)
        self.bn_close.setIcon(icon1)
        self.bn_close.setIconSize(QSize(22, 22))
        self.bn_close.setAutoDefault(False)
        self.bn_close.setFlat(True)

        self.horizontalLayout.addWidget(self.bn_close)

        self.verticalLayout_2.addWidget(self.frame_top)

        self.frame_bottom = QFrame(self.frame_2)
        self.frame_bottom.setObjectName(u"frame_bottom")
        self.frame_bottom.setStyleSheet(u"background:rgb(91,90,90);")
        self.frame_bottom.setFrameShape(QFrame.StyledPanel)
        self.frame_bottom.setFrameShadow(QFrame.Raised)
        self.gridLayout = QGridLayout(self.frame_bottom)
        self.gridLayout.setObjectName(u"gridLayout")
        self.gridLayout.setHorizontalSpacing(5)
        self.gridLayout.setVerticalSpacing(0)
        self.gridLayout.setContentsMargins(15, -1, 35, 0)
        self.bn_east = QPushButton(self.frame_bottom)
        self.bn_east.setObjectName(u"bn_east")
        self.bn_east.setMinimumSize(QSize(69, 25))
        self.bn_east.setMaximumSize(QSize(69, 25))
        font1 = QFont()
        font1.setFamily(u"Segoe UI")
        font1.setPointSize(12)
        self.bn_east.setFont(font1)
        self.bn_east.setStyleSheet(u"QPushButton {\n"
                                   "	border: 2px solid rgb(51,51,51);\n"
                                   "	border-radius: 5px;	\n"
                                   "	color:rgb(255,255,255);\n"
                                   "	background-color: rgb(51,51,51);\n"
                                   "}\n"
                                   "QPushButton:hover {\n"
                                   "	border: 2px solid rgb(0,143,150);\n"
                                   "	background-color: rgb(0,143,150);\n"
                                   "}\n"
                                   "QPushButton:pressed {	\n"
                                   "	border: 2px solid rgb(0,143,150);\n"
                                   "	background-color: rgb(51,51,51);\n"
                                   "}")
        self.bn_east.setAutoDefault(False)

        self.gridLayout.addWidget(self.bn_east, 1, 3, 1, 1)

        self.lab_icon = QLabel(self.frame_bottom)
        self.lab_icon.setObjectName(u"lab_icon")
        self.lab_icon.setMinimumSize(QSize(40, 40))
        self.lab_icon.setMaximumSize(QSize(40, 40))

        self.gridLayout.addWidget(self.lab_icon, 0, 0, 1, 1)

        self.bn_west = QPushButton(self.frame_bottom)
        self.bn_west.setObjectName(u"bn_west")
        self.bn_west.setMinimumSize(QSize(69, 25))
        self.bn_west.setMaximumSize(QSize(69, 25))
        self.bn_west.setFont(font1)
        self.bn_west.setStyleSheet(u"QPushButton {\n"
                                   "	border: 2px solid rgb(51,51,51);\n"
                                   "	border-radius: 5px;	\n"
                                   "	color:rgb(255,255,255);\n"
                                   "	background-color: rgb(51,51,51);\n"
                                   "}\n"
                                   "QPushButton:hover {\n"
                                   "	border: 2px solid rgb(0,143,150);\n"
                                   "	background-color: rgb(0,143,150);\n"
                                   "}\n"
                                   "QPushButton:pressed {	\n"
                                   "	border: 2px solid rgb(0,143,150);\n"
                                   "	background-color: rgb(51,51,51);\n"
                                   "}")
        self.bn_west.setAutoDefault(False)

        self.gridLayout.addWidget(self.bn_west, 1, 2, 1, 1)

        self.lab_message = QLabel(self.frame_bottom)
        self.lab_message.setObjectName(u"lab_message")
        self.lab_message.setFont(font1)
        self.lab_message.setStyleSheet(u"color:rgb(255,255,255);")
        self.lab_message.setWordWrap(True)

        self.gridLayout.addWidget(self.lab_message, 0, 1, 1, 3)

        self.verticalLayout_2.addWidget(self.frame_bottom)

        self.verticalLayout.addWidget(self.frame_2)

        self.retranslateUi(Dialog)

        QMetaObject.connectSlotsByName(Dialog)

    # setupUi

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(
            QCoreApplication.translate("Dialog", u"Dialog", None))
        self.lab_heading.setText("")
        self.bn_min.setText("")
        self.bn_close.setText("")
        self.bn_east.setText("")
        self.lab_icon.setText("")
        self.bn_west.setText("")
        self.lab_message.setText("")
Ejemplo n.º 14
0
    def _setup_ui(self):
        self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)
        layout = QVBoxLayout(self)
        self.setLayout(layout)
        layout.setSpacing(2)

        # Create a horizontal widget to hold the Write W settings on the left, and
        # the computer register displays on the right
        upper_displays = QWidget(self)
        upper_layout = QHBoxLayout(upper_displays)
        upper_displays.setLayout(upper_layout)
        upper_layout.setMargin(0)
        upper_layout.setSpacing(1)
        layout.addWidget(upper_displays)

        self._write_w = WriteW(upper_displays, self._usbif)
        upper_layout.addWidget(self._write_w)
        upper_layout.setAlignment(self._write_w, Qt.AlignRight)

        regs = QWidget(upper_displays)
        regs_layout = QVBoxLayout(regs)
        regs.setLayout(regs_layout)
        regs_layout.setSpacing(2)
        regs_layout.setMargin(0)
        regs_layout.addSpacing(25)
        upper_layout.addWidget(regs)
        upper_layout.setAlignment(regs, Qt.AlignTop)

        # Add all of the registers for display
        self._reg_a = Register(regs, self._usbif, 'A', False,
                               QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_a)
        regs_layout.setAlignment(self._reg_a, Qt.AlignRight)

        self._reg_l = Register(regs, self._usbif, 'L', False,
                               QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_l)
        regs_layout.setAlignment(self._reg_l, Qt.AlignRight)

        # self._reg_q = Register(regs, self._usbif, 'Q', False, QColor(0,255,0))
        # regs_layout.addWidget(self._reg_q)
        # regs_layout.setAlignment(self._reg_q, Qt.AlignRight)

        self._reg_z = Register(regs, self._usbif, 'Z', False,
                               QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_z)
        regs_layout.setAlignment(self._reg_z, Qt.AlignRight)

        # self._reg_b = Register(regs, self._usbif, 'B', False, QColor(0,255,0))
        # regs_layout.addWidget(self._reg_b)
        # regs_layout.setAlignment(self._reg_b, Qt.AlignRight)

        self._reg_g = Register(regs, self._usbif, 'G', True, QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_g)
        regs_layout.setAlignment(self._reg_g, Qt.AlignRight)

        self._reg_w = Register(regs, self._usbif, 'W', True, QColor(0, 255, 0))
        regs_layout.addWidget(self._reg_w)
        regs_layout.setAlignment(self._reg_w, Qt.AlignRight)

        self._w_cmp = WComparator(regs, self._usbif)
        regs_layout.addWidget(self._w_cmp)
        regs_layout.setAlignment(self._w_cmp, Qt.AlignRight)

        self._reg_s = AddressRegister(self, self._usbif, QColor(0, 255, 0))
        layout.addWidget(self._reg_s)
        layout.setAlignment(self._reg_s, Qt.AlignRight)

        s_comp_widget = QWidget(self)
        layout.addWidget(s_comp_widget)
        layout.setAlignment(s_comp_widget, Qt.AlignRight)
        s_comp_layout = QHBoxLayout(s_comp_widget)
        s_comp_layout.setMargin(0)
        s_comp_layout.setSpacing(1)

        s1_s2_widget = QWidget(s_comp_widget)
        s_comp_layout.addWidget(s1_s2_widget)
        s_comp_layout.setAlignment(s1_s2_widget, Qt.AlignRight)
        s1_s2_layout = QVBoxLayout(s1_s2_widget)
        s1_s2_layout.setMargin(0)
        s1_s2_layout.setSpacing(1)

        self._s1 = SComparator(s1_s2_widget, self._usbif, 1)
        s1_s2_layout.addWidget(self._s1)
        s1_s2_layout.setAlignment(self._s1, Qt.AlignRight)

        self._s2 = SComparator(s1_s2_widget, self._usbif, 2)
        s1_s2_layout.addWidget(self._s2)
        s1_s2_layout.setAlignment(self._s2, Qt.AlignRight)

        self._bank_s = BankS(s_comp_widget, self._usbif)
        s_comp_layout.addWidget(self._bank_s)
        s_comp_layout.setAlignment(self._bank_s, Qt.AlignTop | Qt.AlignRight)

        self._reg_i = InstructionRegister(self, self._usbif, QColor(0, 255, 0))
        layout.addWidget(self._reg_i)
        layout.setAlignment(self._reg_i, Qt.AlignRight)

        self._i_comp = IComparator(self, self._usbif)
        layout.addWidget(self._i_comp)
        layout.setAlignment(self._i_comp, Qt.AlignRight)

        lower_controls = QWidget(self)
        lower_layout = QHBoxLayout(lower_controls)
        lower_controls.setLayout(lower_layout)
        lower_layout.setMargin(0)
        lower_layout.setSpacing(1)
        layout.addWidget(lower_controls)

        control_stop = QWidget(lower_controls)
        control_stop_layout = QVBoxLayout(control_stop)
        control_stop.setLayout(control_stop_layout)
        control_stop_layout.setSpacing(2)
        control_stop_layout.setMargin(0)
        lower_layout.addWidget(control_stop, Qt.AlignTop)

        # Add the control panel
        self._ctrl_panel = Control(control_stop, self._usbif)
        control_stop_layout.addWidget(self._ctrl_panel)
        control_stop_layout.setAlignment(self._ctrl_panel, Qt.AlignRight)

        # Add the computer stop panel
        self._comp_stop = CompStop(control_stop, self._usbif)
        control_stop_layout.addWidget(self._comp_stop)
        control_stop_layout.setAlignment(self._comp_stop, Qt.AlignRight)

        self._read_load = ReadLoad(self, self._usbif)
        lower_layout.addWidget(self._read_load)
        lower_layout.setAlignment(self._read_load, Qt.AlignTop)
Ejemplo n.º 15
0
class Window(QMainWindow):
    """Class to create main widnow

    Creates main window for displaying frame read from a connected camera.
    The main window contains memu bar, tool bar, status bar, sliders and the
    boxes showing the camera's information. These widget are created and added to
    main window in the instance method of this class.

    """
    def __init__(
            self, device: int = 0, suffix: str = "png", camtype: str = "usb_cam",
            color: str = "RGB", dst: str = ".", param: str = "full",
            rule: str = "Sequential", parent=None):
        super(Window, self).__init__(parent)
        self.device = device
        self.camtype = camtype
        self.colorspace = color
        self.image_suffix = suffix
        self.video_codec = "AVC1"
        self.video_suffix = "avi"
        self.dst = Path(dst)
        self.parent_dir = Path(__file__).parent.resolve()

        self.filename_rule_lst = FileIO.file_save
        self.filename_rule = FileIO.file_save_lst[-1]

        self.is_display = True
        self.param_separate = False

        self.slot = Slot(self)

        cam = self.get_cam()
        self.camera = cam(self.device, self.colorspace, parent=self)
        self.support_params = self.camera.get_supported_params()
        self.current_params = self.camera.get_current_params(param)

        # List of camera properties with temporal initial values
        self.prop_table = [
            ["Fourcc", "aa"],
            ["Width", 640],
            ["Height", 480],
            ["FPS", 30.0],
            ["Bit depth", 8],
            ["File naming style", self.filename_rule]
        ]
        self.setup()
        self.set_timer()

    def get_cam(self) -> str:
        """Return camera object according to current OS.

        Detects what OS you are using, return camera objects  in order to function properly.

            - Linux: LinuxCamera
            - RaspberryPi OS: RaspiCamera
            - Windows: WindowsCamera

        Returns:
            Camera class
        """
        if self.camtype == "raspi":
            return RaspiCamera

        self.system = platform.system()
        if re.search("linux", self.system, re.IGNORECASE):
            return LinuxCamera
        elif re.search("windows", self.system, re.IGNORECASE):
            return WindowsCamera
        else:
            return "Unknown type"

    def setup(self):
        """Setup the main window for displaying frame and widget.

        Creates a QMainWindow object, then add menubar, toolbar, statusbar, widgets and layout
        into the window.
        """
        self.setFocusPolicy(Qt.ClickFocus)
        self.setContentsMargins(20, 0, 20, 0)
        self.information_window_setup()
        self.view_setup()
        self.layout_setup()
        self.image_setup()
        self.toolbar_setup()
        self.setWindowTitle("usbcamGUI")
        self.update_prop_table()
        self.adjust_windowsize()
        self.set_theme()

    def adjust_windowsize(self):
        """Adjusts the main window size
        """
        system = Utility.get_os()
        if system == "linux":
            w, h, _ = self.get_screensize()
            wscale = 0.5
            hscale = 0.7
            self.resize(wscale * w, hscale * h)
        else:
            self.resize(800, 600)

    def set_theme(self):
        """Set color theme of the main window.
        """
        self.style_theme = "light"
        self.style_theme_sheet = ":/{}.qss".format(self.style_theme)
        self.slot.switch_theme()
        self.set_font(self.camera.font_family, self.camera.font_size)

    def set_font(self, family: str = "Yu Gothic", size: int = 14):
        """Sets font-family and size of UI.

        Args:
            family (str, optional): Font-family. Defaults to "Yu Gothic".
            size (int, optional): Font-size. Defaults to 20.
        """
        self.setStyleSheet('font-family: "{}"; font-size: {}px;'.format(family, size))

    def set_timer(self):
        """Set QTimer

        Creates a QTimer object to update frame on view area. The interval is set to the inverse
        of camera FPS.
        """
        self.qtime_factor = 0.8
        self.fps = 30.0
        if self.fps:
            self.msec = 1 / self.fps * 1000 * self.qtime_factor
        else:
            self.msec = 1 / 30.0 * 1000 * self.qtime_factor
        self.timer = QTimer()
        self.timer.setInterval(self.msec)
        self.timer.timeout.connect(self.next_frame)
        self.timer.start()

    def stop_timer(self):
        """Deactivate the Qtimer object.
        """
        self.timer.stop()

    def start_timer(self):
        """Activate the Qtimer object.
        """
        self.fps = 30.0
        if self.fps:
            self.msec = 1 / self.fps * 1000 * self.qtime_factor
        else:
            self.msec = 1 / 30.0 * 1000 * self.qtime_factor
        self.timer.setInterval(self.msec)
        self.timer.start()

    def toolbar_setup(self):
        """Create toolbar
        """
        self.toolbar = QToolBar("test", self)
        self.addToolBar(self.toolbar)

        current_size = str(self.font().pointSize())
        lst = [str(i) for i in range(6, 14)]
        lst.extend([str(i) for i in range(14, 40, 2)])
        index = lst.index(current_size)

        self.fontsize_combo = QComboBox()
        self.fontsize_combo.addItems(lst)
        self.fontsize_combo.setCurrentIndex(index)
        self.fontsize_combo.currentTextChanged.connect(self.slot.set_fontsize)
        self.fontsize_label = QLabel("Font size")
        self.fontsize_label.setFrameShape(QFrame.Box)

        self.comb = QFontComboBox()

        self.toolbar.addWidget(self.save_button)
        self.toolbar.addWidget(self.stop_button)
        self.toolbar.addWidget(self.rec_button)
        self.toolbar.addWidget(self.close_button)
        self.toolbar.addWidget(self.theme_button)
        self.toolbar.addWidget(self.help_button)
        self.toolbar.addWidget(self.fontsize_label)
        self.toolbar.addWidget(self.fontsize_combo)
        self.toolbar.setStyleSheet(
            """
            QToolBar {spacing:5px;}
            """
            )

    def view_setup(self):
        """Set view area to diplay read frame in part of the main window
        """
        self.view = QGraphicsView()
        self.scene = QGraphicsScene()
        self.view.setScene(self.scene)
        self.width = 640
        self.height = 480
        self.scene.setSceneRect(0, 0, self.width, self.height)
        self.view.setMouseTracking(True)
        self.view.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        self.view.setCacheMode(QGraphicsView.CacheBackground)
        self.view.setViewportUpdateMode(QGraphicsView.SmartViewportUpdate)

    def layout_setup(self):
        """Set layout of objects on the window.
        """
        self.window = QWidget()
        self.setCentralWidget(self.window)
        #self.view.mouseMoveEvent = self.get_coordinates

        self.main_layout = QHBoxLayout()
        self.window.setLayout(self.main_layout)

        self.add_actions()
        self.add_menubar()
        self.add_statusbar()
        self.button_block = self.add_buttons()
        self.slider_group = self.add_params()
        self.prop_block = self.add_prop_window()
        self.create_mainlayout()

    def image_setup(self):
        """Creates a Qimage to assign frame, then initialize with an image which has zero in all pixels.
        """
        self.frame = np.zeros((640, 480, 3), dtype=np.uint8)
        #cinit = np.ctypeslib.as_ctypes(self.frame)
        #self.frame.buffer = sharedctypes.RawArray(cinit._type_, cinit)
        self.qimage = QImage(
            self.frame.data,
            640,
            480,
            640 * 3,
            QImage.Format_RGB888
            )
        self.pixmap = QPixmap.fromImage(self.qimage)

    def add_actions(self):
        """Add actions executed when press each item in the memu window.
        """
        self.save_act = self.create_action("&Save", self.save_frame, "Ctrl+s")
        self.stop_act = self.create_action("&Pause", self.stop_frame, "Ctrl+p", checkable=True)
        self.rec_act = self.create_action("&Record", self.record, "Ctrl+r", True)
        self.quit_act = self.create_action("&Quit", self.slot.quit, "Ctrl+q")

        self.theme_act = self.create_action("Switch &Theme", self.slot.switch_theme, "Ctrl+t")
        self.param_act = self.create_action("Choose parameter slider", self.slot.switch_paramlist, "Ctrl+g")
        self.show_paramlist_act = self.create_action("Parameters &List", self.slot.show_paramlist, "Ctrl+l")
        self.show_shortcut_act = self.create_action("&Keybord shortcut", self.slot.show_shortcut, "Ctrl+k")
        self.font_act = self.create_action("&Font", self.slot.set_font, "Ctrl+f")

        self.usage_act = self.create_action("&Usage", self.slot.usage, "Ctrl+h")
        self.about_act = self.create_action("&About", self.slot.about, "Ctrl+a")

    def create_action(self, text: str, slot: Callable, key: str = None, checkable: bool = False,
        check_defalut: bool = False) -> QAction:
        """Create a QAction object.

        Args:
            text (str): Text shown on menu.
            slot (Callable): A method called when click the menu.
            key (str, optional): Shortcut key. Defaults to None.
            checkable (bool, optional): Add a checkbox into the menu. Defaults to False.
            check_defalut (bool, optional): Check default status. Defaults to False.

        Returns:
            QAction: PySide2 QAction
        """
        act = QAction(text)
        act.setShortcut(key)
        if checkable:
            act.setCheckable(True)
            act.setChecked(check_defalut)
            act.toggled.connect(slot)
        else:
            act.triggered.connect(slot)

        return act

    def add_menubar(self):
        """Create menu bar, then add to the main window.
        """
        self.menubar = QMenuBar()
        self.setMenuBar(self.menubar)

        self.file_tab = QMenu("&File")
        self.file_tab.addAction(self.save_act)
        self.file_tab.addAction(self.stop_act)
        self.file_tab.addAction(self.rec_act)
        self.file_tab.addSeparator()
        self.file_tab.addAction(self.quit_act)
        #self.file_tab.setSizePolicy(policy)

        self.view_tab = QMenu("&View")
        self.view_tab.addAction(self.theme_act)
        self.view_tab.addAction(self.font_act)
        self.view_tab.addAction(self.param_act)
        self.view_tab.addAction(self.show_shortcut_act)
        self.view_tab.addAction(self.show_paramlist_act)

        self.help_tab = QMenu("&Help")
        self.help_tab.addAction(self.usage_act)
        self.help_tab.addAction(self.about_act)

        self.menubar.addMenu(self.file_tab)
        self.menubar.addMenu(self.view_tab)
        self.menubar.addMenu(self.help_tab)
        self.menubar.setStyleSheet(
            """
            QMenuBar {
                    font-size: 16px;
                    spacing:10px;
                    padding-top: 5px;
                    padding-bottom: 10px;
                }
            """
            )

    def add_statusbar(self):
        """Create status bar, then add to the main window.

        The status bar shows the coordinates on the frame where the cursor is located and
        its pixel value. The pixel value has RGB if the format of is color (RGB), does grayscale
        value if grayscale.
        """
        self.statbar_list = []
        if self.colorspace == "rgb":
            self.stat_css = {
                "postion": "color: white",
                "R": "color: white;",
                "G": "color: white;",
                "B": "color: white;",
                "alpha": "color: white;",
            }
        else:
            self.stat_css = {
                "postion": "color: black;",
                "gray": "color: black"
            }

        for s in self.stat_css.values():
            stat = QStatusBar(self)
            stat.setStyleSheet(s)
            self.statbar_list.append(stat)

        first = True
        for stat in self.statbar_list:
            if first:
                self.setStatusBar(stat)
                self.statbar_list[0].reformat()
                first = False
            else:
                self.statbar_list[0].addPermanentWidget(stat)

    def add_buttons(self):
        """Add push buttons on the window.

        Add quit, save stop and usage buttons on the windows. When press each button, the set
        method (called "slot" in Qt framework) are execeuted.
        """
        self.save_button = self.create_button("&Save", self.save_frame, None, None, "Save the frame")
        self.stop_button = self.create_button("&Pause", self.stop_frame, None, None, "Stop reading frame", True)
        self.rec_button = self.create_button("&Rec", self.record, None, None, "Start recording", True)
        self.close_button = self.create_button("&Quit", self.slot.quit, None, None, "Quit the program")
        self.theme_button = self.create_button("Light", self.slot.switch_theme, None, None, "Switche color theme")
        self.help_button = self.create_button("&Usage", self.slot.usage, None, None, "Show usage")

        self.frame_button = self.create_button(
            "Properties",
            self.slot.change_frame_prop,
            None,
            tip="Change properties",
            minsize=(150, 30)
            )
        self.default_button = self.create_button(
            "&Default params",
            self.set_param_default,
            "Ctrl+d",
            tip="Set default parameters",
            minsize=(150, 30)
            )
        self.filerule_button = self.create_button(
            "&Naming style",
            self.slot.set_file_rule,
            "Ctrl+n",
            tip="Change naming style",
            minsize=(150, 30)
            )

        hbox = QHBoxLayout()
        hbox.addWidget(self.save_button)
        hbox.addWidget(self.stop_button)
        hbox.addWidget(self.rec_button)
        hbox.addWidget(self.close_button)
        hbox.addWidget(self.theme_button)
        hbox.addWidget(self.help_button)
        return hbox

    def create_button(self, text: str, slot: Callable, key: str = None, icon: Icon = None,
        tip: str = None, checkable: bool = False, minsize: tuple = None) -> QPushButton:
        """Create a QPushButton object.

        Args:
            text (str): Text shown on the button.
            slot (Callable): A method called when click the button.
            key (str, optional): Shortcut key. Defaults to None.
            icon (Icon, optional): An icon shown on the button. Defaults to None.
            tip (str, optional): A tips shown when position the pointer on the button. Defaults to None.
            checkable (bool, optional): Add button to checkbox. Defaults to False.
            msize (tuple, optional): Minimum size of the button box, (width, height).

        Returns:
            QPushButton: PySide2 QPushButton
        """
        button = QPushButton(text)
        if checkable:
            button.setCheckable(True)
            button.toggled.connect(slot)
        else:
            button.clicked.connect(slot)

        if key:
            button.setShortcut(key)
        if icon:
            button.setIcon(QIcon(icon))
        if tip:
            button.setToolTip(tip)
        if minsize:
            button.setMinimumSize(minsize[0], minsize[1])
        else:
            button.setMinimumSize(80, 30)
        return button

    def add_params(self) -> QGridLayout:
        """Set the properties of camera parameter.

        Set the properties of camera parameter, then add sliders to change each parameter.
        When change value on the slider, the value of paramter also changes by the caller
        function.

        """
        lst = self.current_params
        for key, value in lst.items():
            self.add_slider(key)

        # add sliders
        self.slider_table = QGridLayout()
        self.slider_table.setSpacing(15)
        self.slider_table.setContentsMargins(20, 20, 20, 20)
        for row, param in enumerate(self.current_params):
            self.slider_table.addWidget(self.current_params[param]["slider_label"], row, 0)
            self.slider_table.addWidget(self.current_params[param]["slider"], row, 1)
            self.slider_table.addWidget(self.current_params[param]["slider_value"], row, 2)
        if len(self.current_params) > 15:
            self.param_separate = True
        else:
            self.param_separate = False
        return self.slider_table

    def update_params(self, plist: list) -> QGridLayout:
        """Update camera's paramters and sliders shown on the windows.
        """
        #self.current_params.clear()
        self.current_params = self.camera.get_current_params("selected", plist)
        for key, value in self.current_params.items():
            self.add_slider(key)

        # add sliders
        grid = QGridLayout()
        grid.setSpacing(15)
        grid.setContentsMargins(20, 20, 20, 20)
        for row, param in enumerate(self.current_params):
            grid.addWidget(self.current_params[param]["slider_label"], row, 0)
            grid.addWidget(self.current_params[param]["slider"], row, 1)
            grid.addWidget(self.current_params[param]["slider_value"], row, 2)
        if len(self.current_params) > 15:
            self.param_separate = True
        else:
            self.param_separate = False
        self.slider_group = grid
        self.update_mainlayout()
        self.update_prop_table()
        self.write_text("update sliders")
        return grid

    def add_slider(self, param: str):
        """Creates slider, labels to show pamarater's name and its value.

        Args:
            param (str): A parameter to create slider.
        """
        min_ = self.current_params[param]["min"]
        max_ = self.current_params[param]["max"]
        step = self.current_params[param]["step"]
        value = self.current_params[param]["value"]

        slider = QSlider(Qt.Horizontal)
        if max_:
            slider.setRange(min_, max_)
        else:
            slider.setRange(0, 1)
        slider.setValue(int(value))
        slider.setTickPosition(QSlider.TicksBelow)
        slider.valueChanged.connect(lambda val, p=param: self.set_sliderval(p, val))

        if step:
            if max_ < 5:
                slider.setTickInterval(step)
            else:
                slider.setTickInterval(10)

        slider_label = QLabel(param)
        slider_value = QLabel(str(value))

        slider_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        slider_value.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)

        self.current_params[param]["slider"] = slider
        self.current_params[param]["slider_label"] = slider_label
        self.current_params[param]["slider_value"] = slider_value

    def add_prop_window(self) -> QGridLayout:
        """Create a table to show the current properties of camera.

        Returns:
            QGridLayout: PySide2 QGridLayout
        """
        header = ["property", "value"]
        self.prop_table_widget = QTableWidget(self)
        self.prop_table_widget.setColumnCount(len(header))
        self.prop_table_widget.setRowCount(len(self.prop_table))

        self.prop_table_widget.setHorizontalHeaderLabels(header)
        self.prop_table_widget.verticalHeader().setVisible(False)
        self.prop_table_widget.setAlternatingRowColors(True)
        self.prop_table_widget.horizontalHeader().setStretchLastSection(True)
        self.prop_table_widget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.prop_table_widget.setFocusPolicy(Qt.NoFocus)

        for row, content in enumerate(self.prop_table):
            for col, elem in enumerate(content):
                self.item = QTableWidgetItem(elem)

                self.prop_table_widget.setItem(row, col, self.item)
        self.prop_table_widget.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        #self.prop_table_widget.resizeColumnsToContents()
        #self.prop_table_widget.resizeRowsToContents()
        self.prop_table_widget.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.prop_table_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.prop_table_widget.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.prop_table_widget.setColumnWidth(0, 150)
        self.prop_table_widget.setColumnWidth(1, 150)

        vbox = QVBoxLayout()
        vbox.addWidget(self.prop_table_widget)
        vbox.setContentsMargins(20, 20, 20, 20)
        self.prop_group = QGroupBox("Frame Properties")
        self.prop_group.setLayout(vbox)
        return self.prop_group

    def information_window_setup(self):
        """Creates information window.

        Creates the information window where the event related to camera or window.
        """
        self.text_edit = QTextEdit()
        self.text_edit.setReadOnly(True)
        self.text_edit.show()
        vbox = QVBoxLayout()
        vbox.addWidget(self.text_edit)
        self.text_edit_box = QGroupBox("Information", self)
        self.text_edit_box.setLayout(vbox)
        self.text_edit_box.setAlignment(Qt.AlignLeft)

    def create_mainlayout(self):
        """Create the main layout which consists of view area and information window.
        """
        self.main_layout.addLayout(self.create_view_area_layout())
        self.main_layout.addLayout(self.create_information_layout())

    def update_mainlayout(self):
        """Recreate the main layout.
        """
        self.delete_layout(self.information_layout)
        self.delete_layout(self.upper_right)
        self.add_prop_window()
        self.main_layout.addLayout(self.create_information_layout())

    def delete_layout(self, layout):
        """Delete layout

        Args:
            layout (QBoxLayout): QBoxLayout class object to delete
        """
        while layout.count():
            child = layout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()
            try:
                child.spacerIitem().deleteLater()
            except:
                pass

    def create_view_area_layout(self) -> QVBoxLayout:
        """Creates view area layout
        """
        self.view_area_layout = QVBoxLayout()
        self.view_area_layout.addWidget(self.view, 2)
        self.view_area_layout.addWidget(self.text_edit_box)
        return self.view_area_layout

    def create_information_layout(self):
        """Creates information part layout

        upper-left: current properties
        upper-right: buttons
        lower: sliders
        """
        if self.param_separate:
            self.entry_box = QVBoxLayout()
            self.entry_box.addWidget(self.frame_button)
            self.entry_box.addWidget(self.filerule_button)
            self.entry_box.addWidget(self.default_button)
            self.entry_box.addStretch(1)
            self.entry_box.setSpacing(20)
            self.entry_box.setContentsMargins(20, 20, 20, 20)

            self.button_group_box = QGroupBox("Buttons", self)
            self.button_group_box.setLayout(self.entry_box)
            self.button_group_box.setAlignment(Qt.AlignLeft)

            self.upper_right = QVBoxLayout()
            self.upper_right.addWidget(self.prop_group, 1)
            self.upper_right.addWidget(self.button_group_box, 1)

            self.slider_group_box = QGroupBox("Parameters")
            self.slider_group_box.setLayout(self.slider_group)
            self.slider_group_box.setContentsMargins(20, 20, 20, 20)

            self.information_layout = QHBoxLayout()
            self.information_layout.addLayout(self.upper_right, 1)
            self.information_layout.addWidget(self.slider_group_box, 2)
            #self.information_layout.addStretch(1)
            return self.information_layout
        else:
            self.entry_box = QVBoxLayout()
            self.entry_box.addWidget(self.frame_button)
            self.entry_box.addWidget(self.filerule_button)
            self.entry_box.addWidget(self.default_button)
            self.entry_box.addStretch(1)
            self.entry_box.setSpacing(20)
            self.entry_box.setContentsMargins(20, 20, 20, 20)

            self.button_group_box = QGroupBox("Buttons", self)
            self.button_group_box.setLayout(self.entry_box)
            self.button_group_box.setAlignment(Qt.AlignLeft)

            self.upper_right = QHBoxLayout()
            self.upper_right.addWidget(self.prop_group)
            self.upper_right.addWidget(self.button_group_box)

            self.slider_group_box = QGroupBox("Parameters")
            self.slider_group_box.setLayout(self.slider_group)
            self.slider_group_box.setContentsMargins(20, 20, 20, 20)

            self.information_layout = QVBoxLayout()
            self.information_layout.addLayout(self.upper_right)
            self.information_layout.addWidget(self.slider_group_box)
            self.information_layout.setSpacing(30)
            return self.information_layout

    # decorator
    def display(func):
        def wrapper(self, *args, **kwargs):
            try:
                self.is_display = False
                self.stop_timer()
                func(self, *args, **kwargs)
            finally:
                self.is_display = True
                self.start_timer()
        return wrapper

    def stop_frame(self, checked: bool):
        """Stop reading next frame.

        Args:
            checked (bool): True when presse the Stop button (toggle on). False when press
                again (toggel off).
        """
        if checked:
            self.write_text("Stop !!")
            self.is_display = False
            self.stop_button.setText('Start')
            self.stop_button.setChecked(True)
            self.stop_act.setText('Start')
            self.stop_act.setChecked(True)
        else:
            self.write_text("Start !!")
            self.is_display = True
            self.stop_button.setText('&Pause')
            self.stop_button.setChecked(False)
            self.stop_act.setText('&Pause')
            self.stop_act.setChecked(False)

    def keyPressEvent(self, event):
        """Exit the program

        This method will be called when press the Escape key on the window.
        """
        if event.key() == Qt.Key_Escape:
            QApplication.quit()

    def get_coordinates(self, event):
        """Show the current coordinates and value in the pixel where the cursor is located.

        The status bar is updates by the obtained values.
        """
        if self.item is self.view.itemAt(event.pos()):
            sp = self.view.mapToScene(event.pos())
            lp = self.item.mapFromScene(sp).toPoint()
            (x, y) = lp.x(), lp.y()
            #color = self.frame.image.pixel(x, y)
            color = self.qimage.pixelColor(x, y)
            if self.colorspace == "rgb":
                value = color.getRgb()
            elif self.colorspace == "gray":
                value = color.value()

            # Return none if the coordinates are out of range
            if x < 0 and self.frame.width < x:
                return
            elif y < 0 and self.frame.height < y:
                return

            if self.frame.img_is_rgb:
                status_list = [
                    "( x : {}, y :{} )".format(x, y),
                    "R : {}".format(value[0]),
                    "G : {}".format(value[1]),
                    "B : {}".format(value[2]),
                    "alpha : {}".format(value[3])
                ]
            else:
                status_list = [
                    "( x : {}, y :{} )".format(x, y),
                    "gray value : {}".format(value),
                ]

            for statbar, stat in zip(self.statbar_list, status_list):
                statbar.showMessage(stat)

    def next_frame(self):
        """Get next frame from the connected camera.

        Get next frame, set it to the view area and update.
        """
        #print("display :", self.is_display)
        if self.is_display:
            self.camera.read_frame()
            self.convert_frame()
            self.scene.clear()
            self.scene.addPixmap(self.pixmap)
            self.update()
            #print("update")

    def convert_frame(self):
        """Convert the class of frame

        Create qimage, qpixmap objects from ndarray frame for displaying on the window.

        """
        if self.colorspace == "rgb":
            self.qimage = QImage(
                self.camera.frame.data,
                self.camera.frame.shape[1],
                self.camera.frame.shape[0],
                self.camera.frame.shape[1] * 3,
                QImage.Format_RGB888
                )
        elif self.colorspace == "gray":
            self.qimage = QImage(
                self.camera.frame.data,
                self.camera.frame.shape[1],
                self.camera.frame.shape[0],
                self.camera.frame.shape[1] * 1,
                QImage.Format_Grayscale8)

        self.pixmap.convertFromImage(self.qimage)

    def save_frame(self):
        """Save the frame on the window as an image.
        """
        if self.filename_rule == "Manual":
            self.save_frame_manual()
            if not self.filename:
                return None
            prm = re.sub(r"\.(.*)", ".csv", str(self.filename))
        else:
            self.filename = FileIO.get_filename(self.filename_rule, self.image_suffix, self.parent_dir)
            prm = str(self.filename).replace(self.image_suffix, "csv")

        if not self.dst.exists():
            self.dst.mkdir(parents=True)
        im = Image.fromarray(self.camera.frame)
        im.save(self.filename)

        # make a parameter file
        with open(prm, "w") as f:
            for name, key in self.current_params.items():
                f.write("{},{}\n".format(name, self.current_params[name]["value"]))

        self.write_text("{:<10}: {}".format("save image", self.filename))
        self.write_text("{:<10}: {}".format("save param", prm))

    def update_prop_table(self):
        """Updates the table that shows the camera properties.
        """
        w, h, cc, f = self.camera.get_properties()
        self.prop_table = [
            ["Fourcc", cc],
            ["Width", int(w)],
            ["Height", int(h)],
            ["FPS", "{:.1f}".format(f)],
            ["Bit depth", 8],
            ["Naming Style", self.filename_rule]
        ]
        col = 1
        for row in range(len(self.prop_table)):
            text = str(self.prop_table[row][col])
            self.prop_table_widget.item(row, col).setText(text)

    def record(self):
        """Start or end recording
        """
        if self.camera.is_recording:
            self.camera.stop_recording()
            self.rec_button.setText('&Rec')
            self.rec_act.setText('&Record')
            self.write_text("save : {}".format(self.video_filename))
        else:
            self.video_filename = FileIO.get_filename(self.filename_rule, self.video_suffix, self.parent_dir)
            self.camera.start_recording(self.video_filename, self.video_codec)
            self.rec_button.setText('Stop rec')
            self.rec_act.setText('Stop record')

    @display
    def save_frame_manual(self) -> bool:
        """Determine file name of image to save with QFileDialog
        """
        self.dialog = QFileDialog()
        self.dialog.setWindowTitle("Save File")
        self.dialog.setNameFilters([
            "image (*.jpg *.png *.tiff *.pgm)",
            "All Files (*)"
            ])
        self.dialog.setAcceptMode(QFileDialog.AcceptSave)
        self.dialog.setOption(QFileDialog.DontUseNativeDialog)

        if self.dialog.exec_():
            r = self.dialog.selectedFiles()

            # If the file name doesn't include supproted suffixes, add to the end.
            if re.search(".pgm$|.png$|.jpg$|.tiff$", r[0]):
                self.filename = r[0]
            else:
                self.filename = "{}.{}".format(r[0], self.image_suffix)
            return True
        else:
            return False

    def get_screensize(self):
        """Get current screen size from the output of linux cmd `xrandr`.
        """
        cmd = ["xrandr"]
        ret = subprocess.check_output(cmd)
        output = ret.decode()
        pattern = r"current(\s+\d+\s+x\s+\d+)"

        m = re.search(pattern, output)
        if m:
            size = re.sub(" ", "", m.group(1))
            w, h = map(int, size.split("x"))
            return w, h, size
        else:
            return None

    def set_sliderval(self, param: str, value: int):
        """Changes a camera parameter.

        Updates the label on the right of the slider if input value is valid.

        Args:
            param (str): A camera parameter
            value (int): its value
        """
        val = self.camera.set_parameter(param, value)
        self.current_params[param]["value"] = str(val)
        self.current_params[param]["slider_value"].setText(str(value))

    def set_param_default(self):
        """Sets all paramters to default.
        """
        for param, values in self.current_params.items():
            default = values["default"]
            self.camera.set_parameter(param, default)
            self.current_params[param]["slider"].setValue(int(default))
            self.current_params[param]["slider_value"].setText(str(default))

    def get_properties(self) -> list:
        """Get the current camera properties.

        Returns:
            list: parameters. fourcc, width, height, fps.
        """
        tmp = []
        for row in range(4):
            tmp.append(self.prop_table[row][1])
        return tmp

    def write_text(self, text: str, level: str = "info", color: str = None):
        """Writes the message into information window.

        Args:
            text (str): A text to write.
            level (str, optional): Log lebel of the message. Defaults to "info".
            color (str, optional): Font color. Defaults to None.
        """
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
        now = now[:-3]
        if color == "red":
            form = f"<font color='red'>[{level.upper():<4} {now}] {text}</font>"
        elif color == "yellow":
            form = f"<font color='yellow'>[{level.upper():<4} {now}] {text}</font>"
        else:
            form = f"[{level.upper():<4} {now}] {text}"
        self.text_edit.append(form)
Ejemplo n.º 16
0
class QFramelessWindow(QWidget):
    """
    无边框窗口类
    """
    def __init__(self):
        super(QFramelessWindow,
              self).__init__(None, Qt.FramelessWindowHint)  # 设置为顶级窗口,无边框

        # ----------------属性值------------#
        self._m_window_width = 1000  # type: int  # 默认窗口的宽度
        self._m_window_height = 900  # type: int  # 默认窗口的高度
        self._m_window_minimum_width = 250  # type: int  # 最小窗口宽度
        self._m_window_minimum_height = 200  # type: int  # 最小窗口高度
        self._m_padding = 5  # type: int  # 边界宽度
        self._m_title_text = '无边框窗口'  # type: str  # 窗口标题文字
        self._m_icon_path = ''  # type: str # 窗口图标所在的路径
        self._m_title_height = 60  # type: int  # 窗口标题栏的高度
        self._m_title_text_width = 40  # type: int  # 标题文字所占的宽度
        self._m_title_label = QTitleLabel(self)  # type: QTitleLabel  # 用于显示标题
        self._m_title_position = 0  # type: int  # 标题的相对位置:0 - 靠左,1 - 水平居中
        self._m_status_label = QStatusLabel(self)
        self._m_status_time_label = QStatusTimeLabel(self)  #  右下角显示日期时间的label

        # 设置鼠标跟踪判断扳机默认值
        self._m_move_drag = False
        self._m_corner_drag = False
        self._m_bottom_drag = False
        self._m_right_drag = False

        self._m_close_btn = None  # type: QTitleButton  # 右上角的关闭按钮
        self._m_minimum_btn = None  # type: QTitleButton  # 右上角的最小化按钮
        self._m_maximum_btn = None  # type: QTitleButton  # 右上角的最大化按钮,有两种状态:最大化、回复正常

        self._m_main_layout = QVBoxLayout()

        self.setMinimumSize(self._m_window_minimum_width,
                            self._m_window_minimum_height)
        # 设置窗口居中
        screen_w = QApplication.desktop().screenGeometry().width()
        screen_h = QApplication.desktop().screenGeometry().height()
        self.setGeometry((screen_w - self._m_window_width) / 2,
                         (screen_h - self._m_window_height) / 2,
                         self._m_window_width, self._m_window_height)
        self.setMouseTracking(True)  # 设置widget鼠标跟踪
        self._init_title_label()
        self._init_status_label()

    # -----------------API 接口--------------------------#
    def add_close_button(self):
        """
        在右上角添加关闭按钮
        :return:
        """
        self._m_close_btn = QTitleButton(b'\xef\x81\xb2'.decode("utf-8"), self)

        # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
        self._m_close_btn.setObjectName("CloseButton")
        self._m_close_btn.setToolTip("关闭窗口")
        # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
        self._m_close_btn.setMouseTracking(True)
        # 设置按钮高度为标题栏高度
        self._m_close_btn.setFixedHeight(self._m_title_height)
        # 按钮信号连接到关闭窗口的槽函数
        self._m_close_btn.clicked.connect(self.close)
        # self._m_close_btn.setStyleSheet("QPushButton{background: transparent;}")
        self._m_close_btn.setFlat(True)

    def add_minimum_button(self):
        """
        在右上角添加最小化按钮
        :return:
        """
        self._m_minimum_btn = QTitleButton(b'\xef\x80\xb0'.decode("utf-8"),
                                           self)
        self._m_minimum_btn.setObjectName(
            "MinMaxButton")  # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
        self._m_minimum_btn.setToolTip("最小化")
        self._m_minimum_btn.setMouseTracking(
            True)  # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
        self._m_minimum_btn.setFixedHeight(
            self._m_title_height)  # 设置按钮高度为标题栏高度
        self._m_minimum_btn.clicked.connect(
            self.showMinimized)  # 按钮信号连接到最小化窗口的槽函数
        self._m_minimum_btn.setFlat(True)

    def add_maximum_button(self):
        """
        在右上角添加最大化按钮
        :return:
        """
        self._m_maximum_btn = QTitleButton(b'\xef\x80\xb1'.decode("utf-8"),
                                           self)
        self._m_maximum_btn.setObjectName(
            "MinMaxButton")  # 设置按钮的ObjectName以在qss样式表内定义不同的按钮样式
        self._m_maximum_btn.setToolTip("最大化")
        self._m_maximum_btn.setMouseTracking(
            True)  # 设置按钮鼠标跟踪(如不设,则按钮在widget上层,无法实现跟踪)
        self._m_maximum_btn.setFixedHeight(
            self._m_title_height)  # 设置按钮高度为标题栏高度
        self._m_maximum_btn.clicked.connect(
            self._on_set_window_maximum)  # 按钮信号连接切换到恢复窗口大小按钮函数
        # self._m_maximum_btn.setStyleSheet("QPushButton{background: transparent;}")
        self._m_maximum_btn.setFlat(True)

    def set_window_title(self, title: str) -> None:
        """
        设置窗口的标题
        :param title:标题
        :return:
        """
        f = QFont(QFont('Microsoft YaHei', 14))
        fm = QFontMetrics(f)
        self._m_title_text_width = fm.width(title)
        self._m_title_label.setFont(f)
        self._m_title_label.setText(title)
        self._m_title_text = title
        self.setWindowTitle(title)
        self.update()

    def set_window_icon(self, icon_path: str) -> None:
        """
        设置窗口图标
        :param icon_path: 图标文件所在的路径
        :return:
        """
        self._m_icon_path = icon_path
        self.setWindowIcon(QIcon(icon_path))
        self.update()

    def set_window_title_height(self, height: int) -> None:
        """
        设置窗口标题栏的高度
        :param height: 标题栏高度
        :return: None
        """
        self._m_title_height = height
        self._init_title_label()
        self.set_window_title(self._m_title_text)
        self._m_close_btn.setFixedHeight(self._m_title_height)
        self._m_maximum_btn.setFixedHeight(self._m_title_height)
        self._m_minimum_btn.setFixedHeight(self._m_title_height)
        self.resize(self.size())
        self.update()

    def set_window_title_position(self, position: int) -> None:
        """
        设置标题的位置:1-靠右,2-水平居中
        :param position: 1或2
        :return:
        """
        self._m_title_position = position

    def set_layout(self, widget=None, layout=None) -> None:
        """
        向该无边框窗口中设置控件或布局,只能通过此函数添加控件或布局
        :param widget: 控件
        :param layout: 布局
        :return:
        """
        self._m_main_layout.setContentsMargins(0, 0, 0, 0)
        self._m_main_layout.setSpacing(0)
        self._m_main_layout.addSpacing(self._m_title_height)
        if widget:
            self._m_main_layout.addWidget(widget)
        if layout:
            self._m_main_layout.addLayout(layout)

        self._m_main_layout.addSpacing(self._m_status_label.height())

        self.setLayout(self._m_main_layout)

    def _init_title_label(self) -> None:
        """
        在主窗口界面上安放用于显示标题的label
        :return:
        """
        # 设置标题栏标签鼠标跟踪(如不设,则标题栏内在widget上层,无法实现跟踪)
        self._m_title_label.setMouseTracking(True)
        # 设置标题栏文本缩进
        self._m_title_label.setIndent(10)
        self._m_title_label.setFixedHeight(self._m_title_height)
        # 标题栏安放到左上角
        if self._m_title_position == 0:
            self._m_title_label.move(10, 0)
        else:
            self._m_title_label.move(
                (self.width() - self._m_title_text_width) / 2, 0)

    def set_status_text(self, str='状态栏'):
        self._m_status_label.setText(str)

    def _init_status_label(self):
        """
        创建状态栏
        :return:
        """
        self._m_status_label.setMouseTracking(True)

    # -------------槽函数-----------------#

    def _on_set_window_maximum(self):
        """
        点击了最大化按钮,将窗口最大化
        :return:
        """
        try:
            self.showMaximized()  # 先实现窗口最大化
            self._m_maximum_btn.setText(
                b'\xef\x80\xb2'.decode("utf-8"))  # 更改按钮文本
            self._m_maximum_btn.setToolTip("恢复")  # 更改按钮提示
            self._m_maximum_btn.clicked.disconnect()  # pyside2只能用这种方法
            # self._m_maximum_btn.disconnect()  # 断开原本的信号槽连接   pyqt5 中有效
            self._m_maximum_btn.clicked.connect(
                self._on_set_window_normal)  # 重新连接信号和槽
        except:
            pass

    def _on_set_window_normal(self):
        """
        点击了最大化按钮,将窗口恢复正常大小
        :return:
        """
        try:
            self.showNormal()
            self._m_maximum_btn.setText(b'\xef\x80\xb1'.decode("utf-8"))
            self._m_maximum_btn.setToolTip("最大化")
            self._m_maximum_btn.clicked.disconnect()  # pyside2只能用这种方法
            # self._m_maximum_btn.disconnect()    # pyqt5 中有效
            self._m_maximum_btn.clicked.connect(self._on_set_window_maximum)
        except:
            pass

    # -------------------重载事件响应函数--------------#
    def paintEvent(self, a0: QtGui.QPaintEvent) -> None:
        """
        重载paintEvent函数
        :param a0:
        :return:
        """
        p = QPainter(self)
        p.setRenderHint(QPainter.Antialiasing)
        p.save()
        p.setPen(Qt.NoPen)

        lgt = QLinearGradient(QPointF(0, 0), QPointF(self.width(), 0))
        lgt.setColorAt(0.0, QColor('#511235'))
        lgt.setColorAt(1.0, QColor('red'))
        p.setBrush(lgt)
        p.drawRect(QRectF(0, 0, self.width(), self._m_title_height))
        p.drawRect(
            QRectF(0,
                   self.height() - self._m_status_label.height(),
                   self.rect().width(), self._m_status_label.height()))
        line_pen = QPen()
        line_pen.setColor(QColor(30, 144, 255, 30))
        line_pen.setWidth(1)
        p.setPen(line_pen)
        p.drawLine(0,
                   self.rect().height() - self._m_status_label.height(),
                   self.rect().width(),
                   self.rect().height() - self._m_status_label.height())

        # 在窗口左上角画图标

        if self._m_icon_path:
            imx = QPixmap(self._m_icon_path)
            p.drawPixmap(5, (self._m_title_label.height() - imx.height()) / 2,
                         imx)

        p.restore()

    def resizeEvent(self, QResizeEvent):
        # 将标题标签始终设为窗口宽度
        self._m_title_label.setFixedWidth(self._m_title_text_width * 2)
        if self._m_title_position == 0:
            if self._m_icon_path:
                imx = QPixmap(self._m_icon_path)
                self._m_title_label.move(imx.width() + 5, 0)
        else:
            self._m_title_label.move(
                (self.width() - self._m_title_text_width) / 2, 0)

        self._m_status_label.move(
            0,
            self.rect().height() - self._m_status_label.height())
        self._m_status_label.setFixedWidth(self.rect().width() -
                                           self._m_status_time_label.width())
        self._m_status_time_label.move(
            self._m_status_label.width(),
            self.rect().height() - self._m_status_label.height())
        # 分别移动三个按钮到正确的位置
        try:
            self._m_close_btn.move(
                self.width() - self._m_close_btn.width(),
                (self._m_title_height - self._m_close_btn.height()) / 2)
        except:
            pass
        try:
            self._m_minimum_btn.move(
                self.width() - (self._m_close_btn.width() + 1) * 3 + 1,
                (self._m_title_height - self._m_close_btn.height()) / 2 - 4)
        except:
            pass
        try:
            self._m_maximum_btn.move(
                self.width() - (self._m_close_btn.width() + 1) * 2 + 1,
                (self._m_title_height - self._m_close_btn.height()) / 2)
        except:
            pass
        # 重新调整边界范围以备实现鼠标拖放缩放窗口大小,采用三个列表生成式生成三个列表
        self._right_rect = [
            QPoint(x, y) for x in range(self.width() - self._m_padding,
                                        self.width() + 1)
            for y in range(1,
                           self.height() - self._m_padding)
        ]
        self._bottom_rect = [
            QPoint(x, y) for x in range(1,
                                        self.width() - self._m_padding)
            for y in range(self.height() - self._m_padding,
                           self.height() + 1)
        ]
        self._corner_rect = [
            QPoint(x, y) for x in range(self.width() - self._m_padding,
                                        self.width() + 1)
            for y in range(self.height() - self._m_padding,
                           self.height() + 1)
        ]

    def mouseDoubleClickEvent(self, event):
        if (event.button()
                == Qt.LeftButton) and (event.y() < self._m_title_height):
            # 鼠标左键双击标题栏区域,切换界面最大化和最小化
            windowstate = int(self.windowState())
            if windowstate == 0:
                self._on_set_window_maximum()
            elif windowstate == 2:
                self._on_set_window_normal()

            event.accept()

    def mousePressEvent(self, event):
        # 重写鼠标点击的事件
        if (event.button() == Qt.LeftButton) and (event.pos()
                                                  in self._corner_rect):
            # 鼠标左键点击右下角边界区域
            self._m_corner_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos()
                                                    in self._right_rect):
            # 鼠标左键点击右侧边界区域
            self._m_right_drag = True
            event.accept()
        elif (event.button() == Qt.LeftButton) and (event.pos()
                                                    in self._bottom_rect):
            # 鼠标左键点击下侧边界区域
            self._m_bottom_drag = True
            event.accept()
        elif (event.button()
              == Qt.LeftButton) and (event.y() < self._m_title_height):
            # 鼠标左键点击标题栏区域
            self._m_move_drag = True
            self.move_DragPosition = event.globalPos() - self.pos()
            event.accept()

    def mouseMoveEvent(self, QMouseEvent):
        # 判断鼠标位置切换鼠标手势
        if QMouseEvent.pos() in self._corner_rect:
            self.setCursor(Qt.SizeFDiagCursor)
        elif QMouseEvent.pos() in self._bottom_rect:
            self.setCursor(Qt.SizeVerCursor)
        elif QMouseEvent.pos() in self._right_rect:
            self.setCursor(Qt.SizeHorCursor)
        else:
            self.setCursor(Qt.ArrowCursor)
        # 当鼠标左键点击不放及满足点击区域的要求后,分别实现不同的窗口调整
        # 没有定义左方和上方相关的5个方向,主要是因为实现起来不难,但是效果很差,拖放的时候窗口闪烁,再研究研究是否有更好的实现
        if Qt.LeftButton and self._m_right_drag:
            # 右侧调整窗口宽度
            self.resize(QMouseEvent.pos().x(), self.height())
            QMouseEvent.accept()
        elif Qt.LeftButton and self._m_bottom_drag:
            # 下侧调整窗口高度
            self.resize(self.width(), QMouseEvent.pos().y())
            QMouseEvent.accept()
        elif Qt.LeftButton and self._m_corner_drag:
            # 右下角同时调整高度和宽度
            self.resize(QMouseEvent.pos().x(), QMouseEvent.pos().y())
            QMouseEvent.accept()
        elif Qt.LeftButton and self._m_move_drag:
            # 标题栏拖放窗口位置
            self.move(QMouseEvent.globalPos() - self.move_DragPosition)
            QMouseEvent.accept()

    def mouseReleaseEvent(self, a0: QtGui.QMouseEvent) -> None:
        """
        重载 mouseReleaseEvent 函数
        鼠标释放后,各扳机复位
        :param a0: 事件,没有用上
        :return: None
        """
        self._m_move_drag = False
        self._m_corner_drag = False
        self._m_bottom_drag = False
        self._m_right_drag = False
Ejemplo n.º 17
0
    def _add_process(self):
        process_groupbox = QGroupBox("Process")
        process_groupbox.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        process_layout = QVBoxLayout()
        process_layout.setSpacing(0)
        process_groupbox.setLayout(process_layout)

        pbar_frame = QFrame()
        pbar_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        pbar_hbox = QHBoxLayout()
        pbar_hbox.setContentsMargins(QtCore.QMargins(0, 0, 0, 16))
        pbar_hbox.setSpacing(16)

        # Run and stop buttons
        hbox = QHBoxLayout()
        hbox.setSpacing(8)
        self.run_button = QPushButton()
        # is only enabled when validation passes
        self.run_button.setEnabled(False)
        self.run_button.setText("Run")
        self.run_button.setFixedWidth(100)
        run_icon = qta.icon('fa.play', color='green')
        self.run_button.setIcon(run_icon)
        self.run_button.clicked.connect(self._click_run)
        hbox.addWidget(self.run_button)

        self.stop_button = QPushButton()
        self.stop_button.setEnabled(False)
        self.stop_button.setText("Stop")
        self.stop_button.setFixedWidth(100)
        stop_icon = qta.icon('fa.stop', color='red')
        self.stop_button.setIcon(stop_icon)
        self.stop_button.clicked.connect(self._click_stop)
        hbox.addWidget(self.stop_button)

        self.progress_bar = QProgressBar()
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setAlignment(QtCore.Qt.AlignCenter)
        self.progress_bar.setValue(0)
        self.progress_bar.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)

        pbar_hbox.addLayout(hbox)
        pbar_hbox.addWidget(self.progress_bar)
        pbar_frame.setLayout(pbar_hbox)
        process_layout.addWidget(pbar_frame)

        self.warning_frame = QFrame()
        self.warning_frame.setVisible(False)
        self.warning_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        warning_icon_widget = qta.IconWidget('fa.warning', color='red')
        warning_icon_widget.setIconSize(QtCore.QSize(48, 48))
        warning_icon_widget.update()
        hbox.addWidget(warning_icon_widget)
        warning_label = QLabel(
            "Grid Transformer did not complete successfully. Please refer to "
            "log output.")
        warning_label.setStyleSheet("QLabel { color: red; }")
        warning_label.setWordWrap(True)
        warning_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(warning_label)
        self.warning_frame.setLayout(hbox)
        process_layout.addWidget(self.warning_frame)

        self.success_frame = QFrame()
        self.success_frame.setVisible(False)
        self.success_frame.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        hbox = QHBoxLayout()

        success_icon_widget = qta.IconWidget('fa.check', color='green')
        success_icon_widget.setIconSize(QtCore.QSize(48, 48))
        success_icon_widget.update()
        hbox.addWidget(success_icon_widget)
        success_label = QLabel("Grid Transformer completed successfully.")
        success_label.setStyleSheet("QLabel { color: green; }")
        success_label.setWordWrap(True)
        success_label.setSizePolicy(QSizePolicy.Expanding,
                                    QSizePolicy.Preferred)
        hbox.addWidget(success_label)
        self.success_frame.setLayout(hbox)
        process_layout.addWidget(self.success_frame)

        log_layout = QVBoxLayout()
        log_layout.setSpacing(4)
        log_label = QLabel("Log messages")
        log_label.setStyleSheet("QLabel { color: grey; }")
        log_layout.addWidget(log_label)

        self.log_messages = QPlainTextEdit()
        log_font = QFont("monospace")
        log_font.setStyleHint(QFont.TypeWriter)
        self.log_messages.setFont(log_font)
        self.log_messages.setReadOnly(True)
        self.log_messages.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Expanding)
        # self.log_messages.sizePolicy.setVerticalStretch(1)
        log_layout.addWidget(self.log_messages)
        process_layout.addLayout(log_layout)

        self.layout.addWidget(process_groupbox)
Ejemplo n.º 18
0
class ManuelleEingabeRaum(QWidget):
    def __init__(self, parent, data_object: datatypes.Raum = None):
        super(ManuelleEingabeRaum, self).__init__(parent)

        self.data_object = data_object

        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum)

        parent.label_title.setText("Neuer Eintrag: Raum")

        self.layout = QVBoxLayout(self)
        self.layout.setSpacing(10)

        # create inputs
        self.input_raum_id = new_text_input(self, "Raum-ID", "Raum-ID")
        self.input_kapazitaet_id = new_text_input(self, "Kapazität",
                                                  "Maximale Prüfungsplätze",
                                                  True)
        self.input_verfuegbarkeit = new_text_input(self, "Verfügbarkeit",
                                                   "in Minuten", True)
        self.input_time = new_time_input(self, "Uhrzeit")
        self.input_date = new_date_input(self, "Datum")

        # add to layout
        self.layout.addWidget(self.input_raum_id)
        self.layout.addWidget(self.input_kapazitaet_id)
        self.layout.addWidget(self.input_verfuegbarkeit)
        self.layout.addWidget(self.input_time)
        self.layout.addWidget(self.input_date)

        self.setLayout(self.layout)

        # if edit add old data
        if not data_object is None:
            self.input_raum_id.text_edit.setText(str(data_object.id))
            self.input_kapazitaet_id.text_edit.setText(
                str(data_object.kapazitaet))
            self.input_verfuegbarkeit.text_edit.setText(
                str(data_object.verfuegbarkeit))

            datetime = datatypes.timestamp_to_datetime(data_object.timestamp)
            time = QTime(datetime.hour, datetime.minute)
            date = QDate(datetime.year, datetime.month, datetime.day)

            self.input_time.time_input.setTime(time)
            self.input_date.date_input.setDate(date)

    def clear_inputs(self):
        self.input_raum_id.text_edit.clear()
        self.input_kapazitaet_id.text_edit.clear()
        self.input_verfuegbarkeit.text_edit.clear()

    def create_object(self):
        """
        creates data_object
        :return:
        """
        if self.input_raum_id.text_edit.empty() \
                or self.input_kapazitaet_id.text_edit.empty() \
                or self.input_verfuegbarkeit.text_edit.empty():
            return False  # failed
        else:
            timestamp = self.input_date.date_input.dateTime(
            ).toMSecsSinceEpoch() + self.input_time.time_input.time(
            ).msecsSinceStartOfDay()

            return datatypes.Raum(
                self.input_raum_id.text_edit.text(),
                int(self.input_kapazitaet_id.text_edit.text()),
                int(self.input_verfuegbarkeit.text_edit.text()), timestamp)
Ejemplo n.º 19
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.setWindowFlags(Qt.FramelessWindowHint)

        QFontDatabase.addApplicationFont('Fonts/Roboto-Light.ttf')
        QFontDatabase.addApplicationFont('Fonts/Roboto-Regular.ttf')

        with open('QtInterface/style.qss') as stylefile:
            self.setStyleSheet(stylefile.read())

        self.controlmenu = ElchMenuPages()
        self.ribbon = ElchRibbon(menus=self.controlmenu.menus)
        self.matplotframe = ElchPlot()
        self.titlebar = ElchTitlebar()
        self.statusbar = ElchStatusBar()

        panel_spacing = 20

        hbox_inner = QHBoxLayout()
        hbox_inner.addWidget(self.matplotframe, stretch=1)
        hbox_inner.addWidget(self.controlmenu, stretch=0)
        hbox_inner.setSpacing(panel_spacing)
        hbox_inner.setContentsMargins(0, 0, 0, 0)

        vbox_inner = QVBoxLayout()
        vbox_inner.addWidget(self.statusbar, stretch=0)
        vbox_inner.addLayout(hbox_inner, stretch=1)
        vbox_inner.setSpacing(panel_spacing)
        vbox_inner.setContentsMargins(panel_spacing, panel_spacing,
                                      panel_spacing - 13, panel_spacing)

        sizegrip = QSizeGrip(self)
        hbox_mid = QHBoxLayout()
        hbox_mid.addLayout(vbox_inner, stretch=1)
        hbox_mid.addWidget(sizegrip, alignment=Qt.AlignBottom | Qt.AlignRight)
        hbox_mid.setContentsMargins(0, 0, 0, 0)
        hbox_mid.setSpacing(0)

        vbox_outer = QVBoxLayout()
        vbox_outer.addWidget(self.titlebar, stretch=0)
        vbox_outer.addLayout(hbox_mid, stretch=1)
        vbox_outer.setContentsMargins(0, 0, 0, 0)
        vbox_outer.setSpacing(0)

        hbox_outer = QHBoxLayout()
        hbox_outer.addWidget(self.ribbon, stretch=0)
        hbox_outer.addLayout(vbox_outer, stretch=1)
        hbox_outer.setContentsMargins(0, 0, 0, 0)
        hbox_outer.setSpacing(0)

        self.ribbon.buttongroup.buttonToggled.connect(
            self.controlmenu.adjust_visibility)
        self.ribbon.menu_buttons['Devices'].setChecked(True)

        self.controlmenu.menus['Plotting'].buttons['Start'].clicked.connect(
            self.matplotframe.start_plotting)
        self.controlmenu.menus['Plotting'].buttons['Clear'].clicked.connect(
            self.matplotframe.clear_plot)

        for key, button in self.controlmenu.menus['Devices'].unitbuttons.items(
        ):
            button.clicked.connect(
                functools.partial(self.statusbar.change_units, key))
            button.clicked.connect(
                functools.partial(self.matplotframe.set_units, key))

        self.controlmenu.menus['Plotting'].check_group.buttonToggled.connect(
            self.matplotframe.set_plot_visibility)

        self.controlmenu.menus['Devices'].unitbuttons['Temperature'].click()

        self.setLayout(hbox_outer)
        self.show()
Ejemplo n.º 20
0
class ManuelleEingabePruefung(QWidget):
    def __init__(self, parent, data_object: datatypes.Pruefung = None):
        super(ManuelleEingabePruefung, self).__init__(parent)

        self.data_object = data_object

        parent.label_title.setText("Neuer Eintrag: Prüfung")

        self.layout = QVBoxLayout(self)
        self.layout_id = QHBoxLayout(self)

        self.layout.setSpacing(10)
        self.layout_id.setMargin(0)

        # create inputs
        self.art_input = new_combobox_input(self, "Prüfungsart",
                                            ["schriftlich", "mündlich"])
        self.input_id = new_text_input(self, "Prüfungs-ID", "Prüfungs-ID")
        self.input_kuerzel = new_text_input(self, "",
                                            "Prüfungs-Kürzel (optional)")
        self.input_verfuegbarkeit = new_text_input(self, "Dauer", "in Minuten",
                                                   True)
        self.input_teilnehmer = new_text_input(self, "Anzahl der zu Prüfenden",
                                               "Anzahl der zu Prüfenden", True)
        self.input_time = new_time_input(self, "Uhrzeit")
        self.input_date = new_date_input(self, "Datum")

        # connect art
        self.art_input.combobox_widget.currentIndexChanged.connect(
            self.art_changed)

        # add to layout
        self.layout_id.addWidget(self.input_id)
        self.layout_id.addWidget(self.input_kuerzel)

        self.layout.addWidget(self.art_input)
        self.layout.addLayout(self.layout_id)
        self.layout.addWidget(self.input_verfuegbarkeit)
        self.layout.addWidget(self.input_teilnehmer)
        self.layout.addWidget(self.input_time)
        self.layout.addWidget(self.input_date)

        self.setLayout(self.layout)

        # if edit add old data
        if not data_object is None:
            # art
            art_index = 0 if data_object.art == 's' else 1
            self.art_input.combobox_widget.setCurrentIndex(art_index)

            self.input_id.text_edit.setText(str(data_object.id))
            self.input_kuerzel.text_edit.setText(str(data_object.kuerzel))
            if data_object.art == 'm':
                self.input_verfuegbarkeit.text_edit.setText(
                    str(data_object.verfuegbarkeit // data_object.teilnehmer))
            else:
                self.input_verfuegbarkeit.text_edit.setText(
                    str(data_object.verfuegbarkeit))

            self.input_teilnehmer.text_edit.setText(str(
                data_object.teilnehmer))

            datetime = datatypes.timestamp_to_datetime(data_object.timestamp)
            time = QTime(datetime.hour, datetime.minute)
            date = QDate(datetime.year, datetime.month, datetime.day)

            self.input_time.time_input.setTime(time)
            self.input_date.date_input.setDate(date)

    def art_changed(self, index):
        if self.art_input.combobox_widget.currentIndex() == 0:
            self.__set_text_schriftlich()
        else:
            self.__set_text_mündlich()

    def clear_inputs(self):
        self.input_id.text_edit.clear()
        self.input_kuerzel.text_edit.clear()
        self.input_verfuegbarkeit.text_edit.clear()
        self.input_teilnehmer.text_edit.clear()

    def create_object(self):
        """
        creates data_object
        :return:
        """
        if self.input_id.text_edit.empty() \
                or self.input_verfuegbarkeit.text_edit.empty() \
                or self.input_teilnehmer.text_edit.empty():
            return False  # failed
        else:
            timestamp = self.input_date.date_input.dateTime(
            ).toMSecsSinceEpoch() + self.input_time.time_input.time(
            ).msecsSinceStartOfDay()
            art = 's' if self.art_input.combobox_widget.currentIndex(
            ) == 0 else 'm'

            teilnehmer = int(self.input_teilnehmer.text_edit.text())
            dauer = int(self.input_verfuegbarkeit.text_edit.text())
            if art == 'm':
                dauer *= teilnehmer

            return datatypes.Pruefung(art, self.input_id.text_edit.text(),
                                      self.input_kuerzel.text_edit.text(),
                                      teilnehmer, dauer, timestamp)

    def __set_text_schriftlich(self):
        self.input_teilnehmer.label_title.setText("Anzahl der zu Prüfenden")

    def __set_text_mündlich(self):
        self.input_teilnehmer.label_title.setText("Prüfungsteilnehmer")
Ejemplo n.º 21
0
class UiMainWindow(object):
    '''Интерфейс основного окна программы.
    Created by: Qt User Interface Compiler.
    Задано:
        панель инструментов с кнопками "Новый расчёт" (очистка всех полей),
        выбор режима расчёта, запуск расчёта;

        четыре поля ввода (длина заготовки, длина безусловного отхода,
        ширина реза, длина первичной обрезки торца заготовки)

        таблица ввода длин элементов и их количеств;

        кнопки "добавить строку в конец таблицы" и "удалить последнюю строку
        в таблице";

        поле вывода результата расчёта.
    '''
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(700, 495)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.main_frame = QFrame(self.centralwidget)
        self.main_frame.setObjectName(u"main_frame")
        self.main_frame.setFrameShape(QFrame.StyledPanel)
        self.main_frame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_2 = QVBoxLayout(self.main_frame)
        self.verticalLayout_2.setSpacing(0)
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)

        # "панель инструментов"
        self.top_frame = QFrame(self.main_frame)
        self.top_frame.setObjectName(u"top_frame")
        self.top_frame.setMinimumSize(QSize(0, 60))
        self.top_frame.setMaximumSize(QSize(16777215, 60))
        self.top_frame.setFrameShape(QFrame.StyledPanel)
        self.top_frame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout = QHBoxLayout(self.top_frame)
        self.horizontalLayout.setSpacing(5)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(5, 5, 5, 5)

        # кнопка "новый расчёт"
        self.new_calc_btn = QPushButton(self.top_frame)
        self.new_calc_btn.setObjectName(u"new_calc_btn")
        self.new_calc_btn.setMinimumSize(QSize(110, 50))
        self.new_calc_btn.setMaximumSize(QSize(110, 50))
        icon = QIcon()
        icon.addFile(NEW_CALC_ICON, QSize(), QIcon.Normal, QIcon.Off)
        self.new_calc_btn.setIcon(icon)
        self.new_calc_btn.setIconSize(QSize(45, 45))

        self.horizontalLayout.addWidget(self.new_calc_btn)

        # кнопка "выбор режима расчёта"
        self.select_mode_btn = QPushButton(self.top_frame)
        self.select_mode_btn.setObjectName(u"select_mode_btn")
        self.select_mode_btn.setMinimumSize(QSize(110, 50))
        self.select_mode_btn.setMaximumSize(QSize(110, 50))
        icon1 = QIcon()
        icon1.addFile(SET_MODE_ICON, QSize(), QIcon.Normal, QIcon.Off)
        self.select_mode_btn.setIcon(icon1)
        self.select_mode_btn.setIconSize(QSize(45, 45))

        self.horizontalLayout.addWidget(self.select_mode_btn)

        # кнопка "запуск расчёта"
        self.start_calc_btn = QPushButton(self.top_frame)
        self.start_calc_btn.setObjectName(u"start_calc_btn")
        self.start_calc_btn.setMinimumSize(QSize(110, 50))
        self.start_calc_btn.setMaximumSize(QSize(110, 50))
        icon2 = QIcon()
        icon2.addFile(START_CALC_ICON, QSize(), QIcon.Normal, QIcon.Off)
        self.start_calc_btn.setIcon(icon2)
        self.start_calc_btn.setIconSize(QSize(45, 45))

        self.horizontalLayout.addWidget(self.start_calc_btn)

        self.horizontalSpacer = QSpacerItem(338, 20, QSizePolicy.Expanding,
                                            QSizePolicy.Minimum)

        self.horizontalLayout.addItem(self.horizontalSpacer)

        self.verticalLayout_2.addWidget(self.top_frame)

        self.bottom_frame = QFrame(self.main_frame)
        self.bottom_frame.setObjectName(u"bottom_frame")
        self.bottom_frame.setFrameShape(QFrame.StyledPanel)
        self.bottom_frame.setFrameShadow(QFrame.Raised)
        self.horizontalLayout_2 = QHBoxLayout(self.bottom_frame)
        self.horizontalLayout_2.setSpacing(5)
        self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
        self.horizontalLayout_2.setContentsMargins(5, 5, 5, 5)
        self.input_frame = QFrame(self.bottom_frame)
        self.input_frame.setObjectName(u"input_frame")
        self.input_frame.setMinimumSize(QSize(340, 0))
        self.input_frame.setMaximumSize(QSize(340, 16777215))
        self.input_frame.setFrameShape(QFrame.StyledPanel)
        self.input_frame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_3 = QVBoxLayout(self.input_frame)
        self.verticalLayout_3.setSpacing(5)
        self.verticalLayout_3.setObjectName(u"verticalLayout_3")
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)

        # поле ввода длины заготовки
        self.length_layout = QHBoxLayout()
        self.length_layout.setSpacing(5)
        self.length_layout.setObjectName(u"length_layout")
        self.length_label = QLabel(self.input_frame)
        self.length_label.setObjectName(u"length_label")
        self.length_label.setMinimumSize(QSize(165, 25))
        self.length_label.setMaximumSize(QSize(165, 25))
        self.length_layout.addWidget(self.length_label)
        self.length_entry = QLineEdit(self.input_frame)
        self.length_entry.setObjectName(u"length_entry")
        self.length_entry.setMinimumSize(QSize(165, 25))
        self.length_entry.setMaximumSize(QSize(165, 25))
        self.length_layout.addWidget(self.length_entry)
        self.verticalLayout_3.addLayout(self.length_layout)

        # поле ввода длины безусловного отхода
        self.waste_layout = QHBoxLayout()
        self.waste_layout.setSpacing(5)
        self.waste_layout.setObjectName(u"waste_layout")
        self.waste_label = QLabel(self.input_frame)
        self.waste_label.setObjectName(u"waste_label")
        self.waste_label.setMinimumSize(QSize(165, 25))
        self.waste_label.setMaximumSize(QSize(165, 25))
        self.waste_layout.addWidget(self.waste_label)
        self.waste_entry = QLineEdit(self.input_frame)
        self.waste_entry.setObjectName(u"waste_entry")
        self.waste_entry.setMinimumSize(QSize(165, 25))
        self.waste_entry.setMaximumSize(QSize(165, 25))
        self.waste_layout.addWidget(self.waste_entry)
        self.verticalLayout_3.addLayout(self.waste_layout)

        # поле ввода ширины реза
        self.cut_layout = QHBoxLayout()
        self.cut_layout.setSpacing(5)
        self.cut_layout.setObjectName(u"cut_layout")
        self.cut_label = QLabel(self.input_frame)
        self.cut_label.setObjectName(u"cut_label")
        self.cut_label.setMinimumSize(QSize(165, 25))
        self.cut_label.setMaximumSize(QSize(165, 25))
        self.cut_layout.addWidget(self.cut_label)
        self.cut_entry = QLineEdit(self.input_frame)
        self.cut_entry.setObjectName(u"cut_entry")
        self.cut_entry.setMinimumSize(QSize(165, 25))
        self.cut_entry.setMaximumSize(QSize(165, 25))
        self.cut_layout.addWidget(self.cut_entry)
        self.verticalLayout_3.addLayout(self.cut_layout)

        # поле ввода длины подрезки торца заготовки
        self.trim_layout = QHBoxLayout()
        self.trim_layout.setSpacing(5)
        self.trim_layout.setObjectName(u"trim_layout")
        self.trim_label = QLabel(self.input_frame)
        self.trim_label.setObjectName(u"trim_label")
        self.trim_label.setMinimumSize(QSize(165, 25))
        self.trim_label.setMaximumSize(QSize(165, 25))
        self.trim_layout.addWidget(self.trim_label)
        self.trim_entry = QLineEdit(self.input_frame)
        self.trim_entry.setObjectName(u"trim_entry")
        self.trim_entry.setMinimumSize(QSize(165, 25))
        self.trim_entry.setMaximumSize(QSize(165, 25))
        self.trim_layout.addWidget(self.trim_entry)
        self.verticalLayout_3.addLayout(self.trim_layout)

        # таблица ввода длин и количеств элементов
        self.input_table = QTableWidget(self.input_frame)
        if (self.input_table.columnCount() < 2):
            self.input_table.setColumnCount(2)
        if (self.input_table.rowCount() < 7):
            self.input_table.setRowCount(7)
        self.input_table.setObjectName(u"input_table")
        self.input_table.setRowCount(7)
        self.input_table.setColumnCount(2)
        self.input_table.horizontalHeader().setMinimumSectionSize(33)
        self.input_table.horizontalHeader().setDefaultSectionSize(130)
        self.input_table.horizontalHeader().setProperty(
            "showSortIndicator",
            True,
        )
        self.input_table.horizontalHeader().setStretchLastSection(True)
        self.input_table.verticalHeader().setMinimumSectionSize(30)
        self.input_table.verticalHeader().setDefaultSectionSize(30)
        self.verticalLayout_3.addWidget(self.input_table)

        self.horizontalLayout_3 = QHBoxLayout()
        self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")

        # кнопка "добавить строку в конец таблицы"
        self.add_str_button = QPushButton(self.input_frame)
        self.add_str_button.setObjectName(u"add_str_button")
        self.add_str_button.setMinimumSize(QSize(150, 35))
        self.add_str_button.setMaximumSize(QSize(150, 35))
        icon3 = QIcon()
        icon3.addFile(
            ADD_STR_ICON,
            QSize(),
            QIcon.Normal,
            QIcon.Off,
        )
        self.add_str_button.setIcon(icon3)
        self.add_str_button.setIconSize(QSize(25, 25))
        self.horizontalLayout_3.addWidget(self.add_str_button)

        # кнопка "удалить последнюю строку в таблице"
        self.remove_str_button = QPushButton(self.input_frame)
        self.remove_str_button.setObjectName(u"remove_str_button")
        self.remove_str_button.setMinimumSize(QSize(150, 35))
        self.remove_str_button.setMaximumSize(QSize(150, 35))
        icon4 = QIcon()
        icon4.addFile(
            DESTR_STR_ICON,
            QSize(),
            QIcon.Normal,
            QIcon.Off,
        )
        self.remove_str_button.setIcon(icon4)
        self.remove_str_button.setIconSize(QSize(25, 25))
        self.horizontalLayout_3.addWidget(self.remove_str_button)

        self.verticalLayout_3.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_2.addWidget(self.input_frame)

        self.output_frame = QFrame(self.bottom_frame)
        self.output_frame.setObjectName(u"output_frame")
        self.output_frame.setFrameShape(QFrame.StyledPanel)
        self.output_frame.setFrameShadow(QFrame.Raised)
        self.verticalLayout_4 = QVBoxLayout(self.output_frame)
        self.verticalLayout_4.setObjectName(u"verticalLayout_4")

        # поле вывода результатов расчёта
        self.textBrowser = QTextBrowser(self.output_frame)
        self.textBrowser.setObjectName(u"textBrowser")
        self.verticalLayout_4.addWidget(self.textBrowser)

        self.horizontalLayout_4 = QHBoxLayout()
        self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")

        # строка состояния
        self.label_2 = QLabel(self.output_frame)
        self.label_2.setObjectName(u"label_2")
        self.label_2.setMinimumSize(QSize(25, 25))
        self.label_2.setMaximumSize(QSize(16777215, 25))
        self.horizontalLayout_4.addWidget(self.label_2)
        self.horizontalSpacer_2 = QSpacerItem(
            40,
            20,
            QSizePolicy.Expanding,
            QSizePolicy.Minimum,
        )

        self.horizontalLayout_4.addItem(self.horizontalSpacer_2)

        # поле вывода версии программы
        self.label = QLabel(self.output_frame)
        self.label.setObjectName(u"label")
        self.label.setMinimumSize(QSize(0, 25))
        self.label.setMaximumSize(QSize(16777215, 25))

        self.horizontalLayout_4.addWidget(self.label)
        self.verticalLayout_4.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_2.addWidget(self.output_frame)
        self.verticalLayout_2.addWidget(self.bottom_frame)
        self.verticalLayout.addWidget(self.main_frame)

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
# setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(
            QCoreApplication.translate("MainWindow", u"simple linear nesting",
                                       None))
        # if QT_CONFIG(tooltip)
        self.new_calc_btn.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Clear all fields, Ctrl+N", None))
        # endif // QT_CONFIG(tooltip)
        self.new_calc_btn.setText(
            QCoreApplication.translate("MainWindow", u"new", None))
        # if QT_CONFIG(shortcut)
        self.new_calc_btn.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl+N", None))
        # endif // QT_CONFIG(shortcut)
        # if QT_CONFIG(tooltip)
        self.select_mode_btn.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Select calculation mode, Ctrl+M",
                                       None))
        # endif // QT_CONFIG(tooltip)
        self.select_mode_btn.setText(
            QCoreApplication.translate("MainWindow", u"mode", None))
        # if QT_CONFIG(shortcut)
        self.select_mode_btn.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl+M", None))
        # endif // QT_CONFIG(shortcut)
        # if QT_CONFIG(tooltip)
        self.start_calc_btn.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Start calculation, Ctrl+R", None))
        # endif // QT_CONFIG(tooltip)
        self.start_calc_btn.setText(
            QCoreApplication.translate("MainWindow", u"start", None))
        # if QT_CONFIG(shortcut)
        self.start_calc_btn.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl+R", None))
        # endif // QT_CONFIG(shortcut)
        self.length_label.setText(
            QCoreApplication.translate("MainWindow", u"workpiece length",
                                       None))
        # if QT_CONFIG(tooltip)
        self.length_entry.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Enter the length of the workpiece",
                                       None))
        # endif // QT_CONFIG(tooltip)
        self.waste_label.setText(
            QCoreApplication.translate("MainWindow", u"irreducible waste",
                                       None))
        # if QT_CONFIG(tooltip)
        self.waste_entry.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Enter the length of the waste", None))
        # endif // QT_CONFIG(tooltip)
        self.cut_label.setText(
            QCoreApplication.translate("MainWindow", u"cutting width", None))
        # if QT_CONFIG(tooltip)
        self.cut_entry.setToolTip(
            QCoreApplication.translate("MainWindow",
                                       u"Enter the width of the cutting",
                                       None))
        # endif // QT_CONFIG(tooltip)
        self.trim_label.setText(
            QCoreApplication.translate("MainWindow", u"trim the end", None))
        # if QT_CONFIG(tooltip)
        self.trim_entry.setToolTip(
            QCoreApplication.translate(
                "MainWindow", u"Enter the length of the trimming end", None))
        # endif // QT_CONFIG(tooltip)
        # if QT_CONFIG(tooltip)
        self.add_str_button.setToolTip(
            QCoreApplication.translate(
                "MainWindow", u"Add another row to the table, Ctrl++", None))
        # endif // QT_CONFIG(tooltip)
        self.add_str_button.setText("")
        # if QT_CONFIG(shortcut)
        self.add_str_button.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl++", None))
        # endif // QT_CONFIG(shortcut)
        # if QT_CONFIG(tooltip)
        self.remove_str_button.setToolTip(
            QCoreApplication.translate(
                "MainWindow", u"Delete the last row in the table, Ctrl+-",
                None))
        # endif // QT_CONFIG(tooltip)
        self.remove_str_button.setText("")
        # if QT_CONFIG(shortcut)
        self.remove_str_button.setShortcut(
            QCoreApplication.translate("MainWindow", u"Ctrl+-", None))
        # endif // QT_CONFIG(shortcut)
        self.label_2.setText("")
        self.label.setText(
            QCoreApplication.translate("MainWindow", u"v.0.0.0", None))
Ejemplo n.º 22
0
    def _create_reg(self, ind_list, name, width, color):
        # Create a widget to hold the register's bits
        reg_widget = QWidget(self)
        reg_layout = QVBoxLayout(reg_widget)
        reg_widget.setLayout(reg_layout)
        reg_layout.setSpacing(0)
        reg_layout.setMargin(0)

        # Create a widget to hold the register's label and value textbox
        label_value = QWidget(reg_widget)
        lv_layout = QHBoxLayout(label_value)
        label_value.setLayout(lv_layout)
        lv_layout.setSpacing(1)
        lv_layout.setMargin(0)
        reg_layout.addWidget(label_value)

        # Create a label to show the register's name
        reg_label = QLabel(name, label_value)
        reg_label.setAlignment(Qt.AlignCenter)
        font = reg_label.font()
        font.setPointSize(8)
        reg_label.setFont(font)
        lv_layout.addWidget(reg_label)

        # Create a textbox to show the register's value in octal
        n_digits = int((width + 2) / 3)
        if n_digits == 1:
            value_width = 25
        elif n_digits == 2:
            value_width = 30
        else:
            value_width = 45

        reg_value = QLineEdit(label_value)
        reg_value.setReadOnly(True)
        reg_value.setMaximumSize(value_width, 32)
        reg_value.setText(n_digits * '0')
        font = QFont('Monospace')
        font.setStyleHint(QFont.TypeWriter)
        font.setPointSize(10)
        reg_value.setFont(font)
        reg_value.setAlignment(Qt.AlignCenter)
        lv_layout.addWidget(reg_value)

        # Create a frame to hold the register's bits
        bit_frame = QFrame(reg_widget)
        bit_layout = QHBoxLayout(bit_frame)
        bit_layout.setSpacing(1)
        bit_layout.setMargin(0)
        bit_frame.setLayout(bit_layout)
        bit_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Raised)

        # Add indicators for each bit in the register, from MSB to LSB
        for i in range(width, 0, -1):
            ind = Indicator(bit_frame, color)
            ind.setFixedSize(20, 32)
            bit_layout.addWidget(ind)
            ind_list.insert(0, ind)

            # Add separators between each group of 3 bits
            if (i > 1) and ((i % 3) == 1):
                sep = QFrame(bit_frame)
                sep.setFrameStyle(QFrame.VLine | QFrame.Raised)
                bit_layout.addWidget(sep)

        reg_layout.addWidget(bit_frame)

        return reg_widget, reg_value
Ejemplo n.º 23
0
    def grid_layout(self):

        grid = QVBoxLayout()
        grid.setSpacing(15)

        self.pause_button = QPushButton('■')
        self.running_state = QLabel('Current State: <font color="grey">Inactive</font>')

        def cont_sim():
            self.pause_button.setText('■')
            self.running_state.setText('Current State: <font color="green">Running</font>')
            self.qmp.command('cont')

        def stop_sim():
            self.pause_button.setText('▶')
            self.running_state.setText('Current State: <font color="red">Paused</font>')
            self.qmp.command('stop')

        subgrid = QHBoxLayout()

        self.pause_button.clicked.connect(lambda: stop_sim() if not self.paused else cont_sim())
        self.pause_button.setFixedSize(QSize(50, 50))
        subgrid.addWidget(self.pause_button, 0)
        # self.pause_button.setCheckable(True)

        # self.handle_pause_button(False)
        self.pause_button.setEnabled(False)

        meatball = QLabel(self)
        logo = QPixmap('package/icons/nasa.png')
        logo = logo.scaled(75, 75, Qt.KeepAspectRatio)
        meatball.setPixmap(logo)
        subgrid.addWidget(meatball, 1)

        grid.addLayout(subgrid, 0)

        self.time = QLabel('Time: 00:00:00')
        self.time.setFont(QFont('Courier New'))
        grid.addWidget(self.time, 1)

        grid.addWidget(self.running_state, 2)

        self.banner = QLabel('<font color="grey">Connect to QMP to get started!</font>')
        grid.addWidget(self.banner, 3)

        conn_grid = QHBoxLayout()

        self.connect_button = QPushButton("Connect")
        self.connect_button.setCheckable(True)
        self.connect_button.clicked.connect(self.qmp_start)

        self.host = QLineEdit()
        self.host.returnPressed.connect(lambda: self.connect_button.click() if not self.connect_button.isChecked() else None)

        self.port = QLineEdit()
        self.port.returnPressed.connect(lambda: self.connect_button.click() if not self.connect_button.isChecked() else None)


        conn_grid.addWidget(self.host)
        conn_grid.addWidget(self.port)
        conn_grid.addWidget(self.connect_button)

        grid.addLayout(conn_grid)

        center = QWidget()
        center.setLayout(grid)
        self.setCentralWidget(center)
Ejemplo n.º 24
0
 def initUI(self):
     # Master Layout
     mainlayout = QVBoxLayout()
     mainlayout.setContentsMargins(0, 0, 0, 0)
     mainlayout.setMargin(3)
     mainlayout.setSpacing(0)
     mainlayout.setStretch(0, 0)
     # Top Layout (In Out Duration)
     subLayout = QHBoxLayout()
     subLayout.setContentsMargins(0, 0, 0, 0)
     subLayout.setMargin(2)
     subLayout.setSpacing(5)
     # Top Layout Controls
     self.no = QSpinBox()
     self.no.setMinimum(1)
     self.no.setMaximum(9999)  # < Memory Concerns Lower
     self.tcIn = QLineEdit()
     self.tcOut = QLineEdit()
     self.tcDur = QLineEdit()
     index_lbl = QLabel("No:")
     intc_lbl = QLabel("In:")
     outtc_lbl = QLabel("Out:")
     durtc_lbl = QLabel("Duration:")
     # Add to Layout
     subLayout.addWidget(index_lbl)
     subLayout.addWidget(self.no)
     subLayout.addWidget(intc_lbl)
     subLayout.addWidget(self.tcIn)
     subLayout.addWidget(outtc_lbl)
     subLayout.addWidget(self.tcOut)
     subLayout.addWidget(durtc_lbl)
     subLayout.addWidget(self.tcDur)
     # Add to Main
     mainlayout.addLayout(subLayout)
     # Add Next Line Controls
     second_line_layout = QHBoxLayout()
     font = QFont("Helvetica", 13)
     self.font_family = QFontComboBox()
     self.font_family.setMaximumWidth(180)
     self.font_family.setCurrentFont(font)
     second_line_layout.addWidget(self.font_family)
     self.font_family.currentTextChanged.connect(self.set_font)
     self.font_size = QComboBox()
     self.font_size.addItems(["9", "10", "11", "12", "13", "14", "18", "24", "36", "48", "64"])
     self.font_size.setCurrentText("13")
     self.font_size.setMaximumWidth(80)
     self.font_size.currentIndexChanged.connect(self.set_font)
     second_line_layout.addWidget(self.font_size)
     bold = QPushButton("B")
     bold.clicked.connect(self.bold)
     italic = QPushButton("I")
     italic.clicked.connect(self.italic)
     underline = QPushButton("U")
     underline.clicked.connect(self.underline)
     second_line_layout.addWidget(bold)
     second_line_layout.addWidget(italic)
     second_line_layout.addWidget(underline)
     # ------------------------------------------
     language = QComboBox()
     language.addItems(["English", "Tamil", "Hindi"])
     language.currentIndexChanged.connect(self.setup_language)
     language.setDisabled(True)  # Disabled
     spellCheck = QPushButton("Spell Check")
     spellCheck.setDisabled(True)  # Disabled
     autocomplete = QCheckBox("AutoCmp")
     autocomplete.toggled.connect(self.setup_autocomplete)
     second_line_layout.addWidget(language)
     second_line_layout.addWidget(spellCheck)
     second_line_layout.addWidget(autocomplete)
     second_line_layout.addStretch(1)
     mainlayout.addLayout(second_line_layout)
     # txtSubTitle = QTextEdit()
     self.subtitle = CompletionTextEdit()
     # print(self.subtitle.font())
     # completer = DictionaryCompleter()
     # self.subtitle.setCompleter(completer)
     # self.subtitle.setMaximumHeight(100)
     mainlayout.addWidget(self.subtitle)
     # Setup TimeCode LineEdit Controls
     self.setup_linedt_tc(self.tcIn)
     self.setup_linedt_tc(self.tcOut)
     self.setup_linedt_tc(self.tcDur)
     self.tcOut.editingFinished.connect(self.calculate_duration)
     # Layout Operations
     self.setLayout(mainlayout)
     self.setTabOrder(self.tcDur, self.subtitle)
     self.show()
 def init_ui(self):
     layout = QVBoxLayout(self)
     layout.setSpacing(0)
     layout.addWidget(self.listView)
     self.setLayout(layout)
class LayersSelectorWidget(QWidget):
    '''
    LayerChoiceWidget class provide widget plugin for picking layers.
    '''
    def __init__(self):
        super().__init__()
        filter = QLineEdit()
        filter.setPlaceholderText("filter")
        names = [
            'Core Layers', 'Convolution Layers', 'Pooling Layers',
            'Recurrent Layers', 'Preprocessing Layers', 'Attention Layers',
            'Reshaping Layers', 'Locally-Connected Layers'
        ]
        layers = [['Dense', 'Activation', 'Embedding', 'Masking', 'Lambda'],
                  [
                      'Conv1D', 'Conv2D', 'Conv3D', 'SeparableConv1D',
                      'SeparableConv2D', 'DepthwiseConv2D', 'Conv2DTranspose',
                      'Conv3Dtranspose'
                  ],
                  [
                      'MaxPooling1D', 'MaxPooling2D', 'MaxPooling3D',
                      'AveragePooling1D', 'AveragePooling2D',
                      'AveragePooling3D', 'GlobalMaxPooling1D',
                      'GlobalMaxPooling2D', 'GlobalMaxPooling3D',
                      'GlobalAveragePooling1D', 'GlobalAveragePooling2D',
                      'GlobalAveragePooling3D'
                  ],
                  [
                      'LSTM', 'GRU', 'SimpleRNN', 'TimeDistributed',
                      'BiDirectional', 'ConvLSTM2D'
                  ], ['TextToVector', 'Normalization'],
                  ['Attention', 'AdditiveAttention'],
                  [
                      'Reshape', 'Flatten', 'Cropping1D', 'Cropping2D',
                      'Cropping3D', 'UpSampling1D', 'UpSampling2D',
                      'UpSampling3D', 'ZeroPadding1D', 'ZeroPadding2D',
                      'ZeroPadding3D'
                  ], ['LocallyConnected1D', 'LocallyConnected2D']]
        self.main_layout = QVBoxLayout()
        self.main_layout.addWidget(filter)
        for i in range(len(names)):
            if i > 1:
                self.main_layout.addWidget(
                    LayersList(names[i], layers[i], filter, False))
            else:
                self.main_layout.addWidget(
                    LayersList(names[i], layers[i], filter))
        self.main_layout.setSpacing(0)
        self.main_layout.setAlignment(Qt.AlignTop)
        self.main_layout.setMargin(0)
        self.main_layout.setSpacing(0)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.scroll_area = QScrollArea()
        names = QWidget()
        names.setLayout(self.main_layout)
        self.scroll_area.setWidget(names)
        self.main_layout = QVBoxLayout()
        self.main_layout.setAlignment(Qt.AlignTop)
        self.main_layout.setMargin(0)
        self.main_layout.setSpacing(0)
        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.scroll_area.setAlignment(Qt.AlignTop)
        self.scroll_area.setWidgetResizable(True)
        self.main_layout.addWidget(self.scroll_area)
        self.setLayout(self.main_layout)
        del (names)
        del (layers)

        self.set_styling()

    def set_styling(self):
        self.setStyleSheet('''
                           background-color:aliceblue;
                           ''')
Ejemplo n.º 27
0
class DebugModulesWidget(QWidget, DockContextHandler):
    def __init__(self, parent, name, data):
        if not type(data) == binaryninja.binaryview.BinaryView:
            raise Exception('expected widget data to be a BinaryView')

        self.bv = data

        QWidget.__init__(self, parent)
        DockContextHandler.__init__(self, self, name)
        self.actionHandler = UIActionHandler()
        self.actionHandler.setupActionHandler(self)

        self.table = QTableView(self)
        self.model = DebugModulesListModel(self.table, data)
        self.table.setModel(self.model)

        self.item_delegate = DebugModulesItemDelegate(self)
        self.table.setItemDelegate(self.item_delegate)

        # self.table.setSortingEnabled(True)
        self.table.setSelectionBehavior(
            QAbstractItemView.SelectionBehavior.SelectRows)
        self.table.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.table.verticalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.table.verticalHeader().setVisible(False)

        self.table.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        self.table.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)

        self.table.resizeColumnsToContents()
        self.table.resizeRowsToContents()

        for i in range(len(self.model.columns)):
            self.table.setColumnWidth(
                i,
                self.item_delegate.sizeHint(
                    self.table.viewOptions(),
                    self.model.index(-1, i, QModelIndex())).width())

        update_layout = QHBoxLayout()
        update_layout.setContentsMargins(0, 0, 0, 0)

        update_label = QLabel("Data is Stale")
        update_button = QPushButton("Refresh")
        update_button.clicked.connect(lambda: self.refresh())

        update_layout.addWidget(update_label)
        update_layout.addStretch(1)
        update_layout.addWidget(update_button)

        self.update_box = QWidget()
        self.update_box.setLayout(update_layout)

        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)
        self.layout.addWidget(self.table)
        self.setLayout(self.layout)

    def notifyOffsetChanged(self, offset):
        pass

    def refresh(self):
        debug_state = binjaplug.get_state(self.bv)
        debug_state.ui.update_modules()

    def notifyModulesChanged(self, new_modules):
        self.model.update_rows(new_modules)
        self.table.resizeColumnsToContents()
        self.layout.removeWidget(self.update_box)
        self.update_box.setVisible(False)

    def mark_dirty(self):
        self.layout.addWidget(self.update_box)
        self.update_box.setVisible(True)

    def contextMenuEvent(self, event):
        self.m_contextMenuManager.show(self.m_menu, self.actionHandler)

    def shouldBeVisible(self, view_frame):
        if view_frame is None:
            return False
        else:
            return True
Ejemplo n.º 28
0
    def __init__(self, parent, data):
        assert type(data) == BinaryView
        self.bv = data
        QDialog.__init__(self, parent)

        debug_state = binjaplug.get_state(self.bv)

        self.setWindowTitle("Debug Adapter Settings")
        self.setMinimumSize(UIContext.getScaledWindowSize(400, 130))
        self.setAttribute(Qt.WA_DeleteOnClose)

        layout = QVBoxLayout()
        layout.setSpacing(0)

        titleLabel = QLabel("Adapter Settings")
        titleLayout = QHBoxLayout()
        titleLayout.setContentsMargins(0, 0, 0, 0)
        titleLayout.addWidget(titleLabel)

        self.adapterEntry = QPushButton(self)
        self.adapterMenu = QMenu(self)
        for adapter in DebugAdapter.ADAPTER_TYPE:
            if not DebugAdapter.ADAPTER_TYPE.can_use(adapter):
                continue

            def select_adapter(adapter):
                return lambda: self.selectAdapter(adapter)

            self.adapterMenu.addAction(adapter.name, select_adapter(adapter))
            if adapter == debug_state.adapter_type:
                self.adapterEntry.setText(adapter.name)

        self.adapterEntry.setMenu(self.adapterMenu)

        self.argumentsEntry = QLineEdit(self)
        self.addressEntry = QLineEdit(self)
        self.portEntry = QLineEdit(self)

        self.formLayout = QFormLayout()
        self.formLayout.addRow("Adapter Type", self.adapterEntry)
        self.formLayout.addRow("Command Line Arguments", self.argumentsEntry)
        self.formLayout.addRow("Address", self.addressEntry)
        self.formLayout.addRow("Port", self.portEntry)

        buttonLayout = QHBoxLayout()
        buttonLayout.setContentsMargins(0, 0, 0, 0)

        self.cancelButton = QPushButton("Cancel")
        self.cancelButton.clicked.connect(lambda: self.reject())
        self.acceptButton = QPushButton("Accept")
        self.acceptButton.clicked.connect(lambda: self.accept())
        self.acceptButton.setDefault(True)
        buttonLayout.addStretch(1)
        buttonLayout.addWidget(self.cancelButton)
        buttonLayout.addWidget(self.acceptButton)

        layout.addLayout(titleLayout)
        layout.addSpacing(10)
        layout.addLayout(self.formLayout)
        layout.addStretch(1)
        layout.addSpacing(10)
        layout.addLayout(buttonLayout)

        self.setLayout(layout)

        self.addressEntry.setText(debug_state.remote_host)
        self.portEntry.setText(str(debug_state.remote_port))

        self.addressEntry.textEdited.connect(lambda: self.apply())
        self.portEntry.textEdited.connect(lambda: self.apply())

        self.argumentsEntry.setText(' '.join(
            shlex.quote(arg) for arg in debug_state.command_line_args))
        self.argumentsEntry.textEdited.connect(lambda: self.updateArguments())

        self.accepted.connect(lambda: self.apply())
Ejemplo n.º 29
0
    def _set_labels_and_layout(self):
        """
        Creates this Widget's content and layout
        """
        # --- Content ---

        # Lecluse DevCorp. Logo
        logo = QLabel()
        logo.setPixmap(QPixmap("assets/LDC-dark.png"))
        logo.setFixedSize(QSize(
            512, 222))  # Original dimension is 2048x888, we divided by 4
        logo.setScaledContents(True)

        # App credo
        lab_app = QLabel(f'<b>{tr("app_title")}</b> {tr("about_sdc")}')

        # Devs
        features_lab = QLabel(tr("about_features"))
        ihm_lab = QLabel(tr("about_ihm"))
        web_lab = QLabel(tr("about_web"))
        features_dev = QLabel(
            f'{self.links_style}<a href="https://www.lecluse.fr">Olivier Lécluse</a>'
        )
        features_dev.setOpenExternalLinks(True)
        ihm_dev = QLabel(
            f'{self.links_style}<a href="https://www.linkedin.com/in/thomas-lécluse-62130395/">Thomas Lécluse</a>'
        )
        ihm_dev.setOpenExternalLinks(True)
        web_dev = QLabel(
            f'{self.links_style}<a href="https://www.linkedin.com/in/nicolas-lecluse-a3488752/">Nicolas Lécluse</a>'
        )
        web_dev.setOpenExternalLinks(True)

        # Documentation link
        lab_link_doc = QLabel(
            f'{tr("link_to")} {self.links_style}<a href="https://sdc.lecluse.fr">{tr("about_doc")}</a>'
        )
        lab_link_doc.setOpenExternalLinks(True)

        # Github link
        lab_link_git = QLabel(
            f'{tr("link_to")} {self.links_style}<a href="https://github.com/wawachief/SalleDeClasse">{tr("about_github")}</a>'
        )
        lab_link_git.setOpenExternalLinks(True)

        # Contact
        lab_contact = QLabel(
            f'{tr("about_contact")} {self.links_style}<a href="mailto:[email protected]">[email protected]</a>'
        )
        lab_contact.setOpenExternalLinks(True)

        # License
        lab_license = QLabel(
            f'{self.links_style}<a href="https://www.gnu.org/licenses/gpl-3.0.fr.html">GPL-3.0 License</a>'
        )
        lab_license.setOpenExternalLinks(True)

        # Version
        lab_app_version = QLabel(tr("app_version"))
        lab_bdd_version = QLabel(tr("bdd_version"))
        app_version = QLabel(AssetManager.getInstance().config(
            'main', 'version'))
        bdd_version = QLabel(str(self.bdd_version))

        # --- Layout ---
        box = QVBoxLayout()
        box.setMargin(0)
        box.setSpacing(0)

        # Logo
        box.addWidget(logo, alignment=Qt.AlignCenter)

        Separator(self.width(), box)  # ----

        # 'Salle de Classe' credo
        box.addWidget(lab_app, alignment=Qt.AlignCenter)
        box.addSpacing(SPACING_SIZE)

        # Devs roles
        dev_grid = QGridLayout()
        dev_grid.setContentsMargins(0, 0, 0, 0)
        dev_grid.addWidget(features_lab, 0, 0, alignment=Qt.AlignRight)
        dev_grid.addWidget(ihm_lab, 1, 0, alignment=Qt.AlignRight)
        dev_grid.addWidget(web_lab, 2, 0, alignment=Qt.AlignRight)
        dev_grid.addWidget(features_dev, 0, 1, alignment=Qt.AlignLeft)
        dev_grid.addWidget(ihm_dev, 1, 1, alignment=Qt.AlignLeft)
        dev_grid.addWidget(web_dev, 2, 1, alignment=Qt.AlignLeft)
        box.addLayout(dev_grid)

        # Contact
        box.addSpacing(SPACING_SIZE)
        box.addWidget(lab_contact, alignment=Qt.AlignCenter)

        Separator(self.width(), box)  # ----

        # Links of doc, git and license
        box.addWidget(lab_link_doc, alignment=Qt.AlignCenter)
        box.addWidget(lab_link_git, alignment=Qt.AlignCenter)
        box.addSpacing(SPACING_SIZE)
        box.addWidget(lab_license, alignment=Qt.AlignCenter)

        Separator(self.width(), box)  # ----

        # Version
        grid_version = QGridLayout()
        grid_version.addWidget(lab_app_version, 0, 0, alignment=Qt.AlignRight)
        grid_version.addWidget(lab_bdd_version, 1, 0, alignment=Qt.AlignRight)
        grid_version.addWidget(app_version, 0, 1, alignment=Qt.AlignLeft)
        grid_version.addWidget(bdd_version, 1, 1, alignment=Qt.AlignLeft)
        box.addLayout(grid_version)
        box.addSpacing(SPACING_SIZE)

        self.setLayout(box)
Ejemplo n.º 30
0
    def __init__(self, parent, data):
        if not type(data) == binaryninja.binaryview.BinaryView:
            raise Exception('expected widget data to be a BinaryView')

        self.bv = data

        self.debug_state = binjaplug.get_state(data)
        memory_view = self.debug_state.memory_view
        self.debug_state.ui.debug_view = self

        QWidget.__init__(self, parent)
        self.controls = ControlsWidget.DebugControlsWidget(
            self, "Controls", data, self.debug_state)
        View.__init__(self)

        self.setupView(self)

        self.current_offset = 0

        self.splitter = QSplitter(Qt.Orientation.Horizontal, self)

        frame = ViewFrame.viewFrameForWidget(self)
        self.memory_editor = LinearView(memory_view, frame)
        self.binary_editor = DisassemblyContainer(frame, data, frame)

        self.binary_text = TokenizedTextView(self, memory_view)
        self.is_raw_disassembly = False

        # TODO: Handle these and change views accordingly
        # Currently they are just disabled as the DisassemblyContainer gets confused
        # about where to go and just shows a bad view
        self.binary_editor.getDisassembly().actionHandler().bindAction(
            "View in Hex Editor", UIAction())
        self.binary_editor.getDisassembly().actionHandler().bindAction(
            "View in Linear Disassembly", UIAction())
        self.binary_editor.getDisassembly().actionHandler().bindAction(
            "View in Types View", UIAction())

        self.memory_editor.actionHandler().bindAction("View in Hex Editor",
                                                      UIAction())
        self.memory_editor.actionHandler().bindAction(
            "View in Disassembly Graph", UIAction())
        self.memory_editor.actionHandler().bindAction("View in Types View",
                                                      UIAction())

        small_font = QApplication.font()
        small_font.setPointSize(11)

        bv_layout = QVBoxLayout()
        bv_layout.setSpacing(0)
        bv_layout.setContentsMargins(0, 0, 0, 0)

        bv_label = QLabel("Loaded File")
        bv_label.setFont(small_font)
        bv_layout.addWidget(bv_label)
        bv_layout.addWidget(self.binary_editor)

        self.bv_widget = QWidget()
        self.bv_widget.setLayout(bv_layout)

        disasm_layout = QVBoxLayout()
        disasm_layout.setSpacing(0)
        disasm_layout.setContentsMargins(0, 0, 0, 0)

        disasm_label = QLabel("Raw Disassembly at PC")
        disasm_label.setFont(small_font)
        disasm_layout.addWidget(disasm_label)
        disasm_layout.addWidget(self.binary_text)

        self.disasm_widget = QWidget()
        self.disasm_widget.setLayout(disasm_layout)

        memory_layout = QVBoxLayout()
        memory_layout.setSpacing(0)
        memory_layout.setContentsMargins(0, 0, 0, 0)

        memory_label = QLabel("Debugged Process")
        memory_label.setFont(small_font)
        memory_layout.addWidget(memory_label)
        memory_layout.addWidget(self.memory_editor)

        self.memory_widget = QWidget()
        self.memory_widget.setLayout(memory_layout)

        self.splitter.addWidget(self.bv_widget)
        self.splitter.addWidget(self.memory_widget)

        # Equally sized
        self.splitter.setSizes([0x7fffffff, 0x7fffffff])

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self.controls)
        layout.addWidget(self.splitter, 100)
        self.setLayout(layout)

        self.needs_update = True
        self.update_timer = QTimer(self)
        self.update_timer.setInterval(200)
        self.update_timer.setSingleShot(False)
        self.update_timer.timeout.connect(lambda: self.updateTimerEvent())

        self.add_scripting_ref()
Ejemplo n.º 31
0
    def __init__(self, app, parent=None):
        super(MainWindow, self).__init__(parent)
        self.imagesDir = app.dir + '/images/'
        self.setWindowIcon(QIcon(self.imagesDir + 'icon.png'))
        self.path = ''

        self.settings = QSettings()
        self.lastDir = self.settings.value('lastDir', '')

        self.setMinimumWidth(540)

        self.supportedFormats = []
        for f in QImageReader.supportedImageFormats():
            self.supportedFormats.append(str(f.data(), encoding="utf-8"))

        self.fileWatcher = QFileSystemWatcher()
        self.fileWatcher.fileChanged.connect(self.fileChanged)

        # widgets
        self.showPixmapWidget = None

        self.tileWidthSpinBox = QSpinBox()
        self.tileWidthSpinBox.setValue(16)
        self.tileWidthSpinBox.setFixedWidth(50)
        self.tileWidthSpinBox.setMinimum(1)

        self.tileHeightSpinBox = QSpinBox()
        self.tileHeightSpinBox.setValue(16)
        self.tileHeightSpinBox.setFixedWidth(50)
        self.tileHeightSpinBox.setMinimum(1)

        self.paddingSpinBox = QSpinBox()
        self.paddingSpinBox.setFixedWidth(50)
        self.paddingSpinBox.setMinimum(1)

        self.transparentCheckbox = QCheckBox("Transparent")
        self.transparentCheckbox.setChecked(True)
        self.transparentCheckbox.stateChanged.connect(self.transparentChanged)

        self.backgroundColorEdit = ColorEdit()
        self.backgroundColorEdit.setEnabled(False)
        self.backgroundColorLabel = QLabel("Background color:")
        self.backgroundColorLabel.setEnabled(False)

        self.forcePotCheckBox = QCheckBox("Force PoT")
        self.forcePotCheckBox.setChecked(True)
        self.forcePotCheckBox.stateChanged.connect(self.forcePotChanged)

        self.reorderTilesCheckBox = QCheckBox("Reorder tiles")

        self.generateAndExportButton = QPushButton("Generate and export")
        self.generateAndExportButton.setFixedHeight(32)
        self.generateAndExportButton.clicked.connect(self.generateAndExportClicked)
        self.generateAndExportButton.setEnabled(False)

        self.pixmapWidget = PixmapWidget()
        self.pixmapWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.pixmapWidget.setPixmap(self.createDropTextPixmap())
        self.pixmapWidget.dropSignal.connect(self.fileDropped)
        self.pixmapWidget.setMinimumHeight(300)

        # load settings
        self.tileWidthSpinBox.setValue(int(self.settings.value('tileWidth', 16)))
        self.tileHeightSpinBox.setValue(int(self.settings.value('tileHeight', 16)))
        self.paddingSpinBox.setValue(int(self.settings.value('padding', 1)))
        self.forcePotCheckBox.setChecked(True if self.settings.value('forcePot', 'true') == 'true' else False)
        self.reorderTilesCheckBox.setChecked(True if self.settings.value('reorderTiles', 'false') == 'true' else False)
        self.transparentCheckbox.setChecked(True if self.settings.value('transparent', 'false') == 'true' else False)
        self.backgroundColorEdit.setColorText(str(self.settings.value('backgroundColor', '#FF00FF')))
        self.restoreGeometry(QByteArray(self.settings.value('MainWindow/geometry')))
        self.restoreState(QByteArray(self.settings.value('MainWindow/windowState')))

        # layout
        hl1 = QHBoxLayout()
        hl1.setContentsMargins(5, 5, 5, 5)
        hl1.addWidget(QLabel("Tile width:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileWidthSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Tile height:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.tileHeightSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(QLabel("Padding:"))
        hl1.addSpacing(5)
        hl1.addWidget(self.paddingSpinBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.forcePotCheckBox)
        hl1.addSpacing(15)
        hl1.addWidget(self.reorderTilesCheckBox)
        hl1.addStretch()

        hl2 = QHBoxLayout()
        hl2.setContentsMargins(5, 5, 5, 5)
        hl2.addWidget(self.transparentCheckbox)
        hl2.addSpacing(15)
        hl2.addWidget(self.backgroundColorLabel)
        hl2.addSpacing(5)
        hl2.addWidget(self.backgroundColorEdit)
        hl2.addStretch()

        hl3 = QHBoxLayout()
        hl3.setContentsMargins(5, 5, 5, 5)
        hl3.addWidget(self.generateAndExportButton)

        vl = QVBoxLayout()
        vl.setContentsMargins(0, 0, 0, 0)
        vl.setSpacing(0)
        vl.addLayout(hl1)
        vl.addLayout(hl2)
        vl.addWidget(self.pixmapWidget)
        vl.addLayout(hl3)

        w = QWidget()
        w.setLayout(vl)
        self.setCentralWidget(w)

        self.setTitle()