Пример #1
0
    def __create_source_layout(self, side):
        sourceLayout = QVBoxLayout()
        selectedSourceFrame = QFrame()
        selectedSourceFrame.setFrameShape(QFrame.Box)
        selectedSourceFrame.setFrameShadow(QFrame.Raised)
        selectedSourceLayout = QGridLayout(selectedSourceFrame)
        sourceLabel = QLabel("Selected account: None")
        sourceLabel.setObjectName("SourceLabel{}".format(side))
        selectedSourceLayout.addWidget(sourceLabel, 0, 0)
        changeSourceBtn = QPushButton("Change...")
        changeSourceBtn.clicked.connect(lambda: self.__account_select(side))
        selectedSourceLayout.addWidget(changeSourceBtn, 0, 1)
        playlistLabel = QLabel("Selected playlist:")
        playlistLabel.setObjectName("PlaylistLabel{}".format(side))
        playlistLabel.setDisabled(True)
        selectedSourceLayout.addWidget(playlistLabel, 1, 0)
        playlistSelect = QComboBox()
        playlistSelect.setDisabled(True)
        playlistSelect.setObjectName("Playlist{}".format(side))
        playlistSelect.currentIndexChanged.connect(
            lambda: self.__playlist_select(side))
        selectedSourceLayout.addWidget(playlistSelect, 1, 1)
        sourceLayout.addWidget(selectedSourceFrame)

        trackList = QListWidget()
        trackList.setObjectName("Tracklist{}".format(side))
        trackList.currentItemChanged.connect(self.__track_select)
        sourceLayout.addWidget(trackList)
        return sourceLayout
    def __init__(self, x, y, w, h):
        QWidget.__init__(self)
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        self.title = Box.title
        start_position = (self.x, self.y, self.w, self.h)

        self.setGeometry(*start_position)
        width = self.w - self.x
        height = self.h - self.y
        self.resize(width, height)

        tb = QtWidgets.QToolBar

        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)

        layout = QtWidgets.QHBoxLayout(self)
        frame = QFrame(self)
        # frame.setFrameShape(QFrame.StyledPanel)
        frame.setFrameShape(QFrame.WinPanel)
        frame.setLineWidth(.1)
        layout.addWidget(frame)

        self.show()
Пример #3
0
    def __init__(self, route=None):
        super().__init__()

        layout = QVBoxLayout()
        self.route = route

        self.preview_text_edit = QTextEdit()
        self.preview_text_edit.setFont(TEXT_FONT)
        self.preview_text_edit.setReadOnly(True)

        if route is not None:
            if route.group is not None:
                for parameter in route.group.parameters:
                    param_layout = self._create_parameter_layout(
                        route.group.storage_prefix, parameter)
                    layout.addLayout(param_layout)

                line = QFrame()
                line.setFrameShape(QFrame.HLine)
                line.setFrameShadow(QFrame.Sunken)
                layout.addWidget(line)

            for parameter in route.parameters:
                param_layout = self._create_parameter_layout(
                    route.storage_prefix, parameter)
                layout.addLayout(param_layout)

        self.highlighter = TextHighlighter(self.preview_text_edit.document())
        self._update_preview()
        layout.addWidget(self.preview_text_edit)

        self.setLayout(layout)
Пример #4
0
 def horizontal_line():
     line = QFrame()
     line.setFrameShape(QFrame.HLine)
     line.setFrameShadow(QFrame.Sunken)
     line.setFixedHeight(2)
     line.setContentsMargins(0, 30, 0, 0)
     return line
Пример #5
0
    def __init__(self):
        super().__init__()
        page2Layout = QVBoxLayout(self)

        table_header = QHBoxLayout()
        label0 = QLabel()
        label0.setObjectName("label0")
        table_header.addWidget(label0)
        table_header.addItem(QSpacerItem(1, 1, QSizePolicy.Expanding, QSizePolicy.Minimum))
        label1 = QLabel()
        label1.setObjectName("label1")
        table_header.addWidget(label1)
        page2Layout.addLayout(table_header)

        hLine = QFrame(self.__songs_table)
        hLine.setFrameShape(QFrame.HLine)
        hLine.setFrameShadow(QFrame.Sunken)
        page2Layout.addWidget(hLine)

        scrollArea = QScrollArea()
        scrollClient = QWidget()
        scrollClient.setObjectName("scrollClient")
        scrollArea.setWidgetResizable(True)
        scrollArea.setWidget(scrollClient)
        page2Layout.addWidget(scrollArea)

        self.__new_song_row.connect(self.__add_song_row)
Пример #6
0
def _create_vertical_line():
    vertical_line = QFrame()
    vertical_line.setFixedWidth(20)
    vertical_line.setFrameShape(QFrame.VLine)
    vertical_line.setFrameShadow(QFrame.Sunken)
    vertical_line.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
    vertical_line.setMinimumHeight(300)
    return vertical_line
Пример #7
0
class Separator:
    def __init__(self):
        self.widget = QFrame()
        self.widget.setFrameShape(QFrame.HLine)
        self.widget.setFrameShadow(QFrame.Sunken)

    def getWidget(self):
        return self.widget
Пример #8
0
    def build_ui(self):
        self.setGeometry(50, 50, 450, 300)
        self.setMinimumSize(400, 300)
        self.setWindowTitle('Spore Reporter')

        layout = QVBoxLayout()

        #  self.err_wdg = QWidget()
        #  err_layout = QHBoxLayout(self.err_wdg)
        #  layout.addWidget(err_wdg)
        #
        #  err_lbl = 'Ops..\nSpore seems to have caused an error.\n'

        info_msg = 'Help to improve Spore by anonymously submitting your logs'
        self.info_lbl = QLabel(info_msg)
        layout.addWidget(self.info_lbl)

        self.address_edt = QLineEdit()
        self.address_edt.setPlaceholderText('E-Mail Address (optional)')
        layout.addWidget(self.address_edt)

        self.subject_edt = QLineEdit()
        self.subject_edt.setPlaceholderText('Subject (optional)')
        layout.addWidget(self.subject_edt)

        self.msg_edt = QTextEdit()
        self.msg_edt.setPlaceholderText('Message (optional)')
        self.msg_edt.setFixedHeight(60)
        layout.addWidget(self.msg_edt)

        self.log_edt = QTextEdit()
        self.log_edt.setReadOnly(True)
        self.log_edt.setLineWrapMode(QTextEdit.NoWrap)
        layout.addWidget(self.log_edt)

        ctrl_layout = QGridLayout()
        layout.addLayout(ctrl_layout)

        self.submit_btn = QPushButton('Submit')
        ctrl_layout.addWidget(self.submit_btn, 0, 0, 1, 1)

        self.cancel_btn = QPushButton('Cancel')
        ctrl_layout.addWidget(self.cancel_btn, 0, 1, 1, 1)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        ctrl_layout.addWidget(line, 1, 0, 1, 2)

        self.disable_btn = QPushButton('Disable Reporter')
        ctrl_layout.addWidget(self.disable_btn, 2, 0, 1, 1)

        self.auto_btn = QPushButton('Send Reports Automatically')
        ctrl_layout.addWidget(self.auto_btn, 2, 1, 1, 1)

        self.setLayout(layout)
Пример #9
0
class Layout_Main_Window(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.Main_Layout = QHBoxLayout()
        self.Child_1 = Layout_Child_1()
        self.Child_2 = Layout_Child_2()
        self.Main_Layout.addWidget(self.Child_1)
        self.line = QFrame()
        self.line.setFrameShape(QFrame.VLine)
        self.line.setFrameShadow(QFrame.Sunken)
        self.Main_Layout.addWidget(self.line)
        self.Main_Layout.addWidget(self.Child_2)
        self.setLayout(self.Main_Layout)
Пример #10
0
class PageAbout(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self)
        parent.addWidget(self)
        self.gridLayout_about = QGridLayout(self)

        self.frame_about = QFrame(self)
        self.frame_about.setEnabled(True)
        self.frame_about.setStyleSheet(styles.frame_about)
        self.frame_about.setFrameShape(QFrame.StyledPanel)
        self.frame_about.setFrameShadow(QFrame.Raised)
        self.gridLayout_about.addWidget(self.frame_about, 0, 1, 1, 1)

        self.gridLayout_frame_about = QGridLayout(self.frame_about)
        self.gridLayout_frame_about.setContentsMargins(-1, 60, -1, -1)

        self.spacer_about_l = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                          QSizePolicy.Minimum)
        self.spacer_about_r = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                          QSizePolicy.Minimum)
        self.spacer_about_b = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                          QSizePolicy.Expanding)
        self.gridLayout_frame_about.addItem(self.spacer_about_l, 0, 0, 1, 1)
        self.gridLayout_frame_about.addItem(self.spacer_about_r, 0, 2, 1, 1)
        self.gridLayout_frame_about.addItem(self.spacer_about_b, 3, 1, 1, 1)

        self.label_about_name = QLabel("WebCheck", self.frame_about)
        self.label_about_name.setStyleSheet(styles.label_about_name)
        self.label_about_name.setAlignment(Qt.AlignCenter)
        self.gridLayout_frame_about.addWidget(self.label_about_name, 0, 1, 1,
                                              1)

        self.label_about_name = QLabel(
            "Made by Eugene Oros & Michał Piotrowski", self.frame_about)
        self.label_about_name.setStyleSheet(styles.label_about_made)
        self.label_about_name.setAlignment(Qt.AlignCenter)
        self.gridLayout_frame_about.addWidget(self.label_about_name, 1, 1, 1,
                                              1)

        self.label_about_version = QLabel("Version 1.0.0", self.frame_about)
        self.label_about_version.setStyleSheet(styles.label_about_version)
        self.label_about_version.setAlignment(Qt.AlignCenter)
        self.gridLayout_frame_about.addWidget(self.label_about_version, 2, 0,
                                              1, 3)

        self.label_about_c = QLabel("\u00a9 All rights reserved",
                                    self.frame_about)
        self.label_about_c.setStyleSheet(styles.label_about_c)
        self.label_about_c.setAlignment(Qt.AlignCenter)
        self.gridLayout_frame_about.addWidget(self.label_about_c, 3, 0, 1, 3)
Пример #11
0
 def __init__(self, parent=None):
     '''Constructor Function'''
     QWidget.__init__(self, parent)
     self.Main_Layout = QHBoxLayout()
     self.Child_1 = Layout_Child_1()
     self.Child_2 = Layout_Child_2()
     self.Main_Layout.addWidget(self.Child_1)
     # Add a Saperator
     line = QFrame()
     line.setFrameShape(QFrame.VLine)
     line.setFrameShadow(QFrame.Sunken)
     self.Main_Layout.addWidget(line)
     self.Main_Layout.addWidget(self.Child_2)
     self.setLayout(self.Main_Layout)
Пример #12
0
 def set_up_group_box(self):
     self.desc_group_box.setLayout(QVBoxLayout())
     self.desc_label = QLabel(self.model.desc)
     self.desc_label.setWordWrap(True)
     self.desc_group_box.layout().addWidget(self.desc_label)
     if isinstance(self.model, (MonsterCard)):
         self.desc_group_box.setTitle(self.get_group_box_title())
         line = QFrame()
         line.setFrameShape((QFrame.HLine))
         line.setFrameShadow(QFrame.Sunken)
         self.desc_group_box.layout().addWidget(line)
         label = QLabel(
             f"ATK/{self.model.attack}  DEF/{self.model.defence}")
         label.setAlignment(Qt.AlignRight)
         self.desc_group_box.layout().addWidget(label)
Пример #13
0
    def __init__(self):
        super(Main_Widget,self).__init__()

        First = First_Widget()
        Second = Second_Widget()
        Third = Second_Widget()
        Line = QFrame()
        Line.setFrameShape(QFrame.VLine)
        Line.setFrameShadow(QFrame.Sunken)
        H_Layout = QHBoxLayout()
        H_Layout.addWidget(Second)
        #H_Layout.addWidget(First)
        H_Layout.addWidget(Line)
        H_Layout.addWidget(Third)
        self.setLayout(H_Layout)
Пример #14
0
    def __init__(self):
        super(Zero_Layout,self).__init__()
        First = First_Layout()
        Second = Second_Layout()
        Third = Third_Layout()

        H_layout = QHBoxLayout()
        
        H_layout.addWidget(First)
        line = QFrame()
        line.setFrameShape(QFrame.VLine)
        line.setFrameShadow(QFrame.Sunken)
        H_layout.addWidget(line)
        #H_layout.addWidget(Second)
        H_layout.addWidget(Third)
        self.setLayout(H_layout)
Пример #15
0
    def __init__(self, controller, parent=None):
        super(CommandParser, self).__init__(parent)
        self.controller = controller
        cmnd2send_label = QLabel('Command:')
        cmnd2send_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        self.cmnd2send_editor = QLineEdit()

        # cmnd2send_editor.setKeyboardTracking(False)
        self.cmnd2send_editor.setAlignment(Qt.AlignLeft)
        self.cmnd2send_editor.setSizePolicy(QSizePolicy.MinimumExpanding,
                                            QSizePolicy.Fixed)
        # cmnd2send_editor.setClearButtonEnabled()
        send_button = QPushButton('Send')
        send_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        separator = QFrame()
        separator.setFrameShape(QFrame.HLine)
        separator.setFrameShadow(QFrame.Sunken)
        separator.setSizePolicy(QSizePolicy.MinimumExpanding,
                                QSizePolicy.Fixed)

        scrollbar = QScrollBar()
        cmnd_received_label = QLabel('RESPONSE:')
        self.cmnd_received_window = QTextEdit()
        # self.cmnd_received_window.moveCursor(QTextCursor.Down)
        self.cmnd_received_window.setReadOnly(True)
        self.cmnd_received_window.setVerticalScrollBar(scrollbar)

        # Layout
        editor_layout = QGridLayout()
        editor_layout.addWidget(cmnd2send_label, 0, 0)
        editor_layout.addWidget(self.cmnd2send_editor, 0, 1)
        editor_layout.addWidget(send_button, 0, 2)

        editor_layout.addWidget(separator, 1, 0, 1, 3)

        editor_layout.addWidget(cmnd_received_label, 2, 0, 1, 3)
        editor_layout.addWidget(self.cmnd_received_window, 3, 0, 1, 3)

        layout = QHBoxLayout()
        layout.addLayout(editor_layout)
        self.setLayout(layout)

        # Signals and slots
        send_button.clicked.connect(self.parse_cmnd)
class Welcome_Widget(QWidget):
    def __init__(self, parent=None):
        super(Welcome_Widget, self).__init__(parent)
        self.setUp_UI()

    def setUp_UI(self):
        self.image = Image_Widget(self)
        self.line = QFrame()
        self.line.setFrameShape(QFrame.VLine)
        self.line.setFrameShadow(QFrame.Sunken)
        self.login = Login_Widget(self)
        self.layout = QHBoxLayout()
        self.layout.addWidget(self.image)
        self.layout.addWidget(self.line)
        self.layout.addWidget(self.login)

        self.setLayout(self.layout)
Пример #17
0
    def _init_widgets(self):
        self.resize(530, 180)
        main_layout = QVBoxLayout()
        frame = QFrame()
        frame.setFrameShape(QFrame.NoFrame)
        frame.setFrameShadow(QFrame.Plain)
        frameLayout = QVBoxLayout()
        self.connectRad = QRadioButton(frame)
        self.createRad = QRadioButton(frame)
        self.connectRad.setChecked(True)
        self.connectRad.toggled.connect(self.handleRadioButtons)
        self.createRad.toggled.connect(self.handleRadioButtons)
        frameLayout.addWidget(self.connectRad)
        internalFrame = QFrame()
        internalFrameLayout = QHBoxLayout(internalFrame)
        hostLabel = QLabel()
        portLabel = QLabel()
        self.hostText = QLineEdit()
        self.portText = QLineEdit()
        internalFrameLayout.addWidget(hostLabel)
        internalFrameLayout.addWidget(self.hostText)
        internalFrameLayout.addWidget(portLabel)
        internalFrameLayout.addWidget(self.portText)
        self.portText.setMaximumSize(QSize(80, 200))
        internalFrame.setLayout(internalFrameLayout)
        frameLayout.addWidget(internalFrame)
        frameLayout.addWidget(self.createRad)
        frame.setLayout(frameLayout)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        main_layout.addWidget(frame)
        main_layout.addWidget(self.buttonBox)

        self.setLayout(main_layout)
        self.setWindowTitle("Cartprograph Connect")
        self.connectRad.setText("Connect to Existing Cartprograph Server")
        self.createRad.setText("Create New Cartprograph Server")
        hostLabel.setText("Host")
        portLabel.setText("Port")
Пример #18
0
 def __init__(self, parent=None):
     super(MainWindow, self).__init__(parent)
     self.setFixedSize(1200, 920)
     self.setWindowTitle("Vlasov Roman lr3")
     # OpenGL widget
     glWidgetW = 800
     glWidgetH = 900
     self.OpenGLWidget = OpenGLView()
     self.OpenGLWidget.setFixedSize(glWidgetW, glWidgetH)
     self.OpenGLWidget.setIterations(0)
     # number of iterations
     minIter = 0
     maxIter = 6
     self.iterationsLabel = QLabel("Number of iterations: ")
     self.iterationsSpinBox = QSpinBox()
     self.iterationsSpinBox.setMinimum(minIter)
     self.iterationsSpinBox.setMaximum(maxIter)
     self.iterationsSpinBox.valueChanged.connect(self.onSpinPointsChanged)
     self.iterationsSlider = QSlider(QtCore.Qt.Horizontal)
     self.iterationsSlider.setMinimum(minIter)
     self.iterationsSlider.setMaximum(maxIter)
     self.iterationsSlider.valueChanged.connect(self.onSliderPointsChanged)
     self.iterationsMinLabel = QLabel("Min: %d" % minIter)
     self.iterationsMinLabel.setFixedWidth(40)
     self.iterationsMaxLabel = QLabel("Max: %d" % maxIter)
     self.iterationsMaxLabel.setFixedWidth(60)
     line1 = QFrame()
     line1.setFrameShape(QFrame.HLine)
     layoutAmount = QHBoxLayout()
     layoutAmount.addWidget(self.iterationsMinLabel)
     layoutAmount.addWidget(self.iterationsSpinBox)
     layoutAmount.addWidget(self.iterationsMaxLabel)
     # tools panel layout
     layoutTools = QVBoxLayout()
     layoutTools.addWidget(self.iterationsLabel)
     layoutTools.addLayout(layoutAmount)
     layoutTools.addWidget(self.iterationsSlider)
     verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                  QSizePolicy.Expanding)
     layoutTools.addItem(verticalSpacer)
     # window layout
     layout = QHBoxLayout()
     layout.addWidget(self.OpenGLWidget)
     layout.addLayout(layoutTools)
     self.setLayout(layout)
Пример #19
0
class Ui_FE14ChapterEditor(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.toolbar = QToolBar()
        self.addToolBar(self.toolbar)
        self.add_chapter_action = QAction("Add Chapter")
        self.hide_selector_action = QAction("Toggle Selection Pane")
        self.toolbar.addAction(self.add_chapter_action)
        self.toolbar.addSeparator()
        self.toolbar.addAction(self.hide_selector_action)

        self.selector_layout = QVBoxLayout()
        self.chapter_search_bar = QLineEdit()
        self.chapter_search_bar.setPlaceholderText("Search...")
        self.chapter_list_view = QListView()
        self.selector_layout.addWidget(self.chapter_search_bar)
        self.selector_layout.addWidget(self.chapter_list_view)
        self.selector_widget = QWidget()
        self.selector_widget.setLayout(self.selector_layout)
        self.selector_widget.setFixedWidth(225)

        self.config_tab = FE14ChapterConfigTab()
        self.map_tab = FE14MapEditor()
        self.characters_tab = FE14CharacterEditor(is_person=True)
        self.conversation_tab = FE14ConversationEditor()
        self.tab_widget = QTabWidget()
        self.tab_widget.addTab(self.config_tab, "Config")
        self.tab_widget.addTab(self.map_tab, "Map")
        self.tab_widget.addTab(self.characters_tab, "Characters")
        self.tab_widget.addTab(self.conversation_tab, "Text")

        self.main_layout = QHBoxLayout()
        self.main_widget = QWidget()
        self.visual_splitter = QFrame()
        self.visual_splitter.setFrameShape(QFrame.VLine)
        self.visual_splitter.setFrameShadow(QFrame.Sunken)
        self.main_widget.setLayout(self.main_layout)
        self.main_layout.addWidget(self.selector_widget)
        self.main_layout.addWidget(self.visual_splitter)
        self.main_layout.addWidget(self.tab_widget)
        self.setCentralWidget(self.main_widget)
Пример #20
0
    def initUI(self):

        hbox = QHBoxLayout()

        topleft = QFrame(self)
        topleft.setFrameShape(QFrame.StyledPanel)
        # topleft.setFrameShape(QFrame.Shadow)    # ? 报错

        topright = QFrame(self)
        topright.setFrameShape(QFrame.StyledPanel)

        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.StyledPanel)

        splitter1 = QSplitter(Qt.Horizontal)  # 横向增加部件
        splitter1.addWidget(topleft)
        splitter1.addWidget(topright)

        splitter2 = QSplitter(Qt.Vertical)
        splitter2.addWidget(splitter1)
        splitter2.addWidget(bottom)

        hbox.addWidget(splitter2)
        self.setLayout(hbox)

        self.setGeometry(300, 300, 600, 400)
        self.setWindowTitle("QSplitter")
        self.show()
Пример #21
0
    def initUI(self):
        hbox = QHBoxLayout(self)

        topleft = QFrame(self)
        topleft.setFrameShape(QFrame.StyledPanel)

        topright = QFrame(self)
        topright.setFrameShape(QFrame.StyledPanel)

        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.StyledPanel)

        splitter1 = QSplitter(QtCore.Qt.Horizontal)
        splitter1.addWidget(topleft)
        splitter1.addWidget(topright)

        splitter2 = QSplitter(QtCore.Qt.Vertical)
        splitter2.addWidget(splitter1)
        splitter2.addWidget(bottom)

        hbox.addWidget(splitter2)
        self.setLayout(hbox)
        QApplication.setStyle(QStyleFactory.create('Cleanlooks'))

        self.setGeometry(500, 500, 500, 500)
        self.setWindowTitle('QSplitter')
        self.show()
Пример #22
0
 def setupLayout(self):
     # OpenGL widget
     glWidgetW = 800
     glWidgetH = 900
     self.OpenGLWidget = OpenGLView()
     self.OpenGLWidget.setFixedSize(glWidgetW, glWidgetH)
     self.OpenGLWidget.updatePoints(self.x, self.y, self.z)
     # radio buttons
     self.cubicSplineInterpolationMode = QRadioButton(
         "Cubic Spline Interpolation mode")
     self.cubicSplineInterpolationMode.setChecked(True)
     self.cubicSplineInterpolationMode.toggled.connect(
         self.onModeRadioButtonToggled)
     self.BesierCurveMode = QRadioButton(" Besier Curve mode")
     line1 = QFrame()
     line1.setFrameShape(QFrame.HLine)
     # point coords layout
     pointsLayout = QVBoxLayout()
     [
         pointsLayout.addLayout(
             self.createPointWidget(self.x[i], self.y[i], self.z[i]))
         for i in range(self.points)
     ]
     # tools panel layout
     layoutTools = QVBoxLayout()
     layoutTools.addWidget(self.cubicSplineInterpolationMode)
     layoutTools.addWidget(self.BesierCurveMode)
     layoutTools.addWidget(line1)
     layoutTools.addLayout(pointsLayout)
     verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                  QSizePolicy.Expanding)
     layoutTools.addItem(verticalSpacer)
     # window layout
     layout = QHBoxLayout()
     layout.addWidget(self.OpenGLWidget)
     layout.addLayout(layoutTools)
     self.setLayout(layout)
Пример #23
0
class Ui_FilewriterCtrl(object):
    def setupUi(self, FilewriterCtrl):
        FilewriterCtrl.resize(649, 450)
        broker_placeholder_text = "address:port/topic"
        self.central_widget = QWidget(FilewriterCtrl)
        self.vertical_layout_2 = QVBoxLayout(self.central_widget)
        self.vertical_layout = QVBoxLayout()
        self.horizontal_layout = QHBoxLayout()
        self.horizontal_layout.setContentsMargins(-1, -1, 0, -1)
        self.status_layout = QVBoxLayout()
        self.status_layout.setContentsMargins(-1, -1, -1, 0)
        self.status_topic_layout = QHBoxLayout()
        self.status_topic_layout.setContentsMargins(-1, -1, -1, 0)
        self.status_broker_label = QLabel(self.central_widget)
        self.status_topic_layout.addWidget(self.status_broker_label)
        self.status_broker_edit = QLineEdit(self.central_widget)
        self.status_broker_edit.setPlaceholderText(broker_placeholder_text)

        self.status_topic_layout.addWidget(self.status_broker_edit)
        self.status_layout.addLayout(self.status_topic_layout)
        self.line_2 = QFrame(self.central_widget)
        self.line_2.setFrameShape(QFrame.HLine)
        self.line_2.setFrameShadow(QFrame.Sunken)
        self.status_layout.addWidget(self.line_2)
        self.file_writer_table_group = QGroupBox(self.central_widget)
        size_policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(1)
        size_policy.setHeightForWidth(
            self.file_writer_table_group.sizePolicy().hasHeightForWidth())
        self.file_writer_table_group.setSizePolicy(size_policy)
        self.vertical_layout_4 = QVBoxLayout(self.file_writer_table_group)
        self.vertical_layout_3 = QVBoxLayout()
        self.file_writers_list = QTreeView(self.file_writer_table_group)
        self.file_writers_list.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        self.file_writers_list.setIndentation(0)
        self.vertical_layout_3.addWidget(self.file_writers_list)
        self.vertical_layout_4.addLayout(self.vertical_layout_3)
        self.status_layout.addWidget(self.file_writer_table_group)
        self.files_group = QGroupBox(self.central_widget)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(4)
        size_policy.setHeightForWidth(
            self.files_group.sizePolicy().hasHeightForWidth())
        self.files_group.setSizePolicy(size_policy)
        self.vertical_layout_6 = QVBoxLayout(self.files_group)
        self.files_list = QTreeView(self.files_group)
        self.files_list.setIndentation(0)
        self.vertical_layout_6.addWidget(self.files_list)
        self.vertical_layout_5 = QVBoxLayout()
        self.horizontal_layout_4 = QHBoxLayout()
        spacer = QSpacerItem(40, 20, QSizePolicy.Expanding,
                             QSizePolicy.Minimum)
        self.horizontal_layout_4.addItem(spacer)
        self.stop_file_writing_button = QPushButton(self.files_group)
        self.stop_file_writing_button.setEnabled(False)
        self.horizontal_layout_4.addWidget(self.stop_file_writing_button)
        self.vertical_layout_5.addLayout(self.horizontal_layout_4)
        self.vertical_layout_6.addLayout(self.vertical_layout_5)
        self.status_layout.addWidget(self.files_group)
        self.horizontal_layout.addLayout(self.status_layout)
        self.line = QFrame(self.central_widget)
        self.line.setFrameShape(QFrame.VLine)
        self.line.setFrameShadow(QFrame.Sunken)
        self.horizontal_layout.addWidget(self.line)

        self.command_layout = QVBoxLayout()
        self.command_layout.setContentsMargins(-1, 0, -1, 0)
        self.command_broker_layout = QHBoxLayout()
        self.command_broker_label = QLabel(self.central_widget)
        self.command_broker_layout.addWidget(self.command_broker_label)
        self.command_broker_edit = QLineEdit(self.central_widget)
        self.command_broker_edit.setPlaceholderText(broker_placeholder_text)
        self.command_broker_layout.addWidget(self.command_broker_edit)
        self.command_layout.addLayout(self.command_broker_layout)
        self.command_widget = FilewriterCommandWidget(FilewriterCtrl)
        self.command_layout.addWidget(self.command_widget)

        self.horizontal_layout.addLayout(self.command_layout)
        self.vertical_layout.addLayout(self.horizontal_layout)
        self.vertical_layout_2.addLayout(self.vertical_layout)
        FilewriterCtrl.setCentralWidget(self.central_widget)

        self.status_broker_label.setText("Status broker")
        self.file_writer_table_group.setTitle("File-writers")
        self.files_group.setTitle("Files")
        self.stop_file_writing_button.setText("Stop file-writing")
        self.command_broker_label.setText("Command broker")
        self.command_broker_edit.setPlaceholderText("address:port/topic")

        QMetaObject.connectSlotsByName(FilewriterCtrl)
Пример #24
0
class ElementAllegroMonitored(QFrame):

    def __init__(self, name, link, is_done, price, xpath, time, is_monitoring, parent=None, shared_dict=None):
        QFrame.__init__(self, parent)
        self.shared_dict = shared_dict
        self.setMinimumSize(QSize(0, 300))
        self.setStyleSheet("""QFrame{border-bottom: 0.5px solid #aaa;}""")
        self.setFrameShape(QFrame.StyledPanel)
        self.setFrameShadow(QFrame.Raised)
        self.horizontalLayout = QHBoxLayout(self)

        # create description frame and layout
        self.frame_description = QFrame(self)
        self.frame_description.setMinimumSize(QSize(440, 16777215))
        self.frame_description.setStyleSheet("""QFrame{border: none;}""")
        self.frame_description.setFrameShape(QFrame.StyledPanel)
        self.frame_description.setFrameShadow(QFrame.Raised)
        self.gridLayout_description = QGridLayout(self.frame_description)
        self.horizontalLayout.addWidget(self.frame_description)
        self.gridLayout_description.setColumnStretch(0, 1)
        self.gridLayout_description.setColumnStretch(1, 2)
        self.gridLayout_description.setColumnStretch(2, 3)
        self.gridLayout_description.setColumnStretch(3, 1)
        self.gridLayout_description.setColumnStretch(4, 6)

        # fill description layout
        self.label_name = QLabel(name, self.frame_description)
        self.label_name.setStyleSheet(styles.label_allegro_monitored_name)
        self.label_name.setTextFormat(Qt.MarkdownText)
        self.label_name.setAlignment(Qt.AlignJustify | Qt.AlignVCenter)
        self.label_name.setWordWrap(False)
        self.gridLayout_description.addWidget(self.label_name, 0, 0, 1, 5)

        self.url_link = "<a href=\"" + link + "\" style = \" color: #838836; text-decoration: none; font-family:corbel; title=\"Go to monitored page\"\">check product</a>"
        self.label_monitored_link = QLabel(url_link, self.frame_description)
        self.label_monitored_link.setStyleSheet(styles.label_allegro_monitored_link)
        self.gridLayout_description.addWidget(self.label_monitored_link, 1, 1, 2, 2)
        self.label_monitored_link.setOpenExternalLinks(True)

        self.label_stat = QLabel(self.frame_description)
        self.label_stat.setStyleSheet(styles.label_allegro_monitored_stat)
        self.gridLayout_description.addWidget(self.label_stat, 1, 4, 1, 1)

        self.label_is_on = QLabel(self.frame_description)
        self.label_is_on.setStyleSheet(styles.label_allegro_monitored_stat)
        self.gridLayout_description.addWidget(self.label_is_on, 5, 0, 1, 2)

        self.label_new_time = QLabel("Actual refresh time[s]: " + str(time)+" s", self.frame_description)
        self.label_new_time.setStyleSheet(styles.label_allegro_monitored_stat)
        self.gridLayout_description.addWidget(self.label_new_time, 4, 0, 1, 3)

        self.lineEdit_new_time = QLineEdit(self.frame_description)
        self.lineEdit_new_time.setMinimumSize(QSize(0, 33))
        self.lineEdit_new_time.setStyleSheet(styles.lineEdit)
        self.gridLayout_description.addWidget(self.lineEdit_new_time, 4, 3, 1, 2)
        self.lineEdit_new_time.setPlaceholderText("Set new interval")

        self.label_new_price = QLabel("Actual price: " + str(price), self)
        self.label_new_price.setStyleSheet(styles.label_allegro_monitored_stat)
        self.gridLayout_description.addWidget(self.label_new_price, 3, 0, 1, 3)

        self.lineEdit_new_price = QLineEdit(self)
        self.lineEdit_new_price.setMinimumSize(QSize(0, 35))
        self.lineEdit_new_price.setStyleSheet(styles.lineEdit)
        self.gridLayout_description.addWidget(self.lineEdit_new_price, 3, 3, 1, 2)
        self.lineEdit_new_price.setPlaceholderText("Set new price")

        self.label_img_link = QLabel(self.frame_description)
        self.label_img_link.setMaximumSize(QSize(20, 20))
        self.label_img_link.setStyleSheet("""QLabel{border: none;}""")
        self.label_img_link.setPixmap(QPixmap(os.path.join(path, "img/link.png")))
        self.label_img_link.setScaledContents(True)
        self.gridLayout_description.addWidget(self.label_img_link, 1, 0, 2, 1)

        self.label_img_stat = QLabel("done", self.frame_description)
        if is_done:
            self.label_stat.setText("done")
            self.label_img_stat.setPixmap(QPixmap(os.path.join(path, "img/check.png")))
        else:
            self.label_stat.setText("in progress")
            self.label_img_stat.setPixmap(QPixmap(os.path.join(path, "img/loading.png")))
        self.label_img_stat.setMaximumSize(QSize(20, 20))
        self.label_img_stat.setStyleSheet("""QLabel{border: none;}""")
        self.label_img_stat.setScaledContents(True)
        self.gridLayout_description.addWidget(self.label_img_stat, 1, 3, 1, 1)

        self.label_img_monitor = QLabel("done", self.frame_description)
        if is_monitoring:
            monitor_text = "I am just monitoring"
            self.label_img_monitor.setPixmap(QPixmap(os.path.join(path, "img/monitoring.png")))
        else:
            monitor_text = "I am going to buy"
            self.label_img_monitor.setPixmap(QPixmap(os.path.join(path, "img/buy.png")))
        self.label_is_monitoring = QLabel(monitor_text, self)
        self.label_is_monitoring.setStyleSheet(styles.label_allegro_monitored_stat)
        self.gridLayout_description.addWidget(self.label_is_monitoring, 2, 4, 1, 1)

        self.label_img_monitor.setMaximumSize(QSize(20, 20))
        self.label_img_monitor.setStyleSheet("""QLabel{border: none;}""")
        self.label_img_monitor.setScaledContents(True)
        self.gridLayout_description.addWidget(self.label_img_monitor, 2, 3, 1, 1)





        # create spacer and delete btn
        self.spacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(self.spacer)

        self.pushButton_delete = QPushButton(self)
        # self.pushButton_delete.clicked.connect( lambda: self.deleteLater())
        self.pushButton_delete.clicked.connect(lambda: self.on_delete(link))
        icon = QIcon()
        icon.addFile(os.path.join(path, "img/delete.png"), QSize(), QIcon.Selected, QIcon.Off)
        # icon.Active.addFile(os.path.join(path, "img/icon.png"), QSize(), QIcon.Selected, QIcon.Off)
        self.pushButton_delete.setIcon(icon)
        self.pushButton_delete.setIconSize(QSize(50, 50))
        self.pushButton_delete.setStyleSheet("""QPushButton{border:none; }""")
        self.pushButton_delete.setCursor(QCursor(Qt.PointingHandCursor))
        # self.pushButton_delete.ico
        self.horizontalLayout.addWidget(self.pushButton_delete)

        self.is_on = data.get_switch_state(link)
        self.pushButton_switch = QPushButton(self)
        self.pushButton_switch.clicked.connect(lambda: self.on_switch(link))
        self.icon_on = QIcon()
        self.icon_off = QIcon()
        self.icon_on.addFile(os.path.join(path, "img/switch_on.png"), QSize(), QIcon.Selected, QIcon.On)
        self.icon_off.addFile(os.path.join(path, "img/switch_off.png"), QSize(), QIcon.Selected, QIcon.Off)
        if self.is_on:
            self.label_is_on.setText("Disable")
            self.pushButton_switch.setIcon(self.icon_on)
        else:
            self.label_is_on.setText("Enable")
            self.pushButton_switch.setIcon(self.icon_off)
        self.pushButton_switch.setIconSize(QSize(100, 40))
        self.pushButton_switch.setStyleSheet("""QPushButton{border:none; }""")
        self.pushButton_switch.setCursor(QCursor(Qt.PointingHandCursor))
        self.gridLayout_description.addWidget(self.pushButton_switch, 5, 2, 1, 1)

        self.pushButton_save_changes = QPushButton("Save", self)
        self.pushButton_save_changes.clicked.connect(lambda: self.on_save_changes(link))
        self.pushButton_save_changes.setIconSize(QSize(100, 20))
        self.pushButton_save_changes.setStyleSheet(styles.btn_dark)
        self.pushButton_save_changes.setCursor(QCursor(Qt.PointingHandCursor))
        self.gridLayout_description.addWidget(self.pushButton_save_changes, 5, 3, 1, 2)

    def on_delete(self, link):
        data.delete_monitored_element(link)
        self.deleteLater()
        self.shared_dict['isTerminatedP2'] = True

    def on_save_changes(self, link):
        data.change_price_time(link, self.lineEdit_new_price.text(), self.lineEdit_new_time.text())
        if self.lineEdit_new_price.text() != '':
            self.label_new_price.setText("Actual price: " + self.lineEdit_new_price.text())
        if self.lineEdit_new_time.text() != '':
            self.label_new_time.setText("Actual refresh time[s]: " + self.lineEdit_new_time.text() + " s")
        self.lineEdit_new_time.clear()
        self.lineEdit_new_price.clear()
        self.shared_dict['isTerminatedP2'] = True

    def on_switch(self, link):
        # m.stop_run_monitor()
        if self.is_on:
            self.label_is_on.setText("Enable")
            self.pushButton_switch.setIcon(self.icon_off)
            self.is_on = False
            data.switch_state(self.is_on, link)
        else:
            self.label_is_on.setText("Disable")
            self.pushButton_switch.setIcon(self.icon_on)
            self.is_on = True
            data.switch_state(self.is_on, link)
        self.shared_dict['isTerminatedP2'] = True
Пример #25
0
 def _add_line(self):
     line = QFrame()
     line.setFrameShape((QFrame.HLine))
     line.setFrameShadow(QFrame.Sunken)
     self.main_layout.addWidget(line)
Пример #26
0
    def __init__(self):
        super(SidePanel, self).__init__()

        # Internal variables
        self._coverdir = path.join("data", "images", "covers")
        self._id = 0
        self._imagedata = ""
        size = [220, 16]  # Width, Height (for QLineEdits/QTextEdits)

        # QDockWidget settings
        self.setAllowedAreas(Qt.RightDockWidgetArea)
        self.setFeatures(QDockWidget.DockWidgetClosable)
        self.setFixedWidth(350)
        self.setVisible(False)

        # Fonts
        bold = QFont()
        bold.setBold(True)
        boldUnderline = QFont()
        boldUnderline.setBold(True)
        boldUnderline.setUnderline(True)

        # Horizontal line
        hline = QFrame()
        hline.setFrameShape(QFrame.HLine)
        hline.setFrameShadow(QFrame.Sunken)

        """Widgets"""
        # Cover
        self.cover = QLabel()
        self.cover.setAlignment(Qt.AlignCenter)
        self.cover.setMinimumHeight(200)
        self.cover.setMaximumSize(self.width(), 250)
        # Buttons
        self.fetchInfoButton = QPushButton("Fetch missing info")
        self.fetchInfoButton.setToolTip("Try to fetch info from MobyGames")
        self.fetchInfoButton.clicked.connect(self._fetchInfo)
        self.editDetailsButton = QPushButton("Edit")
        self.editDetailsButton.setCheckable(True)
        self.editDetailsButton.clicked.connect(self._editDetails)
        self.saveDetailsButton = QPushButton("Save")
        self.saveDetailsButton.clicked.connect(self._saveInfo)
        self.fetchPriceButton = QPushButton("Update price data")
        self.fetchPriceButton.setToolTip("Try to update price data from Pricecharting")
        self.fetchPriceButton.clicked.connect(self._fetchPriceData)
        self.savePriceButton = QPushButton("Save")
        self.savePriceButton.clicked.connect(self._saveInfo)

        # Info layout widgets
        self.nameInfoLabel = QLabel("Name:")
        self.nameInfoLabel.setFont(bold)
        self.nameDataLabel = QLabel()
        self.nameDataLabel.setWordWrap(True)
        self.platformInfoLabel = QLabel("Platform:")
        self.platformInfoLabel.setFont(bold)
        self.platformDataLabel = QLabel()
        self.publisherInfoLabel = QLabel("Publisher:")
        self.publisherInfoLabel.setFont(bold)
        self.publisherDataLabel = QLabel()
        self.developerInfoLabel = QLabel("Developer:")
        self.developerInfoLabel.setFont(bold)
        self.developerDataLabel = QLabel()
        self.regionInfoLabel = QLabel("Region:")
        self.regionInfoLabel.setFont(bold)
        self.regionDataLabel = QLabel()
        self.codeInfoLabel = QLabel("Code:")
        self.codeInfoLabel.setFont(bold)
        self.codeDataLabel = QLabel()
        self.codeDataLabel.setWordWrap(True)
        self.itemInfoLabel = QLabel("Game:")
        self.itemInfoLabel.setFont(bold)
        self.itemDataLabel = QLabel()
        self.boxInfoLabel = QLabel("Box:")
        self.boxInfoLabel.setFont(bold)
        self.boxDataLabel = QLabel()
        self.manualInfoLabel = QLabel("Manual:")
        self.manualInfoLabel.setFont(bold)
        self.manualDataLabel = QLabel()
        self.genreInfoLabel = QLabel("Genre:")
        self.genreInfoLabel.setFont(bold)
        self.genreDataLabel = QLabel()
        self.yearInfoLabel = QLabel("Year:")
        self.yearInfoLabel.setFont(bold)
        self.yearDataLabel = QLabel()
        self.commentInfoLabel = QLabel("Comment:")
        self.commentInfoLabel.setFont(bold)
        self.commentDataLabel = QLabel()
        self.commentDataLabel.setWordWrap(True)
        self.platformsInfoLabel = QLabel("Available for:")
        self.platformsInfoLabel.setFont(bold)
        self.platformsDataLabel = QLabel()
        self.platformsDataLabel.setWordWrap(True)
        self.platformsDataLabel.setMaximumHeight(50)  # Can get quite large otherwise

        # Edit layout widgets
        self.nameEditLabel = QLabel("Name:")
        self.nameEditLabel.setFont(bold)
        self.nameDataTE = QTextEdit()
        self.nameDataTE.setMaximumSize(size[0], size[1] * 2)
        self.platformEditLabel = QLabel("Platform:")
        self.platformEditLabel.setFont(bold)
        self.platformDataLE = QLineEdit()
        self.platformDataLE.setMaximumSize(size[0], size[1])
        self.publisherEditLabel = QLabel("Publisher:")
        self.publisherEditLabel.setFont(bold)
        self.publisherDataLE = QLineEdit()
        self.publisherDataLE.setMaximumSize(size[0], size[1])
        self.developerEditLabel = QLabel("Developer:")
        self.developerEditLabel.setFont(bold)
        self.developerDataLE = QLineEdit()
        self.developerDataLE.setMaximumSize(size[0], size[1])
        self.regionEditLabel = QLabel("Region:")
        self.regionEditLabel.setFont(bold)
        self.regionDataCoB = QComboBox()
        self.regionDataCoB.addItems(("NTSC (JP)", "NTSC (NA)", "PAL"))
        self.regionDataCoB.setMinimumWidth(size[0])  # If not set it will be too small
        self.regionDataCoB.setMaximumSize(size[0], size[1])
        self.codeEditLabel = QLabel("Code:")
        self.codeEditLabel.setFont(bold)
        self.codeDataLE = QLineEdit()
        self.codeDataLE.setMaximumSize(size[0], size[1])
        self.itemEditLabel = QLabel("Game:")
        self.itemEditLabel.setFont(bold)
        self.itemDataCB = QCheckBox()
        self.itemDataCB.setChecked(False)
        self.boxEditLabel = QLabel("Box:")
        self.boxEditLabel.setFont(bold)
        self.boxDataCB = QCheckBox()
        self.boxDataCB.setChecked(False)
        self.manualEditLabel = QLabel("Manual:")
        self.manualEditLabel.setFont(bold)
        self.manualDataCB = QCheckBox()
        self.manualDataCB.setChecked(False)
        self.genreEditLabel = QLabel("Genre:")
        self.genreEditLabel.setFont(bold)
        self.genreDataLE = QLineEdit()
        self.genreDataLE.setMaximumSize(size[0], size[1])
        self.yearEditLabel = QLabel("Year:")
        self.yearEditLabel.setFont(bold)
        self.yearDataLE = QLineEdit()
        self.yearDataLE.setMaximumSize(size[0], size[1])
        self.commentEditLabel = QLabel("Comment:")
        self.commentEditLabel.setFont(bold)
        self.commentDataTE = QTextEdit()
        self.commentDataTE.setMaximumSize(size[0], size[1] * 2)
        self.platformsEditLabel = QLabel("Available for:")
        self.platformsEditLabel.setFont(bold)
        self.platformsDataTE = QTextEdit()
        self.platformsDataTE.setMaximumSize(size[0], size[1] * 2)

        # Price widgets
        self.paidPriceLabel = QLabel("Paid:")
        self.paidPriceLabel.setFont(bold)
        self.paidPriceDataLE = QLineEdit()
        self.paidPriceDataLE.setMaximumSize(60, size[1])
        self.paidPriceDataLE.setAlignment(Qt.AlignRight)
        self.loosePriceLabel = QLabel("Loose:")
        self.loosePriceLabel.setFont(bold)
        self.loosePriceDataLabel = QLabel()
        self.loosePriceDataLabel.setAlignment(Qt.AlignRight)
        self.cibPriceLabel = QLabel("CIB:")
        self.cibPriceLabel.setFont(bold)
        self.cibPriceDataLabel = QLabel()
        self.cibPriceDataLabel.setAlignment(Qt.AlignRight)
        self.newPriceLabel = QLabel("New:")
        self.newPriceLabel.setFont(bold)
        self.newPriceDataLabel = QLabel()
        self.newPriceDataLabel.setAlignment(Qt.AlignRight)

        """Layouts"""
        # Cover
        self.coverVbox = QVBoxLayout()
        self.coverVbox.addWidget(self.cover, 1)
        self.coverVbox.addWidget(hline, 0)

        # Buttons
        self.detailsButtonHbox = QHBoxLayout()
        self.detailsButtonHbox.addWidget(self.fetchInfoButton, 0)
        self.detailsButtonHbox.addWidget(self.editDetailsButton, 0)
        self.detailsButtonHbox.addWidget(self.saveDetailsButton, 0)
        self.priceButtonHbox = QHBoxLayout()
        self.priceButtonHbox.addWidget(self.fetchPriceButton, 0)
        self.priceButtonHbox.addWidget(self.savePriceButton, 0)

        # Info layouts
        self.nameInfoHbox = QHBoxLayout()
        self.nameInfoHbox.addWidget(self.nameInfoLabel, 0)
        self.nameInfoHbox.addWidget(self.nameDataLabel, 0)
        self.platformInfoHbox = QHBoxLayout()
        self.platformInfoHbox.addWidget(self.platformInfoLabel, 0)
        self.platformInfoHbox.addWidget(self.platformDataLabel, 0)
        self.publisherInfoHbox = QHBoxLayout()
        self.publisherInfoHbox.addWidget(self.publisherInfoLabel, 0)
        self.publisherInfoHbox.addWidget(self.publisherDataLabel, 0)
        self.developerInfoHbox = QHBoxLayout()
        self.developerInfoHbox.addWidget(self.developerInfoLabel, 0)
        self.developerInfoHbox.addWidget(self.developerDataLabel, 0)
        self.regionInfoHbox = QHBoxLayout()
        self.regionInfoHbox.addWidget(self.regionInfoLabel, 0)
        self.regionInfoHbox.addWidget(self.regionDataLabel, 0)
        self.codeInfoHbox = QHBoxLayout()
        self.codeInfoHbox.addWidget(self.codeInfoLabel, 0)
        self.codeInfoHbox.addWidget(self.codeDataLabel, 0)
        self.itemInfoHbox = QHBoxLayout()
        self.itemInfoHbox.addWidget(self.itemInfoLabel, 0)
        self.itemInfoHbox.addWidget(self.itemDataLabel, 0)
        self.boxInfoHbox = QHBoxLayout()
        self.boxInfoHbox.addWidget(self.boxInfoLabel, 0)
        self.boxInfoHbox.addWidget(self.boxDataLabel, 0)
        self.manualInfoHbox = QHBoxLayout()
        self.manualInfoHbox.addWidget(self.manualInfoLabel, 0)
        self.manualInfoHbox.addWidget(self.manualDataLabel, 0)
        self.genreInfoHbox = QHBoxLayout()
        self.genreInfoHbox.addWidget(self.genreInfoLabel, 0)
        self.genreInfoHbox.addWidget(self.genreDataLabel, 0)
        self.yearInfoHbox = QHBoxLayout()
        self.yearInfoHbox.addWidget(self.yearInfoLabel, 0)
        self.yearInfoHbox.addWidget(self.yearDataLabel, 0)
        self.commentInfoHbox = QHBoxLayout()
        self.commentInfoHbox.addWidget(self.commentInfoLabel, 0)
        self.commentInfoHbox.addWidget(self.commentDataLabel, 0)
        self.platformsInfoHbox = QHBoxLayout()
        self.platformsInfoHbox.addWidget(self.platformsInfoLabel, 0)
        self.platformsInfoHbox.addWidget(self.platformsDataLabel, 0)

        # Edit layouts
        self.nameEditHbox = QHBoxLayout()
        self.nameEditHbox.addWidget(self.nameEditLabel, 0)
        self.nameEditHbox.addWidget(self.nameDataTE, 0)
        self.platformEditHbox = QHBoxLayout()
        self.platformEditHbox.addWidget(self.platformEditLabel, 0)
        self.platformEditHbox.addWidget(self.platformDataLE, 0)
        self.publisherEditHbox = QHBoxLayout()
        self.publisherEditHbox.addWidget(self.publisherEditLabel, 0)
        self.publisherEditHbox.addWidget(self.publisherDataLE, 0)
        self.developerEditHbox = QHBoxLayout()
        self.developerEditHbox.addWidget(self.developerEditLabel, 0)
        self.developerEditHbox.addWidget(self.developerDataLE, 0)
        self.regionEditHbox = QHBoxLayout()
        self.regionEditHbox.addWidget(self.regionEditLabel, 0)
        self.regionEditHbox.addWidget(self.regionDataCoB, 0)
        self.codeEditHbox = QHBoxLayout()
        self.codeEditHbox.addWidget(self.codeEditLabel, 0)
        self.codeEditHbox.addWidget(self.codeDataLE, 0)
        self.itemEditHbox = QHBoxLayout()
        self.itemEditHbox.addWidget(self.itemEditLabel, 0)
        self.itemEditHbox.addWidget(self.itemDataCB, 0)
        self.itemEditHbox.addSpacing(135)
        self.boxEditHbox = QHBoxLayout()
        self.boxEditHbox.addWidget(self.boxEditLabel, 0)
        self.boxEditHbox.addWidget(self.boxDataCB, 0)
        self.boxEditHbox.addSpacing(135)
        self.manualEditHbox = QHBoxLayout()
        self.manualEditHbox.addWidget(self.manualEditLabel, 0)
        self.manualEditHbox.addWidget(self.manualDataCB, 0)
        self.manualEditHbox.addSpacing(135)
        self.genreEditHbox = QHBoxLayout()
        self.genreEditHbox.addWidget(self.genreEditLabel, 0)
        self.genreEditHbox.addWidget(self.genreDataLE, 0)
        self.yearEditHbox = QHBoxLayout()
        self.yearEditHbox.addWidget(self.yearEditLabel, 0)
        self.yearEditHbox.addWidget(self.yearDataLE, 0)
        self.commentEditHbox = QHBoxLayout()
        self.commentEditHbox.addWidget(self.commentEditLabel, 0)
        self.commentEditHbox.addWidget(self.commentDataTE, 0)
        self.platformsEditHbox = QHBoxLayout()
        self.platformsEditHbox.addWidget(self.platformsEditLabel, 0)
        self.platformsEditHbox.addWidget(self.platformsDataTE, 0)

        # Price layouts
        self.paidPriceHbox = QHBoxLayout()
        self.paidPriceHbox.addWidget(self.paidPriceLabel, 0)
        self.paidPriceHbox.addWidget(self.paidPriceDataLE, 0)
        self.loosePriceHbox = QHBoxLayout()
        self.loosePriceHbox.addWidget(self.loosePriceLabel, 0)
        self.loosePriceHbox.addWidget(self.loosePriceDataLabel, 0)
        self.cibPriceHbox = QHBoxLayout()
        self.cibPriceHbox.addWidget(self.cibPriceLabel, 0)
        self.cibPriceHbox.addWidget(self.cibPriceDataLabel, 0)
        self.newPriceHbox = QHBoxLayout()
        self.newPriceHbox.addWidget(self.newPriceLabel, 0)
        self.newPriceHbox.addWidget(self.newPriceDataLabel, 0)

        # Info layout
        self.infoLayout = QVBoxLayout()
        self.infoLayout.addLayout(self.nameInfoHbox, 0)
        self.infoLayout.addLayout(self.platformInfoHbox, 0)
        self.infoLayout.addLayout(self.publisherInfoHbox, 0)
        self.infoLayout.addLayout(self.developerInfoHbox, 0)
        self.infoLayout.addLayout(self.genreInfoHbox, 0)
        self.infoLayout.addLayout(self.regionInfoHbox, 0)
        self.infoLayout.addLayout(self.yearInfoHbox, 0)
        self.infoLayout.addLayout(self.codeInfoHbox, 0)
        self.infoLayout.addLayout(self.itemInfoHbox, 0)
        self.infoLayout.addLayout(self.boxInfoHbox, 0)
        self.infoLayout.addLayout(self.manualInfoHbox, 0)
        self.infoLayout.addLayout(self.commentInfoHbox, 0)
        self.infoLayout.addLayout(self.platformsInfoHbox, 0)

        # Edit layout
        self.editLayout = QVBoxLayout()
        self.editLayout.addLayout(self.nameEditHbox, 0)
        self.editLayout.addLayout(self.platformEditHbox, 0)
        self.editLayout.addLayout(self.publisherEditHbox, 0)
        self.editLayout.addLayout(self.developerEditHbox, 0)
        self.editLayout.addLayout(self.genreEditHbox, 0)
        self.editLayout.addLayout(self.regionEditHbox, 0)
        self.editLayout.addLayout(self.yearEditHbox, 0)
        self.editLayout.addLayout(self.codeEditHbox, 0)
        self.editLayout.addLayout(self.itemEditHbox, 0)
        self.editLayout.addLayout(self.boxEditHbox, 0)
        self.editLayout.addLayout(self.manualEditHbox, 0)
        self.editLayout.addLayout(self.commentEditHbox, 0)
        self.editLayout.addLayout(self.platformsEditHbox, 0)

        # Price layout
        self.priceLayout = QVBoxLayout()
        self.priceLayout.addLayout(self.paidPriceHbox, 0)
        self.priceLayout.addLayout(self.loosePriceHbox, 0)
        self.priceLayout.addLayout(self.cibPriceHbox, 0)
        self.priceLayout.addLayout(self.newPriceHbox, 0)
        self.priceLayout.addStretch(1)
        self.priceLayout.addLayout(self.priceButtonHbox, 0)

        """Main layout"""
        self.infoWidget = QWidget()
        self.infoWidget.setLayout(self.infoLayout)
        self.editWidget = QWidget()
        self.editWidget.setLayout(self.editLayout)
        # Add info and edit widgets to a stacked layout so we can switch layouts when editing
        self.stackedLayout = QStackedLayout()
        self.stackedLayout.addWidget(self.infoWidget)
        self.stackedLayout.addWidget(self.editWidget)
        self.stackedLayout.setCurrentIndex(0)  # Default to info layout

        self.detailsLayout = QVBoxLayout()
        self.detailsLayout.addLayout(self.coverVbox, 1)
        self.detailsLayout.addLayout(self.stackedLayout, 0)
        self.detailsLayout.addLayout(self.detailsButtonHbox, 0)
        self.detailsWidget = QWidget()
        self.detailsWidget.setLayout(self.detailsLayout)

        self.priceWidget = QWidget()
        self.priceWidget.setLayout(self.priceLayout)

        self.tab = QTabWidget()
        self.tab.addTab(self.detailsWidget, "Details")
        self.tab.addTab(self.priceWidget, "Price info")
        self.setWidget(self.tab)
Пример #27
0
class UiSignUp:
    def setupUi(self, widget):
        widget.resize(800, 480)

        self.frame_menu = QFrame(widget)
        self.frame_menu.setGeometry(QRect(0, 0, 800, 60))
        self.frame_menu.setStyleSheet(
            "QLabel {"
            "   color: white;"
            "   background-color: rgb(249, 138, 15);"
            "   font: 20pt 배달의민족 주아;"
            "}"
            "QPushButton {"
            "   color: white;"
            "   background-color: rgba(0, 0, 0, 0);"
            "   font: 16pt 배달의민족 주아;"
            "   border: none;"
            "   border-radius: 16px;"
            "}"
            "QPushButton:hover {"
            "   background-color: rgb(241, 219, 194);"
            "}")

        self.label_menu = QLabel(self.frame_menu)
        self.label_menu.setGeometry(QRect(0, 0, 800, 60))
        self.label_menu.setText("사용자 등록")
        self.label_menu.setAlignment(Qt.AlignCenter)

        img_home = QPixmap(str(PATH_IMG / "home.png"))
        self.button_home = QPushButton(self.frame_menu)
        self.button_home.setGeometry(QRect(10, 5, 90, 50))
        self.button_home.setIcon(QIcon(img_home))
        self.button_home.setIconSize(QSize(40, 40))
        self.button_home.setText("홈")

        self.frame_main = QFrame(widget)
        self.frame_main.setGeometry(QRect(0, 60, 800, 420))
        self.frame_main.setStyleSheet(
            "QFrame {"
            "   font: 20pt 배달의민족 주아;"
            "   background-color: white;"
            "}"
            "QLineEdit {"
            "   font: 20pt 배달의민족 주아;"
            "   border: 3px solid black;"
            "   border-radius: 10px;"
            "}"
            "QLineEdit:hover {"
            "   background-color: rgb(200, 200, 200);"
            "}"
            "QLineEdit:focus {"
            "   border-color: rgb(0, 85, 255);"
            "}")

        self.line_left = QFrame(self.frame_main)
        self.line_left.setGeometry(QRect(130, 50, 2, 80))
        self.line_left.setFrameShape(QFrame.VLine)
        self.line_left.setStyleSheet(
            "background-color: rgb(176, 176, 176); border: none;")

        self.line_right = QFrame(self.frame_main)
        self.line_right.setGeometry(QRect(670, 50, 2, 80))
        self.line_right.setFrameShape(QFrame.VLine)
        self.line_right.setStyleSheet(
            "background-color: rgb(176, 176, 176); border: none;")

        path_left = PATH_IMG / "arrow_left.png"
        path_right = PATH_IMG / "arrow_right.png"
        path_left_hover = PATH_IMG / "arrow_left_hover.png"
        path_right_hover = PATH_IMG / "arrow_right_hover.png"

        self.button_left = QPushButton(self.frame_main)
        self.button_left.setGeometry(QRect(30, 50, 80, 80))
        self.button_left.setStyleSheet("QPushButton {"
                                       f"   image: url({path_left});"
                                       "   border: none;"
                                       "}"
                                       "QPushButton:hover {"
                                       f"   image: url({path_left_hover});"
                                       "}")

        self.button_right = QPushButton(self.frame_main)
        self.button_right.setGeometry(QRect(690, 50, 80, 80))
        self.button_right.setStyleSheet("QPushButton {"
                                        f"  image: url({path_right});"
                                        "   border: none;"
                                        "}"
                                        "QPushButton:hover {"
                                        f"   image: url({path_right_hover});"
                                        "}")
Пример #28
0
class SCOUTS(QMainWindow):
    """Main Window Widget for SCOUTS."""
    style = {
        'title': 'QLabel {font-size: 18pt; font-weight: 600}',
        'header': 'QLabel {font-size: 12pt; font-weight: 520}',
        'label': 'QLabel {font-size: 10pt}',
        'button': 'QPushButton {font-size: 10pt}',
        'md button': 'QPushButton {font-size: 12pt}',
        'run button': 'QPushButton {font-size: 18pt; font-weight: 600}',
        'line edit': 'QLineEdit {font-size: 10pt}',
        'checkbox': 'QCheckBox {font-size: 10pt}',
        'radio button': 'QRadioButton {font-size: 10pt}'
    }

    def __init__(self) -> None:
        """SCOUTS Constructor. Defines all aspects of the GUI."""

        # ###
        # ### Main Window setup
        # ###

        # Inherits from QMainWindow
        super().__init__()
        self.rootdir = get_project_root()
        self.threadpool = QThreadPool()
        # Sets values for QMainWindow
        self.setWindowTitle("SCOUTS")
        self.setWindowIcon(
            QIcon(
                os.path.abspath(os.path.join(self.rootdir, 'src',
                                             'scouts.ico'))))
        # Creates StackedWidget as QMainWindow's central widget
        self.stacked_pages = QStackedWidget(self)
        self.setCentralWidget(self.stacked_pages)
        # Creates Widgets for individual "pages" and adds them to the StackedWidget
        self.main_page = QWidget()
        self.samples_page = QWidget()
        self.gating_page = QWidget()
        self.pages = (self.main_page, self.samples_page, self.gating_page)
        for page in self.pages:
            self.stacked_pages.addWidget(page)
        # ## Sets widget at program startup
        self.stacked_pages.setCurrentWidget(self.main_page)

        # ###
        # ### MAIN PAGE
        # ###

        # Main page layout
        self.main_layout = QVBoxLayout(self.main_page)

        # Title section
        # Title
        self.title = QLabel(self.main_page)
        self.title.setText('SCOUTS - Single Cell Outlier Selector')
        self.title.setStyleSheet(self.style['title'])
        self.title.adjustSize()
        self.main_layout.addWidget(self.title)

        # ## Input section
        # Input header
        self.input_header = QLabel(self.main_page)
        self.input_header.setText('Input settings')
        self.input_header.setStyleSheet(self.style['header'])
        self.main_layout.addChildWidget(self.input_header)
        self.input_header.adjustSize()
        self.main_layout.addWidget(self.input_header)
        # Input frame
        self.input_frame = QFrame(self.main_page)
        self.input_frame.setFrameShape(QFrame.StyledPanel)
        self.input_frame.setLayout(QFormLayout())
        self.main_layout.addWidget(self.input_frame)
        # Input button
        self.input_button = QPushButton(self.main_page)
        self.input_button.setStyleSheet(self.style['button'])
        self.set_icon(self.input_button, 'x-office-spreadsheet')
        self.input_button.setObjectName('input')
        self.input_button.setText(' Select input file (.xlsx or .csv)')
        self.input_button.clicked.connect(self.get_path)
        # Input path box
        self.input_path = QLineEdit(self.main_page)
        self.input_path.setObjectName('input_path')
        self.input_path.setStyleSheet(self.style['line edit'])
        # Go to sample naming page
        self.samples_button = QPushButton(self.main_page)
        self.samples_button.setStyleSheet(self.style['button'])
        self.set_icon(self.samples_button, 'preferences-other')
        self.samples_button.setText(' Name samples...')
        self.samples_button.clicked.connect(self.goto_samples_page)
        # Go to gating page
        self.gates_button = QPushButton(self.main_page)
        self.gates_button.setStyleSheet(self.style['button'])
        self.set_icon(self.gates_button, 'preferences-other')
        self.gates_button.setText(' Gating && outlier options...')
        self.gates_button.clicked.connect(self.goto_gates_page)
        # Add widgets above to input frame Layout
        self.input_frame.layout().addRow(self.input_button, self.input_path)
        self.input_frame.layout().addRow(self.samples_button)
        self.input_frame.layout().addRow(self.gates_button)

        # ## Analysis section
        # Analysis header
        self.analysis_header = QLabel(self.main_page)
        self.analysis_header.setText('Analysis settings')
        self.analysis_header.setStyleSheet(self.style['header'])
        self.analysis_header.adjustSize()
        self.main_layout.addWidget(self.analysis_header)
        # Analysis frame
        self.analysis_frame = QFrame(self.main_page)
        self.analysis_frame.setFrameShape(QFrame.StyledPanel)
        self.analysis_frame.setLayout(QVBoxLayout())
        self.main_layout.addWidget(self.analysis_frame)
        # Cutoff text
        self.cutoff_text = QLabel(self.main_page)
        self.cutoff_text.setText('Type of outlier to select:')
        self.cutoff_text.setToolTip(
            'Choose whether to select outliers using the cutoff value from a reference\n'
            'sample (OutR) or by using the cutoff value calculated for each sample\n'
            'individually (OutS)')
        self.cutoff_text.setStyleSheet(self.style['label'])
        # Cutoff button group
        self.cutoff_group = QButtonGroup(self)
        # Cutoff by sample
        self.cutoff_sample = QRadioButton(self.main_page)
        self.cutoff_sample.setText('OutS')
        self.cutoff_sample.setObjectName('sample')
        self.cutoff_sample.setStyleSheet(self.style['radio button'])
        self.cutoff_sample.setChecked(True)
        self.cutoff_group.addButton(self.cutoff_sample)
        # Cutoff by reference
        self.cutoff_reference = QRadioButton(self.main_page)
        self.cutoff_reference.setText('OutR')
        self.cutoff_reference.setObjectName('ref')
        self.cutoff_reference.setStyleSheet(self.style['radio button'])
        self.cutoff_group.addButton(self.cutoff_reference)
        # Both cutoffs
        self.cutoff_both = QRadioButton(self.main_page)
        self.cutoff_both.setText('both')
        self.cutoff_both.setObjectName('sample ref')
        self.cutoff_both.setStyleSheet(self.style['radio button'])
        self.cutoff_group.addButton(self.cutoff_both)
        # Markers text
        self.markers_text = QLabel(self.main_page)
        self.markers_text.setStyleSheet(self.style['label'])
        self.markers_text.setText('Show results for:')
        self.markers_text.setToolTip(
            'Individual markers: for each marker, select outliers\n'
            'Any marker: select cells that are outliers for AT LEAST one marker'
        )
        # Markers button group
        self.markers_group = QButtonGroup(self)
        # Single marker
        self.single_marker = QRadioButton(self.main_page)
        self.single_marker.setText('individual markers')
        self.single_marker.setObjectName('single')
        self.single_marker.setStyleSheet(self.style['radio button'])
        self.single_marker.setChecked(True)
        self.markers_group.addButton(self.single_marker)
        # Any marker
        self.any_marker = QRadioButton(self.main_page)
        self.any_marker.setText('any marker')
        self.any_marker.setObjectName('any')
        self.any_marker.setStyleSheet(self.style['radio button'])
        self.markers_group.addButton(self.any_marker)
        # Both methods
        self.both_methods = QRadioButton(self.main_page)
        self.both_methods.setText('both')
        self.both_methods.setObjectName('single any')
        self.both_methods.setStyleSheet(self.style['radio button'])
        self.markers_group.addButton(self.both_methods)
        # Tukey text
        self.tukey_text = QLabel(self.main_page)
        self.tukey_text.setStyleSheet(self.style['label'])
        # Tukey button group
        self.tukey_text.setText('Tukey factor:')
        self.tukey_group = QButtonGroup(self)
        # Low Tukey value
        self.tukey_low = QRadioButton(self.main_page)
        self.tukey_low.setText('1.5')
        self.tukey_low.setStyleSheet(self.style['radio button'])
        self.tukey_low.setChecked(True)
        self.tukey_group.addButton(self.tukey_low)
        # High Tukey value
        self.tukey_high = QRadioButton(self.main_page)
        self.tukey_high.setText('3.0')
        self.tukey_high.setStyleSheet(self.style['radio button'])
        self.tukey_group.addButton(self.tukey_high)
        # Add widgets above to analysis frame layout
        self.analysis_frame.layout().addWidget(self.cutoff_text)
        self.cutoff_buttons = QHBoxLayout()
        for button in self.cutoff_group.buttons():
            self.cutoff_buttons.addWidget(button)
        self.analysis_frame.layout().addLayout(self.cutoff_buttons)
        self.analysis_frame.layout().addWidget(self.markers_text)
        self.markers_buttons = QHBoxLayout()
        for button in self.markers_group.buttons():
            self.markers_buttons.addWidget(button)
        self.analysis_frame.layout().addLayout(self.markers_buttons)
        self.analysis_frame.layout().addWidget(self.tukey_text)
        self.tukey_buttons = QHBoxLayout()
        for button in self.tukey_group.buttons():
            self.tukey_buttons.addWidget(button)
        self.tukey_buttons.addWidget(QLabel())  # aligns row with 2 buttons
        self.analysis_frame.layout().addLayout(self.tukey_buttons)

        # ## Output section
        # Output header
        self.output_header = QLabel(self.main_page)
        self.output_header.setText('Output settings')
        self.output_header.setStyleSheet(self.style['header'])
        self.output_header.adjustSize()
        self.main_layout.addWidget(self.output_header)
        # Output frame
        self.output_frame = QFrame(self.main_page)
        self.output_frame.setFrameShape(QFrame.StyledPanel)
        self.output_frame.setLayout(QFormLayout())
        self.main_layout.addWidget(self.output_frame)
        # Output button
        self.output_button = QPushButton(self.main_page)
        self.output_button.setStyleSheet(self.style['button'])
        self.set_icon(self.output_button, 'folder')
        self.output_button.setObjectName('output')
        self.output_button.setText(' Select output folder')
        self.output_button.clicked.connect(self.get_path)
        # Output path box
        self.output_path = QLineEdit(self.main_page)
        self.output_path.setStyleSheet(self.style['line edit'])
        # Generate CSV checkbox
        self.output_csv = QCheckBox(self.main_page)
        self.output_csv.setText('Export multiple text files (.csv)')
        self.output_csv.setStyleSheet(self.style['checkbox'])
        self.output_csv.setChecked(True)
        # Generate XLSX checkbox
        self.output_excel = QCheckBox(self.main_page)
        self.output_excel.setText('Export multiple Excel spreadsheets (.xlsx)')
        self.output_excel.setStyleSheet(self.style['checkbox'])
        self.output_excel.clicked.connect(self.enable_single_excel)
        # Generate single, large XLSX checkbox
        self.single_excel = QCheckBox(self.main_page)
        self.single_excel.setText(
            'Also save one multi-sheet Excel spreadsheet')
        self.single_excel.setToolTip(
            'After generating all Excel spreadsheets, SCOUTS combines them into '
            'a single\nExcel spreadsheet where each sheet corresponds to an output'
            'file from SCOUTS')
        self.single_excel.setStyleSheet(self.style['checkbox'])
        self.single_excel.setEnabled(False)
        self.single_excel.clicked.connect(self.memory_warning)
        # Add widgets above to output frame layout
        self.output_frame.layout().addRow(self.output_button, self.output_path)
        self.output_frame.layout().addRow(self.output_csv)
        self.output_frame.layout().addRow(self.output_excel)
        self.output_frame.layout().addRow(self.single_excel)

        # ## Run & help-quit section
        # Run button (stand-alone)
        self.run_button = QPushButton(self.main_page)
        self.set_icon(self.run_button, 'system-run')
        self.run_button.setText(' Run!')
        self.run_button.setStyleSheet(self.style['run button'])
        self.main_layout.addWidget(self.run_button)
        self.run_button.clicked.connect(self.run)
        # Help-quit frame (invisible)
        self.helpquit_frame = QFrame(self.main_page)
        self.helpquit_frame.setLayout(QHBoxLayout())
        self.helpquit_frame.layout().setMargin(0)
        self.main_layout.addWidget(self.helpquit_frame)
        # Help button
        self.help_button = QPushButton(self.main_page)
        self.set_icon(self.help_button, 'help-about')
        self.help_button.setText(' Help')
        self.help_button.setStyleSheet(self.style['md button'])
        self.help_button.clicked.connect(self.get_help)
        # Quit button
        self.quit_button = QPushButton(self.main_page)
        self.set_icon(self.quit_button, 'process-stop')
        self.quit_button.setText(' Quit')
        self.quit_button.setStyleSheet(self.style['md button'])
        self.quit_button.clicked.connect(self.close)
        # Add widgets above to help-quit layout
        self.helpquit_frame.layout().addWidget(self.help_button)
        self.helpquit_frame.layout().addWidget(self.quit_button)

        # ###
        # ### SAMPLES PAGE
        # ###

        # Samples page layout
        self.samples_layout = QVBoxLayout(self.samples_page)

        # ## Title section
        # Title
        self.samples_title = QLabel(self.samples_page)
        self.samples_title.setText('Name your samples')
        self.samples_title.setStyleSheet(self.style['title'])
        self.samples_title.adjustSize()
        self.samples_layout.addWidget(self.samples_title)
        # Subtitle
        self.samples_subtitle = QLabel(self.samples_page)
        string = (
            'Please name the samples to be analysed by SCOUTS.\n\nSCOUTS searches the first '
            'column of your data\nand locates the exact string as part of the sample name.'
        )
        self.samples_subtitle.setText(string)
        self.samples_subtitle.setStyleSheet(self.style['label'])
        self.samples_subtitle.adjustSize()
        self.samples_layout.addWidget(self.samples_subtitle)

        # ## Sample addition section
        # Sample addition frame
        self.samples_frame = QFrame(self.samples_page)
        self.samples_frame.setFrameShape(QFrame.StyledPanel)
        self.samples_frame.setLayout(QGridLayout())
        self.samples_layout.addWidget(self.samples_frame)
        # Sample name box
        self.sample_name = QLineEdit(self.samples_page)
        self.sample_name.setStyleSheet(self.style['line edit'])
        self.sample_name.setPlaceholderText('Sample name ...')
        # Reference check
        self.is_reference = QCheckBox(self.samples_page)
        self.is_reference.setText('Reference?')
        self.is_reference.setStyleSheet(self.style['checkbox'])
        # Add sample to table
        self.add_sample_button = QPushButton(self.samples_page)
        QShortcut(QKeySequence("Return"), self.add_sample_button,
                  self.write_to_sample_table)
        self.set_icon(self.add_sample_button, 'list-add')
        self.add_sample_button.setText(' Add sample (Enter)')
        self.add_sample_button.setStyleSheet(self.style['button'])
        self.add_sample_button.clicked.connect(self.write_to_sample_table)
        # Remove sample from table
        self.remove_sample_button = QPushButton(self.samples_page)
        QShortcut(QKeySequence("Delete"), self.remove_sample_button,
                  self.remove_from_sample_table)
        self.set_icon(self.remove_sample_button, 'list-remove')
        self.remove_sample_button.setText(' Remove sample (Del)')
        self.remove_sample_button.setStyleSheet(self.style['button'])
        self.remove_sample_button.clicked.connect(
            self.remove_from_sample_table)
        # Add widgets above to sample addition layout
        self.samples_frame.layout().addWidget(self.sample_name, 0, 0)
        self.samples_frame.layout().addWidget(self.is_reference, 1, 0)
        self.samples_frame.layout().addWidget(self.add_sample_button, 0, 1)
        self.samples_frame.layout().addWidget(self.remove_sample_button, 1, 1)

        # ## Sample table
        self.sample_table = QTableWidget(self.samples_page)
        self.sample_table.setColumnCount(2)
        self.sample_table.setHorizontalHeaderItem(0,
                                                  QTableWidgetItem('Sample'))
        self.sample_table.setHorizontalHeaderItem(
            1, QTableWidgetItem('Reference?'))
        self.sample_table.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.Stretch)
        self.sample_table.horizontalHeader().setSectionResizeMode(
            1, QHeaderView.ResizeToContents)
        self.samples_layout.addWidget(self.sample_table)

        # ## Save & clear buttons
        # Save & clear frame (invisible)
        self.saveclear_frame = QFrame(self.samples_page)
        self.saveclear_frame.setLayout(QHBoxLayout())
        self.saveclear_frame.layout().setMargin(0)
        self.samples_layout.addWidget(self.saveclear_frame)
        # Clear samples button
        self.clear_samples = QPushButton(self.samples_page)
        self.set_icon(self.clear_samples, 'edit-delete')
        self.clear_samples.setText(' Clear table')
        self.clear_samples.setStyleSheet(self.style['md button'])
        self.clear_samples.clicked.connect(self.prompt_clear_data)
        # Save samples button
        self.save_samples = QPushButton(self.samples_page)
        self.set_icon(self.save_samples, 'document-save')
        self.save_samples.setText(' Save samples')
        self.save_samples.setStyleSheet(self.style['md button'])
        self.save_samples.clicked.connect(self.goto_main_page)
        # Add widgets above to save & clear layout
        self.saveclear_frame.layout().addWidget(self.clear_samples)
        self.saveclear_frame.layout().addWidget(self.save_samples)

        # ###
        # ### GATING PAGE
        # ###

        # Gating page layout
        self.gating_layout = QVBoxLayout(self.gating_page)

        # ## Title section
        # Title
        self.gates_title = QLabel(self.gating_page)
        self.gates_title.setText('Gating & outlier options')
        self.gates_title.setStyleSheet(self.style['title'])
        self.gates_title.adjustSize()
        self.gating_layout.addWidget(self.gates_title)

        # ## Gating options section
        # Gating header
        self.gate_header = QLabel(self.gating_page)
        self.gate_header.setText('Gating')
        self.gate_header.setStyleSheet(self.style['header'])
        self.gate_header.adjustSize()
        self.gating_layout.addWidget(self.gate_header)

        # Gating frame
        self.gate_frame = QFrame(self.gating_page)
        self.gate_frame.setFrameShape(QFrame.StyledPanel)
        self.gate_frame.setLayout(QFormLayout())
        self.gating_layout.addWidget(self.gate_frame)
        # Gating button group
        self.gating_group = QButtonGroup(self)
        # Do not gate samples
        self.no_gates = QRadioButton(self.gating_page)
        self.no_gates.setObjectName('no_gate')
        self.no_gates.setText("Don't gate samples")
        self.no_gates.setStyleSheet(self.style['radio button'])
        self.no_gates.setChecked(True)
        self.gating_group.addButton(self.no_gates)
        self.no_gates.clicked.connect(self.activate_gate)
        # CyToF gating
        self.cytof_gates = QRadioButton(self.gating_page)
        self.cytof_gates.setObjectName('cytof')
        self.cytof_gates.setText('Mass Cytometry gating')
        self.cytof_gates.setStyleSheet(self.style['radio button'])
        self.cytof_gates.setToolTip(
            'Exclude cells for which the average expression of all\n'
            'markers is below the selected value')
        self.gating_group.addButton(self.cytof_gates)
        self.cytof_gates.clicked.connect(self.activate_gate)
        # CyToF gating spinbox
        self.cytof_gates_value = QDoubleSpinBox(self.gating_page)
        self.cytof_gates_value.setMinimum(0)
        self.cytof_gates_value.setMaximum(1)
        self.cytof_gates_value.setValue(0.1)
        self.cytof_gates_value.setSingleStep(0.05)
        self.cytof_gates_value.setEnabled(False)
        # scRNA-Seq gating
        self.rnaseq_gates = QRadioButton(self.gating_page)
        self.rnaseq_gates.setText('scRNA-Seq gating')
        self.rnaseq_gates.setStyleSheet(self.style['radio button'])
        self.rnaseq_gates.setToolTip(
            'When calculating cutoff, ignore reads below the selected value')
        self.rnaseq_gates.setObjectName('rnaseq')
        self.gating_group.addButton(self.rnaseq_gates)
        self.rnaseq_gates.clicked.connect(self.activate_gate)
        # scRNA-Seq gating spinbox
        self.rnaseq_gates_value = QDoubleSpinBox(self.gating_page)
        self.rnaseq_gates_value.setMinimum(0)
        self.rnaseq_gates_value.setMaximum(10)
        self.rnaseq_gates_value.setValue(0)
        self.rnaseq_gates_value.setSingleStep(1)
        self.rnaseq_gates_value.setEnabled(False)
        # export gated population checkbox
        self.export_gated = QCheckBox(self.gating_page)
        self.export_gated.setText('Export gated cells as an output file')
        self.export_gated.setStyleSheet(self.style['checkbox'])
        self.export_gated.setEnabled(False)
        # Add widgets above to Gate frame layout
        self.gate_frame.layout().addRow(self.no_gates, QLabel())
        self.gate_frame.layout().addRow(self.cytof_gates,
                                        self.cytof_gates_value)
        self.gate_frame.layout().addRow(self.rnaseq_gates,
                                        self.rnaseq_gates_value)
        self.gate_frame.layout().addRow(self.export_gated, QLabel())

        # ## Outlier options section
        # Outlier header
        self.outlier_header = QLabel(self.gating_page)
        self.outlier_header.setText('Outliers')
        self.outlier_header.setStyleSheet(self.style['header'])
        self.outlier_header.adjustSize()
        self.gating_layout.addWidget(self.outlier_header)
        # Outlier frame
        self.outlier_frame = QFrame(self.gating_page)
        self.outlier_frame.setFrameShape(QFrame.StyledPanel)
        self.outlier_frame.setLayout(QVBoxLayout())
        self.gating_layout.addWidget(self.outlier_frame)
        # Top outliers information
        self.top_outliers = QLabel(self.gating_page)
        self.top_outliers.setStyleSheet(self.style['label'])
        self.top_outliers.setText(
            'By default, SCOUTS selects the top outliers from the population')
        self.top_outliers.setStyleSheet(self.style['label'])
        # Bottom outliers data
        self.bottom_outliers = QCheckBox(self.gating_page)
        self.bottom_outliers.setText('Include results for low outliers')
        self.bottom_outliers.setStyleSheet(self.style['checkbox'])
        # Non-outliers data
        self.not_outliers = QCheckBox(self.gating_page)
        self.not_outliers.setText('Include results for non-outliers')
        self.not_outliers.setStyleSheet(self.style['checkbox'])
        # Add widgets above to Gate frame layout
        self.outlier_frame.layout().addWidget(self.top_outliers)
        self.outlier_frame.layout().addWidget(self.bottom_outliers)
        self.outlier_frame.layout().addWidget(self.not_outliers)

        # ## Save/back button
        self.save_gates = QPushButton(self.gating_page)
        self.set_icon(self.save_gates, 'go-next')
        self.save_gates.setText(' Back to main menu')
        self.save_gates.setStyleSheet(self.style['md button'])
        self.gating_layout.addWidget(self.save_gates)
        self.save_gates.clicked.connect(self.goto_main_page)

        # ## Add empty label to take vertical space
        self.empty_label = QLabel(self.gating_page)
        self.empty_label.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)
        self.gating_layout.addWidget(self.empty_label)

    # ###
    # ### ICON SETTING
    # ###

    def set_icon(self, widget: QWidget, icon: str) -> None:
        """Associates an icon to a widget."""
        i = QIcon()
        i.addPixmap(
            QPixmap(
                os.path.abspath(
                    os.path.join(self.rootdir, 'src', 'default_icons',
                                 f'{icon}.svg'))))
        widget.setIcon(QIcon.fromTheme(icon, i))

    # ###
    # ### STACKED WIDGET PAGE SWITCHING
    # ###

    def goto_main_page(self) -> None:
        """Switches stacked widget pages to the main page."""
        self.stacked_pages.setCurrentWidget(self.main_page)

    def goto_samples_page(self) -> None:
        """Switches stacked widget pages to the samples table page."""
        self.stacked_pages.setCurrentWidget(self.samples_page)

    def goto_gates_page(self) -> None:
        """Switches stacked widget pages to the gating & other options page."""
        self.stacked_pages.setCurrentWidget(self.gating_page)

    # ###
    # ### MAIN PAGE GUI LOGIC
    # ###

    def get_path(self) -> None:
        """Opens a dialog box and sets the chosen file/folder path, depending on the caller widget."""
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        sender_name = self.sender().objectName()
        if sender_name == 'input':
            query, _ = QFileDialog.getOpenFileName(self,
                                                   "Select file",
                                                   "",
                                                   "All Files (*)",
                                                   options=options)
        elif sender_name == 'output':
            query = QFileDialog.getExistingDirectory(self,
                                                     "Select Directory",
                                                     options=options)
        else:
            return
        if query:
            getattr(self, f'{sender_name}_path').setText(query)

    def enable_single_excel(self) -> None:
        """Enables checkbox for generating a single Excel output."""
        if self.output_excel.isChecked():
            self.single_excel.setEnabled(True)
        else:
            self.single_excel.setEnabled(False)
            self.single_excel.setChecked(False)

    # ###
    # ### SAMPLE NAME/SAMPLE TABLE GUI LOGIC
    # ###

    def write_to_sample_table(self) -> None:
        """Writes data to sample table."""
        table = self.sample_table
        ref = 'no'
        sample = self.sample_name.text()
        if sample:
            for cell in range(table.rowCount()):
                item = table.item(cell, 0)
                if item.text() == sample:
                    self.same_sample()
                    return
            if self.is_reference.isChecked():
                for cell in range(table.rowCount()):
                    item = table.item(cell, 1)
                    if item.text() == 'yes':
                        self.more_than_one_reference()
                        return
                ref = 'yes'
            sample = QTableWidgetItem(sample)
            is_reference = QTableWidgetItem(ref)
            is_reference.setFlags(Qt.ItemIsEnabled)
            row_position = table.rowCount()
            table.insertRow(row_position)
            table.setItem(row_position, 0, sample)
            table.setItem(row_position, 1, is_reference)
            self.is_reference.setChecked(False)
            self.sample_name.setText('')

    def remove_from_sample_table(self) -> None:
        """Removes data from sample table."""
        table = self.sample_table
        rows = set(index.row() for index in table.selectedIndexes())
        for index in sorted(rows, reverse=True):
            self.sample_table.removeRow(index)

    def prompt_clear_data(self) -> None:
        """Prompts option to clear all data in the sample table."""
        if self.confirm_clear_data():
            table = self.sample_table
            while table.rowCount():
                self.sample_table.removeRow(0)

    # ###
    # ### GATING GUI LOGIC
    # ###

    def activate_gate(self) -> None:
        """Activates/deactivates buttons related to gating."""
        if self.sender().objectName() == 'no_gate':
            self.cytof_gates_value.setEnabled(False)
            self.rnaseq_gates_value.setEnabled(False)
            self.export_gated.setEnabled(False)
            self.export_gated.setChecked(False)
        elif self.sender().objectName() == 'cytof':
            self.cytof_gates_value.setEnabled(True)
            self.rnaseq_gates_value.setEnabled(False)
            self.export_gated.setEnabled(True)
        elif self.sender().objectName() == 'rnaseq':
            self.cytof_gates_value.setEnabled(False)
            self.rnaseq_gates_value.setEnabled(True)
            self.export_gated.setEnabled(True)

    # ###
    # ### CONNECT SCOUTS TO ANALYTICAL MODULES
    # ###

    def run(self) -> None:
        """Runs SCOUTS as a Worker, based on user input in the GUI."""
        try:
            data = self.parse_input()
        except Exception as error:
            trace = traceback.format_exc()
            self.propagate_error((error, trace))
        else:
            data['widget'] = self
            worker = Worker(func=start_scouts, **data)
            worker.signals.started.connect(self.analysis_has_started)
            worker.signals.finished.connect(self.analysis_has_finished)
            worker.signals.success.connect(self.success_message)
            worker.signals.error.connect(self.propagate_error)
            self.threadpool.start(worker)

    def parse_input(self) -> Dict:
        """Returns user input on the GUI as a dictionary."""
        # Input and output
        input_dict = {
            'input_file': str(self.input_path.text()),
            'output_folder': str(self.output_path.text())
        }
        if not input_dict['input_file'] or not input_dict['output_folder']:
            raise NoIOPathError
        # Set cutoff by reference or by sample rule
        input_dict['cutoff_rule'] = self.cutoff_group.checkedButton(
        ).objectName()  # 'sample', 'ref', 'sample ref'
        # Outliers for each individual marker or any marker in row
        input_dict['marker_rule'] = self.markers_group.checkedButton(
        ).objectName()  # 'single', 'any', 'single any'
        # Tukey factor used for calculating cutoff
        input_dict['tukey_factor'] = float(
            self.tukey_group.checkedButton().text())  # '1.5', '3.0'
        # Output settings
        input_dict['export_csv'] = True if self.output_csv.isChecked(
        ) else False
        input_dict['export_excel'] = True if self.output_excel.isChecked(
        ) else False
        input_dict['single_excel'] = True if self.single_excel.isChecked(
        ) else False
        # Retrieve samples from sample table
        input_dict['sample_list'] = []
        for tuples in self.yield_samples_from_table():
            input_dict['sample_list'].append(tuples)
        if not input_dict['sample_list']:
            raise NoSampleError
        # Set gate cutoff (if any)
        input_dict['gating'] = self.gating_group.checkedButton().objectName(
        )  # 'no_gate', 'cytof', 'rnaseq'
        input_dict['gate_cutoff_value'] = None
        if input_dict['gating'] != 'no_gate':
            input_dict['gate_cutoff_value'] = getattr(
                self, f'{input_dict["gating"]}_gates_value').value()
        input_dict['export_gated'] = True if self.export_gated.isChecked(
        ) else False
        # Generate results for non-outliers
        input_dict['non_outliers'] = False
        if self.not_outliers.isChecked():
            input_dict['non_outliers'] = True
        # Generate results for bottom outliers
        input_dict['bottom_outliers'] = False
        if self.bottom_outliers.isChecked():
            input_dict['bottom_outliers'] = True
        # return dictionary with all gathered inputs
        return input_dict

    def yield_samples_from_table(
            self) -> Generator[Tuple[str, str], None, None]:
        """Yields sample names from the sample table."""
        table = self.sample_table
        for cell in range(table.rowCount()):
            sample_name = table.item(cell, 0).text()
            sample_type = table.item(cell, 1).text()
            yield sample_name, sample_type

    # ###
    # ### MESSAGE BOXES
    # ###

    def analysis_has_started(self) -> None:
        """Disables run button while SCOUTS analysis is underway."""
        self.run_button.setText(' Working...')
        self.run_button.setEnabled(False)

    def analysis_has_finished(self) -> None:
        """Enables run button after SCOUTS analysis has finished."""
        self.run_button.setEnabled(True)
        self.run_button.setText(' Run!')

    def success_message(self) -> None:
        """Info message box used when SCOUTS finished without errors."""
        title = "Analysis finished!"
        mes = "Your analysis has finished. No errors were reported."
        if self.stacked_pages.isEnabled() is True:
            QMessageBox.information(self, title, mes)

    def memory_warning(self) -> None:
        """Warning message box used when user wants to generate a single excel file."""
        if self.sender().isChecked():
            title = 'Memory warning!'
            mes = (
                "Depending on your dataset, this option can consume a LOT of memory and take"
                " a long time to process. Please make sure that your computer can handle it!"
            )
            QMessageBox.information(self, title, mes)

    def same_sample(self) -> None:
        """Error message box used when the user tries to input the same sample twice in the sample table."""
        title = 'Error: sample name already in table'
        mes = (
            "Sorry, you can't do this because this sample name is already in the table. "
            "Please select a different name.")
        QMessageBox.critical(self, title, mes)

    def more_than_one_reference(self) -> None:
        """Error message box used when the user tries to input two reference samples in the sample table."""
        title = "Error: more than one reference selected"
        mes = (
            "Sorry, you can't do this because there is already a reference column in the table. "
            "Please remove it before adding a reference.")
        QMessageBox.critical(self, title, mes)

    def confirm_clear_data(self) -> bool:
        """Question message box used to confirm user action of clearing sample table."""
        title = 'Confirm Action'
        mes = "Table will be cleared. Are you sure?"
        reply = QMessageBox.question(self, title, mes,
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            return True
        return False

    # ###
    # ### EXCEPTIONS & ERRORS
    # ###

    def propagate_error(self, error: Tuple[Exception, str]) -> None:
        """Calls the appropriate error message box based on type of Exception raised."""
        if isinstance(error[0], NoIOPathError):
            self.no_io_path_error_message()
        elif isinstance(error[0], NoReferenceError):
            self.no_reference_error_message()
        elif isinstance(error[0], NoSampleError):
            self.no_sample_error_message()
        elif isinstance(error[0], PandasInputError):
            self.pandas_input_error_message()
        elif isinstance(error[0], SampleNamingError):
            self.sample_naming_error_message()
        else:
            self.generic_error_message(error)

    def no_io_path_error_message(self) -> None:
        """Message displayed when the user did not include an input file path, or an output folder path."""
        title = 'Error: no file/folder'
        message = ("Sorry, no input file and/or output folder was provided. "
                   "Please add the path to the necessary file/folder.")
        QMessageBox.critical(self, title, message)

    def no_reference_error_message(self) -> None:
        """Message displayed when the user wants to analyse cutoff based on a reference, but did not specify what
        sample corresponds to the reference."""
        title = "Error: No reference selected"
        message = (
            "Sorry, no reference sample was found on the sample list, but analysis was set to "
            "reference. Please add a reference sample, or change the rule for cutoff calculation."
        )
        QMessageBox.critical(self, title, message)

    def no_sample_error_message(self) -> None:
        """Message displayed when the user did not add any samples to the sample table."""
        title = "Error: No samples selected"
        message = (
            "Sorry, the analysis cannot be performed because no sample names were input. "
            "Please add your sample names.")
        QMessageBox.critical(self, title, message)

    def pandas_input_error_message(self) -> None:
        """Message displayed when the input file cannot be read (likely because it is not a Excel or csv file)."""
        title = 'Error: unexpected input file'
        message = (
            "Sorry, the input file could not be read. Please make sure that "
            "the data is save in a valid format (supported formats are: "
            ".csv, .xlsx).")
        QMessageBox.critical(self, title, message)

    def sample_naming_error_message(self) -> None:
        """Message displayed when none of the sample names passed by the user are found in the input DataFrame."""
        title = 'Error: sample names not in input file'
        message = (
            "Sorry, your sample names were not found in the input file. Please "
            "make sure that the names were typed correctly (case-sensitive).")
        QMessageBox.critical(self, title, message)

    def generic_error_message(self, error: Tuple[Exception, str]) -> None:
        """Error message box used to display any error message (including traceback) for any uncaught errors."""
        title = 'An error occurred!'
        name, trace = error
        QMessageBox.critical(self, title,
                             f"{str(name)}\n\nfull traceback:\n{trace}")

    def not_implemented_error_message(self) -> None:
        """Error message box used when the user accesses a functionality that hasn't been implemented yet."""
        title = "Not yet implemented"
        mes = "Sorry, this functionality has not been implemented yet."
        QMessageBox.critical(self, title, mes)

    # ###
    # ### HELP & QUIT
    # ###

    @staticmethod
    def get_help() -> None:
        """Opens SCOUTS documentation on the browser. Called when the user clicks the "help" button"""
        webbrowser.open('https://scouts.readthedocs.io/en/master/')

    def closeEvent(self, event: QEvent) -> None:
        """Defines the message box for when the user wants to quit SCOUTS."""
        title = 'Quit SCOUTS'
        mes = "Are you sure you want to quit?"
        reply = QMessageBox.question(self, title, mes,
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.stacked_pages.setEnabled(False)
            message = self.quit_message()
            waiter = Waiter(waiter_func=self.threadpool.activeThreadCount)
            waiter.signals.started.connect(message.show)
            waiter.signals.finished.connect(message.destroy)
            waiter.signals.finished.connect(sys.exit)
            self.threadpool.start(waiter)
        event.ignore()

    def quit_message(self) -> QDialog:
        """Displays a window while SCOUTS is exiting"""
        message = QDialog(self)
        message.setWindowTitle('Exiting SCOUTS')
        message.resize(300, 50)
        label = QLabel('SCOUTS is exiting, please wait...', message)
        label.setStyleSheet(self.style['label'])
        label.adjustSize()
        label.setAlignment(Qt.AlignCenter)
        label.move(int((message.width() - label.width()) / 2),
                   int((message.height() - label.height()) / 2))
        return message
class PropertyTreeDelegateEditor(QFrame):
    """A special editor that handles renaming blocks and groups."""
    sizeHintChanged = Signal(object)
    """Emitted when the widget changes sizeHint. Delegate should update it's geometry."""

    def __init__(self, parent=None):
        super().__init__(parent)
        layout = QVBoxLayout()
        self.setLayout(layout)            
        self.setContentsMargins(0, 0, 0, 0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        self.setAutoFillBackground(True)
        self.setFocusPolicy(Qt.StrongFocus)
        self.setFrameStyle(QFrame.Panel | QFrame.Plain)

        self._fallback_text = None
        self._experiment = None

        self.line_edit = QLineEdit()
        self.line_edit.setFrame(False)
        self.message_label = QLabel()
        self.message_label.hide()

        # Divider line
        self.divider_line = QFrame()
        self.divider_line.setFrameShape(QFrame.HLine)
        self.divider_line.setFrameShadow(QFrame.Plain)
        self.divider_line.setLineWidth(1)

        layout.addWidget(self.line_edit)
        layout.addWidget(self.divider_line)
        layout.addWidget(self.message_label)

        self.line_edit.textChanged.connect(self._updateMessage)
    
    def experiment(self):
        return self._experiment

    def setExperiment(self, ex):
        self._experiment = ex

    def fallbackText(self):
        return self._fallback_text

    def text(self):
        """Get the current text value of the editor widget.
        If editing has not been finished succesfully, returns fallbackText().
        """
        (text_ok, _) = self.experiment().checkName(self.line_edit.text())
        if text_ok:
            return self.line_edit.text()
        else:
            return self.fallbackText()
    
    def setFallbackText(self, text):
        """Set the fallback text value to be used if the editing was not succesfully finished.
        The text() method returns this value or the line_edit text.
        """
        self._fallback_text = text

    def setText(self, text):
        """Set currently editable text. Equivalent to self.line_edit.setText."""
        self.line_edit.setText(text)
    
    def _updateMessage(self):
        """Update the displayed message in response to changed text."""
        if self.line_edit.text() == self.fallbackText():
            # Perform no check
            text_ok = True
        else:
            (text_ok, reason) = self.experiment().checkName(self.line_edit.text())
        
        if text_ok:
            self.message_label.hide()
            self.divider_line.hide()
        else:
            self.message_label.setText(reason)
            self.message_label.show()
            self.divider_line.show()
        
        self.sizeHintChanged.emit(self)
    
    def focusInEvent(self, event):
        super().focusInEvent(event)
        self.line_edit.setFocus()
Пример #30
0
class Ui_FE14CharacterEditor(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.search_bar = QLineEdit()
        self.search_bar.setPlaceholderText("Search...")
        self.search_bar.setFixedWidth(225)
        self.characters_list_view = QListView()
        self.characters_list_view.setContextMenuPolicy(
            QtCore.Qt.CustomContextMenu)
        self.characters_list_view.setFixedWidth(225)
        self.characters_list_layout = QVBoxLayout()
        self.characters_list_layout.addWidget(self.search_bar)
        self.characters_list_layout.addWidget(self.characters_list_view)

        self.character_details_box = QGroupBox(title="Character Details")
        self.portrait_display = QGraphicsView()
        self.portrait_display.setFixedSize(140, 140)
        self.character_details_form_contents_1 = QWidget()
        self.character_details_form_contents_2 = QWidget()
        self.character_details_layout = QHBoxLayout()
        self.character_details_layout.addWidget(self.portrait_display)
        self.character_details_layout.addWidget(
            self.character_details_form_contents_1)
        self.character_details_layout.addWidget(
            self.character_details_form_contents_2)
        self.character_details_box.setLayout(self.character_details_layout)
        self.character_details_box.setFixedHeight(200)

        self.tab_widget = QTabWidget()
        self.ids_tab = QWidget()
        self.classes_tab = QWidget()
        self.stats_tab = QScrollArea()
        self.skills_tab = QScrollArea()
        self.misc_tab = QScrollArea()
        self.portraits_tab = PortraitViewer()

        self.stats_contents = QWidget()
        self.stats_tab.setWidget(self.stats_contents)
        self.stats_tab.setWidgetResizable(True)
        self.stats_layout = QVBoxLayout()
        self.stats_layout.setAlignment(QtCore.Qt.AlignTop)
        self.stats_contents.setLayout(self.stats_layout)

        self.skills_contents = QWidget()
        self.skills_tab.setWidget(self.skills_contents)
        self.skills_tab.setWidgetResizable(True)

        self.misc_contents = QWidget()
        self.misc_tab.setWidget(self.misc_contents)
        self.misc_tab.setWidgetResizable(True)
        self.misc_layout = QVBoxLayout()
        self.misc_layout.setAlignment(QtCore.Qt.AlignTop)
        self.misc_contents.setLayout(self.misc_layout)

        self.tab_widget.addTab(self.ids_tab, "IDs")
        self.tab_widget.addTab(self.classes_tab, "Classes")
        self.tab_widget.addTab(self.stats_tab, "Stats")
        self.tab_widget.addTab(self.skills_tab, "Skills")
        self.tab_widget.addTab(self.misc_tab, "Misc.")
        self.tab_widget.addTab(self.portraits_tab, "Portraits")

        self.editor_layout = QVBoxLayout()
        self.editor_layout.addWidget(self.character_details_box)
        self.editor_layout.addWidget(self.tab_widget)

        self.main_layout = QHBoxLayout()
        self.main_layout.addLayout(self.characters_list_layout)
        self.visual_splitter = QFrame()
        self.visual_splitter.setFrameShape(QFrame.VLine)
        self.visual_splitter.setFrameShadow(QFrame.Sunken)
        self.main_layout.addWidget(self.visual_splitter)
        self.main_layout.addLayout(self.editor_layout)

        self.tool_bar = QToolBar()
        self.action_add = QAction(text="Add")
        self.action_remove = QAction(text="Remove")
        self.action_copy_to = QAction(text="Copy To")
        self.tool_bar.addActions(
            [self.action_add, self.action_remove, self.action_copy_to])

        self.addToolBar(self.tool_bar)

        self.resize(1000, 600)
        central_widget = QWidget()
        central_widget.setLayout(self.main_layout)
        self.setWindowTitle("Character Editor")
        self.setWindowIcon(QIcon("paragon.ico"))
        self.setCentralWidget(central_widget)