示例#1
0
class PianoPanel(InstrumentPanel):
    def __init__(self):
        super().__init__(PianoInstrument())
        self.name = 'Piano'
        self.initUI()

    def initUI(self):
        self.vbox = QVBoxLayout()
        # 往上对齐
        self.vbox.setAlignment(Qt.AlignTop)
        self.fl = QHBoxLayout()
        self.fl.setAlignment(Qt.AlignTop)
        self.board = PianoBoard(self.instrument, 4)
        self.fl.addWidget(self.board)

        # 垂直布局
        # self.vbox.addLayout(self.hbox)
        self.vbox.addLayout(self.fl)
        self.vbox.addWidget(self.detail)
        self.setLayout(self.vbox)

    def initPanel(self, num, notes=None):
        self.fl.removeWidget(self.board)
        self.board.deleteLater()
        self.currentNum = num
        self.board = PianoBoard(self.instrument, self.currentNum)
        self.board.highlightNotes(notes)
        self.fl.addWidget(self.board)
示例#2
0
文件: ui.py 项目: free-free/FeelUOwn
class RightPanel(FFrame):
    def __init__(self, app, parent=None):
        super().__init__(parent)
        self._app = app

        self.widget = None

        self._layout = QHBoxLayout(self)
        self.setLayout(self._layout)
        self.setObjectName('right_panel')
        self.set_theme_style()
        self.setup_ui()

    def set_theme_style(self):
        style_str = '''
            #{0} {{
                background: transparent;
            }}
        '''.format(self.objectName())
        self.setStyleSheet(style_str)

    def set_widget(self, widget):
        if self.widget and self.widget != widget:
            self._layout.removeWidget(self.widget)
            self.widget.hide()
            widget.show()
            self._layout.addWidget(widget)
        else:
            self._layout.addWidget(widget)
        self.widget = widget

    def setup_ui(self):
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(0)
示例#3
0
文件: ui.py 项目: leohazy/FeelUOwn
class RightPanel(FFrame):
    def __init__(self, app, parent=None):
        super().__init__(parent)
        self._app = app

        self.widget = None

        self._layout = QHBoxLayout(self)
        self.setLayout(self._layout)
        self.setObjectName('right_panel')
        self.set_theme_style()
        self.setup_ui()

    def set_theme_style(self):
        style_str = '''
            #{0} {{
                background: transparent;
            }}
        '''.format(self.objectName())
        self.setStyleSheet(style_str)

    def set_widget(self, widget):
        if self.widget and self.widget != widget:
            self._layout.removeWidget(self.widget)
            self.widget.hide()
            widget.show()
            self._layout.addWidget(widget)
        else:
            self._layout.addWidget(widget)
        self.widget = widget

    def setup_ui(self):
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(0)
示例#4
0
class PlayersLayout(QWidget):
    def __init__(self, scheme: SchemePreset):
        super().__init__()
        self.scheme = scheme
        self.player_editors = []  # List[PlayerEditor]
        self._player_layout = QHBoxLayout(self)
        self.setLayout(self._player_layout)

    @property
    def players_count(self):
        return len(self.player_editors)

    def add_player(self):
        new_player_id = self.get_next_player_id()
        new_player_scheme_index = self.get_next_player_scheme_index()
        player_editor = PlayerEditor(player_id=new_player_id,
                                     initial_index=new_player_scheme_index,
                                     schemes=self.scheme)
        self.player_editors.append(player_editor)
        self._player_layout.addWidget(player_editor)

    def remove_player(self):
        item = self.player_editors.pop()
        self._player_layout.removeWidget(item)
        item.close()

    def get_next_player_id(self):
        return len(self.player_editors) + 1

    def get_next_player_scheme_index(self):
        return len(self.player_editors)

    def get_players(self):
        return [i.create_player() for i in self.player_editors]
示例#5
0
class TopBarView(QWidget):
    def __init__(self, tools):
        super().__init__()

        self.top_bars = {}
        for key in tools:
            self.top_bars[key] = tools[key].top_bar

        self.layout = QHBoxLayout()
        self.setFixedHeight(40)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.currentBar = self.top_bars['paint']
        if self.currentBar is not None:
            self.layout.addWidget(self.currentBar)

        self.setAutoFillBackground(True)
        p = self.palette()
        p.setColor(self.backgroundRole(), Qt.darkGray)
        self.setPalette(p)

        self.setStyleSheet('color: white;')

        #self.layout.addStretch()
        self.setLayout(self.layout)

    # changes the top bar to the corresponding bar (of the clicked tool)
    def changeTopBar(self, name):
        #print("cleaning the widget")
        self.layout.removeWidget(self.currentBar)
        self.currentBar.setVisible(False)
        self.currentBar = self.top_bars[name]
        self.layout.addWidget(self.currentBar)
        #self.layout.addStretch()
        self.currentBar.setVisible(True)
示例#6
0
文件: tool.py 项目: zaswed76/note_tab
class Tool(QFrame):
    def __init__(self, cfg):
        super().__init__()
        self.cfg = cfg
        self.custom_groups = {}
        self.selected_line_text = []

        self.setFixedHeight(cfg["tool_height"])
        # self.setStyleSheet("background-color: lightgrey")

        self.box = QHBoxLayout(self)

        self.word_line = LineEdit()

        # self.word_line.selectionChanged.connect(self.set_select_text)
        # self.word_line.editingFinished.connect(self.set_edit_text)

        self.search_btn = ToolBtn("search")
        self.config_btn = ToolBtn("config")

        self.box.addWidget(self.word_line)
        self.box.addWidget(self.search_btn)
        self.box.addWidget(CustomSpace(min_w=10))
        # self.add_btn("uk")
        self.box.addStretch(1)

        self.box.addWidget(self.config_btn)
        #

    def set_select_text(self):
        self.selected_line_text.append(self.word_line.selectedText())

    def set_edit_text(self):
        print(self.word_line.selectedText(), 888)

    @property
    def line_edit_text(self):
        return self.word_line.toPlainText()

    def set_line_validator(self, reg=None):
        if reg is None:
            reg = "[\d\w!]+"
        validator = QRegExpValidator(QRegExp(reg))
        self.word_line.setValidator(validator)

    def set_custom_dict(self):
        self.custom_groups["dict"] = CustomButton("ru")
        self.box.insertWidget(3, self.custom_groups["dict"])

    def del_custom_dict(self):
        try:
            self.box.removeWidget(self.custom_groups["dict"])
        except KeyError:
            pass

    def selected_text(self):
        self.word_line.setFocus()
        cursor = self.word_line.textCursor()
        textSelected = cursor.selectedText()
        return textSelected
示例#7
0
class ColorGroup(QWidget):
    def __init__(self, colors=None):
        super().__init__()
        self.widgets = []
        self.layout = None
        self.set_colors(colors)

    def set_colors(self, colors):
        if self.layout is None:
            self.layout = QHBoxLayout()
            self.setLayout(self.layout)
        else:
            while len(self.widgets):
                widget = self.widgets.pop(0)
                self.layout.removeWidget(widget)
                widget.deleteLater()
        if colors:
            for x in colors:
                if x == 'vertex':
                    widget = QLabel(x)
                else:
                    widget = ColorWidget(color=x[1], text=x[0])
                self.layout.addWidget(widget)
                self.widgets.append(widget)
            self.setLayout(self.layout)
class ShopWidget(QWidget):
    """Shop selection widget.

    A compound widget which consists of a QLabel showing the net income
    of the shop, a clickable button with its name and a QLabel with the QPixmap
    icon of the shop.
    The button is a subclass of QPushButton which has the ability to wrap text.
    """

    clicked = pyqtSignal()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._layout = QHBoxLayout(self)
        self._money_label = QLabel('0', self)
        self._money_label.setStyleSheet('QLabel {color: grey}')
        self._money_label.setMaximumWidth(self._money_label.sizeHint().width())
        self._button = QLabeledPushButton(self)
        self._button.clicked.connect(self.clicked.emit)
        self._icon = None
        self.initUi()

    def initUi(self):
        self._button.setFixedHeight(HEIGHT)
        self._money_label.setFixedHeight(HEIGHT)
        self._layout.addWidget(self._money_label)
        self._layout.addWidget(self._button)
        self._button.setSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.Fixed)

    def setText(self, text: str):
        self._button.setText(text)

    def set_money(self, money: int):
        if not isinstance(money, int):
            raise TypeError(f'Expected type: int, got: {type(money).__name__}')
        self._money_label.setText(f'{money:+}')
        self._money_label.setMaximumWidth(self._money_label.sizeHint().width())
        if money < 0:
            self._money_label.setStyleSheet('QLabel {color: red}')
        elif money > 0:
            self._money_label.setStyleSheet('QLabel {color: green}')
        else:
            self._money_label.setStyleSheet('QLabel {color: grey}')

    def set_icon(self, pixmap: QPixmap):
        icon = QLabel()
        resized_pixmap = pixmap.scaled(HEIGHT, HEIGHT, Qt.KeepAspectRatio)
        icon.setPixmap(resized_pixmap)
        if self._icon is not None:
            self._layout.removeWidget(self._icon)
        self._icon = icon
        self._layout.addWidget(self._icon)
示例#9
0
class GameView(QObject):
    unit_changed = pyqtSignal(UnitType)

    def __init__(self):
        super().__init__()
        self.game_window_ = QMainWindow()
        self.main_widget_ = QWidget()
        self.view_widget_ = QGraphicsView()
        self.british_creating_panel_ = UnitCreatingPanel(
            Game().get_british_player())
        self.french_creating_panel_ = UnitCreatingPanel(
            Game().get_french_player())
        self.current_creating_panel = self.british_creating_panel_

        self.init_window()
        self.init_main_widget()

        self.british_creating_panel_.connect_radios(self.unit_changed)
        self.french_creating_panel_.connect_radios(self.unit_changed)

    def init_window(self):
        self.game_window_.setCentralWidget(self.main_widget_)
        self.game_window_.setWindowTitle('rly stupid game')
        self.game_window_.show()

    def init_main_widget(self):
        self.main_widget_.setMinimumSize(1000, 700)
        self.main_widget_layout = QHBoxLayout()
        self.main_widget_layout.addWidget(self.british_creating_panel_)
        self.main_widget_layout.addWidget(self.view_widget_)
        self.main_widget_.setLayout(self.main_widget_layout)

    def set_scene(self, scene):
        self.view_widget_.setScene(scene)
        scene.add_map_tiles()

    def update_after_adding_unit(self):
        self.british_creating_panel_.update_after_adding_unit()
        self.french_creating_panel_.update_after_adding_unit()

    def update_after_turn_change(self):
        self.main_widget_layout.removeWidget(self.current_creating_panel)
        self.current_creating_panel.hide()
        if self.current_creating_panel is self.british_creating_panel_:
            self.current_creating_panel = self.french_creating_panel_
            self.main_widget_layout.addWidget(self.current_creating_panel)
        else:
            self.current_creating_panel = self.british_creating_panel_
            self.main_widget_layout.insertWidget(0,
                                                 self.current_creating_panel)
        self.current_creating_panel.show()
示例#10
0
class PlayerConfWidget(QWidget):
    """docstring for PlayerConfWidget"""
    def __init__(self, **args):
        super(PlayerConfWidget, self).__init__()
        # props
        # main layout
        self.mainLayout = QHBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)

        self.widgets = []
        # basic conf
        pal = QPalette(self.palette())
        pal.setColor(QPalette.Background, QColor('#DDD'))
        self.setAutoFillBackground(True)
        self.setPalette(pal)
        # init ui
        self.initUI(args)

    def initUI(self, args):
        conf = propConf['player']
        args = args['args']
        brief = conf['brief']
        print(brief)
        for key in brief.keys():
            value = brief[key]
            name = '%s : %s  '
            if 'player' in args:
                p = args['player']
                name = name % (value, str(p[key]))
            else:
                name = 'New player'
            label = QLabel(name)
            self.mainLayout.addWidget(label)
            self.widgets.append(label)

        self.mainLayout.addStretch()

        # self.saveBtn = QPushButton('Save')
        # self.saveBtn.setStyleSheet('border-radius: 0;background-color: %s' % (SAVE_BTN_COLOR))
        # self.mainLayout.addWidget(self.saveBtn)

        self.deleteBtn = QPushButton('Delete')
        self.deleteBtn.setStyleSheet(DELETE_BTN_QSS)
        self.mainLayout.addWidget(self.deleteBtn)

    def reset(self):
        for widget in self.widgets:
            self.mainLayout.removeWidget(widget)
            widget.deleteLater()
        self.widgets = []
示例#11
0
class NetworkLabel(QLabel):
    def __init__(self, parent):
        super().__init__()
        if parent:
            self.setParent(parent)
        self.setGeometry(300, 300, 900, 30)
        self.num = 0
        self.label_num = 20
        self.config = {}
        self.currentlab = ""
        self.setObjectName("main")
        self.setStyleSheet(NetworkLbel_style)
        self.main_layout = QHBoxLayout()
        self.main_layout.setContentsMargins(0, 1, 0, 1)
        self.main_layout.setSpacing(0)
        self.setLayout(self.main_layout)
        self.show()

    def addlabel(self, label: QLabel):
        self.num += 1
        label.setParent(self)
        self.currentlab = "label" + str(self.num)
        self.config[self.currentlab] = {}
        self.config[self.currentlab]["widget"] = label

    def set_first_btn(self, btn: QPushButton):
        self.config[self.currentlab]["firstbtn"] = btn

    def set_close_btn(self, btn: QPushButton):
        self.config[self.currentlab]["closebtn"] = btn
        btn.clicked.connect(self.close_btn_label_close)

    def close_btn_label_close(self):
        self.num -= 1
        self.sender().parent().close()
        for s in self.config.keys():
            if self.config[s]["closebtn"] == self.sender():
                del self.config[s]
                break
        self.add_layout()

    def add_layout(self):
        print(self.config)
        for s in self.children():
            if s.isWidgetType():
                self.main_layout.removeWidget(s)
        for d in self.config.keys():
            self.main_layout.addWidget(self.config[d]["widget"], 1)
        if self.num < self.label_num:
            self.main_layout.addWidget(QFrame(self), self.label_num - self.num)
示例#12
0
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.msh = int(input('Уровень маштабирования(от 0 до 17):'))
        self.initUI()

    def initUI(self):
        self.setGeometry(100, 100, *SCREEN_SIZE)
        self.hbox = QHBoxLayout(self)
        self.coords = [37.530887, 55.703118]
        self.setLayout(self.hbox)
        self.lbl = QLabel(self)
        self.show_image()

    def closeEvent(self, event):
        os.remove(self.map_file)

    def show_image(self):
        self.map_file = "map.png"
        response = requests.get(
            f"http://static-maps.yandex.ru/1.x/?ll={self.coords[0]},{self.coords[1]}&z={self.msh}&l=map"
        )
        with open(self.map_file, "wb") as file:
            file.write(response.content)
        if self.lbl is not None:
            self.hbox.removeWidget(self.lbl)
        pixmap = QPixmap(self.map_file)
        self.lbl.setPixmap(pixmap)
        self.hbox.addWidget(self.lbl)

    def keyReleaseEvent(self, event):
        if event.key() == Qt.Key_PageUp:
            if self.msh > 1:
                self.msh -= 1
        if event.key() == Qt.Key_PageDown:
            if self.msh < 14:
                self.msh += 1
        if event.key() == Qt.Key_Up:
            self.coords[1] += (15 - self.msh) / (5 * self.msh)
        if event.key() == Qt.Key_Down:
            self.coords[1] -= (15 - self.msh) / (5 * self.msh)
        if event.key() == Qt.Key_Left:
            self.coords[0] -= (15 - self.msh) / (5 * self.msh)
        if event.key() == Qt.Key_Right:
            self.coords[0] += (15 - self.msh) / (5 * self.msh)
        self.show_image()
示例#13
0
class SearchBox:
    searchFields = []
    program = None

    #Use this group for keyword combinations
    def __init__(self):
        self.groupBox = QGroupBox("or:")

        #One initial search field
        self.searchTerm1 = LineEditColor("Example")
        self.searchFields.append(self.searchTerm1)

        #Add it to a vbox
        self.row = QHBoxLayout()

        #Add the vbox to a container
        #self.row.addStretch(1)
        self.groupBox.setLayout(self.row)

        #Create button for creating more search fields
        self.addButton = QPushButton("+")
        self.addButton.clicked.connect(lambda: self.AddSearchField())
        self.row.addWidget(self.addButton)

        self.row.setAlignment(self.searchTerm1, Qt.AlignLeft)
        self.groupBox.setAlignment(Qt.AlignLeft)

    def AddSearchField(self):
        newST = LineEditColor("")
        self.searchFields.append(newST)

        self.addLabel = QLabel("&")

        self.addLabel.setFixedWidth(10)

        self.row.addWidget(self.addLabel, Qt.AlignLeft)
        self.row.addWidget(newST.colorPicker)
        self.row.addWidget(newST, Qt.AlignLeft)

        self.row.removeWidget(self.addButton)
        self.row.addWidget(self.addButton)

    def Get(self, title):
        self.groupBox.setTitle(title)
        return self.groupBox
示例#14
0
    def organizeWidgets(self, init, availableWidth=None):
        if not init:
            for i in reversed(range(self.cbArea.count())):
                item = self.cbArea.itemAt(i)
                if isinstance(item, QLayoutItem):
                    layout = item.layout()
                    for j in reversed(range(layout.count())):
                        widget = layout.itemAt(j).widget()
                        if widget is not None:
                            layout.removeWidget(widget)
                        else:
                            print("ERR")
                else:
                    print("Err")
                self.cbArea.removeItem(item)
                item.deleteLater()

        self.width_needed = None
        i = 0
        while i < len(self.cbList):
            line = QHBoxLayout()
            columnCount = 0
            while True:
                if availableWidth is not None and line.minimumSize().width(
                ) >= availableWidth:
                    if columnCount > 1:
                        i -= 1
                        line.removeWidget(self.cbList[i])
                    overlap = line.minimumSize().width() - availableWidth
                    if self.width_needed is None:
                        self.width_needed = overlap
                    else:
                        self.width_needed = min(self.width_needed, overlap)
                    break
                elif i >= len(self.cbList):
                    break
                else:
                    line.addWidget(self.cbList[i])
                    i += 1
                    columnCount += 1
            self.cbArea.addLayout(line)
示例#15
0
class ThumbnailRow(QWidget):

    def __init__(self):
        super().__init__()
        self.labels = []
        self.layout = QHBoxLayout()
        self.layout.setSpacing(3)
        self.layout.setContentsMargins(3, 0, 0, 3)
        self.setLayout(self.layout)
        self.items = []

    def add_items(self, items):
        self.items = items
        self.draw_items()

    def draw_items(self):
        self.clear()
        for item in self.items:
            thumbnail = Thumbnail(item)
            self.layout.addWidget(thumbnail, 0)
        self.layout.addWidget(QWidget(), 1)

    def clear(self):
        for i in reversed(range(self.layout.count())):
            widget = self.layout.itemAt(i).widget()
            # remove it from the layout list
            self.layout.removeWidget(widget)
            # remove it from the gui
            widget.setParent(None)

    def zoom(self, scale):
        for i in reversed(range(self.layout.count())):
            widget = self.layout.itemAt(i).widget()
            if isinstance(widget, Thumbnail):
                widget.zoom(scale)

    def mousePressEvent(self, a0: QtGui.QMouseEvent):
        print("Mouse Press")

    def mouseDoubleClickEvent(self, a0: QtGui.QMouseEvent):
        print("Mouse Double Click")
示例#16
0
class PlayerWidget(QWidget):
	"""docstring for PlayerWidget"""
	def __init__(self, **args):
		super(PlayerWidget, self).__init__()
		# props
		self.widgets = []
		self.mainLayout = QVBoxLayout(self)
		self.mainLayout.setContentsMargins(0, 0, 0, 0)
		self.confLayout = QHBoxLayout()
		self.confLayout.setContentsMargins(0, 0, 0, 0)
		# TODO
		# create an empty players

	def initData(self, **args):
		self.reset()
		if 'args' in args:
			args = args['args']
		if 'player' in args:
			playerWidget = PlayerConfWidget(args = args)
			self.mainLayout.addWidget(playerWidget)
			self.widgets.append(playerWidget)
			self.mainLayout.addLayout(self.confLayout)
			if 'generals' in args:
				generalWidget = ConfWidget(catagory = 'generals', args = args)
				self.confLayout.addWidget(generalWidget)
				self.widgets.append(generalWidget)
			if 'buildings' in args:
				buildingWidget = ConfWidget(catagory = 'buildings', args = args)
				self.confLayout.addWidget(buildingWidget)
				self.widgets.append(buildingWidget)
			if 'slave_buildings' in args:
				slaveBuildingsWidget = ConfWidget(catagory = 'slave_buildings', args = args)
				self.confLayout.addWidget(slaveBuildingsWidget)
				self.widgets.append(slaveBuildingsWidget)

	def reset(self):
		for widget in self.widgets:
			self.mainLayout.removeWidget(widget)
			self.confLayout.removeWidget(widget)
			widget.reset()
		self.widgets = []
示例#17
0
class ShopWidget(QWidget):
    """Shop selection widget.

    A compound widget which consists of a QLabel showing the net income
    of the shop, a clickable button with its name and a QLabel with the QPixmap
    icon of the shop.
    The button is a subclass of QPushButton which has the ability to wrap text.
    """

    clicked = pyqtSignal()

    def __init__(self, shop_id: int, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._layout = QHBoxLayout(self)
        self._button = QLabeledPushButton(self)
        self._button.clicked.connect(self.clicked.emit)
        self._icon = None
        self._id = shop_id
        self.initUi()

    def initUi(self):
        self._button.setFixedHeight(HEIGHT)
        self._layout.addWidget(self._button)
        self._button.setSizePolicy(QSizePolicy.MinimumExpanding,
                                   QSizePolicy.Fixed)

    def setText(self, text: str):
        self._button.setText(text)

    def set_icon(self, pixmap: QPixmap):
        icon = QLabel()
        resized_pixmap = pixmap.scaled(HEIGHT, HEIGHT, Qt.KeepAspectRatio)
        icon.setPixmap(resized_pixmap)
        if self._icon is not None:
            self._layout.removeWidget(self._icon)
        self._icon = icon
        self._layout.addWidget(self._icon)

    def get_shop_id(self):
        return self._id
示例#18
0
class QCustomQWidget(QWidget):
    def __init__(self, parent=None):
        super(QCustomQWidget, self).__init__(parent)
        self.textQVBoxLayout = QVBoxLayout()
        self.textUpQLabel = QLabel()
        self.textDownQLabel = QLabel()
        self.textQVBoxLayout.addWidget(self.textUpQLabel)
        self.textQVBoxLayout.addWidget(self.textDownQLabel)
        self.allQHBoxLayout = QHBoxLayout()
        self.iconQLabel = QLabel()
        self.allQHBoxLayout.addWidget(self.iconQLabel, 0)
        self.allQHBoxLayout.addLayout(self.textQVBoxLayout, 1)
        self.setLayout(self.allQHBoxLayout)
        # setStyleSheet
        self.textUpQLabel.setStyleSheet('''
            color: rgb(0, 0, 255);
        ''')
        self.textDownQLabel.setStyleSheet('''
            color: rgb(255, 0, 0);
        ''')

    def setTextUp(self, text):
        self.textUpQLabel.setText(text)

    def setTextDown(self, text):
        self.textDownQLabel.setText(text)

    def setIcon(self, imagePath):
        self.iconQLabel.setPixmap(QPixmap(imagePath))

    def cleared(self):
        item = self.allQHBoxLayout
        if item != None:
            widget = item.widget()
            if widget != None:
                self.allQHBoxLayout.removeWidget(widget)
                widget.deleteLater()
示例#19
0
文件: bar.py 项目: mehak/qutebrowser
class StatusBar(QWidget):

    """The statusbar at the bottom of the mainwindow.

    Attributes:
        txt: The Text widget in the statusbar.
        keystring: The KeyString widget in the statusbar.
        percentage: The Percentage widget in the statusbar.
        url: The UrlText widget in the statusbar.
        prog: The Progress widget in the statusbar.
        cmd: The Command widget in the statusbar.
        _hbox: The main QHBoxLayout.
        _stack: The QStackedLayout with cmd/txt widgets.
        _win_id: The window ID the statusbar is associated with.

    Signals:
        resized: Emitted when the statusbar has resized, so the completion
                 widget can adjust its size to it.
                 arg: The new size.
        moved: Emitted when the statusbar has moved, so the completion widget
               can move to the right position.
               arg: The new position.
    """

    resized = pyqtSignal('QRect')
    moved = pyqtSignal('QPoint')
    _severity = None
    _color_flags = []

    STYLESHEET = _generate_stylesheet()

    def __init__(self, *, win_id, private, parent=None):
        super().__init__(parent)
        objreg.register('statusbar', self, scope='window', window=win_id)
        self.setObjectName(self.__class__.__name__)
        self.setAttribute(Qt.WA_StyledBackground)
        config.set_register_stylesheet(self)

        self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)

        self._win_id = win_id
        self._color_flags = ColorFlags()
        self._color_flags.private = private

        self._hbox = QHBoxLayout(self)
        self._set_hbox_padding()
        self._hbox.setSpacing(5)

        self._stack = QStackedLayout()
        self._hbox.addLayout(self._stack)
        self._stack.setContentsMargins(0, 0, 0, 0)

        self.cmd = command.Command(private=private, win_id=win_id)
        self._stack.addWidget(self.cmd)
        objreg.register('status-command', self.cmd, scope='window',
                        window=win_id)

        self.txt = textwidget.Text()
        self._stack.addWidget(self.txt)

        self.cmd.show_cmd.connect(self._show_cmd_widget)
        self.cmd.hide_cmd.connect(self._hide_cmd_widget)
        self._hide_cmd_widget()

        self.url = url.UrlText()
        self.percentage = percentage.Percentage()
        self.backforward = backforward.Backforward()
        self.tabindex = tabindex.TabIndex()
        self.keystring = keystring.KeyString()
        self.prog = progress.Progress(self)
        self._draw_widgets()

        config.instance.changed.connect(self._on_config_changed)
        QTimer.singleShot(0, self.maybe_hide)

    def __repr__(self):
        return utils.get_repr(self)

    @pyqtSlot(str)
    def _on_config_changed(self, option):
        if option == 'statusbar.hide':
            self.maybe_hide()
        elif option == 'statusbar.padding':
            self._set_hbox_padding()
        elif option == 'statusbar.widgets':
            self._draw_widgets()

    def _draw_widgets(self):
        """Draw statusbar widgets."""
        # Start with widgets hidden and show them when needed
        for widget in [self.url, self.percentage,
                       self.backforward, self.tabindex,
                       self.keystring, self.prog]:
            widget.hide()
            self._hbox.removeWidget(widget)

        tab = self._current_tab()

        # Read the list and set widgets accordingly
        for segment in config.val.statusbar.widgets:
            if segment == 'url':
                self._hbox.addWidget(self.url)
                self.url.show()
            elif segment == 'scroll':
                self._hbox.addWidget(self.percentage)
                self.percentage.show()
            elif segment == 'scroll_raw':
                self._hbox.addWidget(self.percentage)
                self.percentage.raw = True
                self.percentage.show()
            elif segment == 'history':
                self._hbox.addWidget(self.backforward)
                self.backforward.enabled = True
                if tab:
                    self.backforward.on_tab_changed(tab)
            elif segment == 'tabs':
                self._hbox.addWidget(self.tabindex)
                self.tabindex.show()
            elif segment == 'keypress':
                self._hbox.addWidget(self.keystring)
                self.keystring.show()
            elif segment == 'progress':
                self._hbox.addWidget(self.prog)
                self.prog.enabled = True
                if tab:
                    self.prog.on_tab_changed(tab)

    @pyqtSlot()
    def maybe_hide(self):
        """Hide the statusbar if it's configured to do so."""
        tab = self._current_tab()
        hide = config.val.statusbar.hide
        if hide or (tab is not None and tab.data.fullscreen):
            self.hide()
        else:
            self.show()

    def _set_hbox_padding(self):
        padding = config.val.statusbar.padding
        self._hbox.setContentsMargins(padding.left, 0, padding.right, 0)

    @pyqtProperty('QStringList')
    def color_flags(self):
        """Getter for self.color_flags, so it can be used as Qt property."""
        return self._color_flags.to_stringlist()

    def _current_tab(self):
        """Get the currently displayed tab."""
        window = objreg.get('tabbed-browser', scope='window',
                            window=self._win_id)
        return window.widget.currentWidget()

    def set_mode_active(self, mode, val):
        """Setter for self.{insert,command,caret}_active.

        Re-set the stylesheet after setting the value, so everything gets
        updated by Qt properly.
        """
        if mode == usertypes.KeyMode.insert:
            log.statusbar.debug("Setting insert flag to {}".format(val))
            self._color_flags.insert = val
        if mode == usertypes.KeyMode.passthrough:
            log.statusbar.debug("Setting passthrough flag to {}".format(val))
            self._color_flags.passthrough = val
        if mode == usertypes.KeyMode.command:
            log.statusbar.debug("Setting command flag to {}".format(val))
            self._color_flags.command = val
        elif mode in [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno]:
            log.statusbar.debug("Setting prompt flag to {}".format(val))
            self._color_flags.prompt = val
        elif mode == usertypes.KeyMode.caret:
            if not val:
                # Turning on is handled in on_current_caret_selection_toggled
                log.statusbar.debug("Setting caret mode off")
                self._color_flags.caret = ColorFlags.CaretMode.off
        config.set_register_stylesheet(self, update=False)

    def _set_mode_text(self, mode):
        """Set the mode text."""
        if mode == 'passthrough':
            key_instance = config.key_instance
            all_bindings = key_instance.get_reverse_bindings_for('passthrough')
            bindings = all_bindings.get('leave-mode')
            if bindings:
                suffix = ' ({} to leave)'.format(bindings[0])
            else:
                suffix = ''
        else:
            suffix = ''
        text = "-- {} MODE --{}".format(mode.upper(), suffix)
        self.txt.set_text(self.txt.Text.normal, text)

    def _show_cmd_widget(self):
        """Show command widget instead of temporary text."""
        self._stack.setCurrentWidget(self.cmd)
        self.show()

    def _hide_cmd_widget(self):
        """Show temporary text instead of command widget."""
        log.statusbar.debug("Hiding cmd widget")
        self._stack.setCurrentWidget(self.txt)
        self.maybe_hide()

    @pyqtSlot(str)
    def set_text(self, val):
        """Set a normal (persistent) text in the status bar."""
        self.txt.set_text(self.txt.Text.normal, val)

    @pyqtSlot(usertypes.KeyMode)
    def on_mode_entered(self, mode):
        """Mark certain modes in the commandline."""
        keyparsers = objreg.get('keyparsers', scope='window',
                                window=self._win_id)
        if keyparsers[mode].passthrough:
            self._set_mode_text(mode.name)
        if mode in [usertypes.KeyMode.insert,
                    usertypes.KeyMode.command,
                    usertypes.KeyMode.caret,
                    usertypes.KeyMode.prompt,
                    usertypes.KeyMode.yesno,
                    usertypes.KeyMode.passthrough]:
            self.set_mode_active(mode, True)

    @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode)
    def on_mode_left(self, old_mode, new_mode):
        """Clear marked mode."""
        keyparsers = objreg.get('keyparsers', scope='window',
                                window=self._win_id)
        if keyparsers[old_mode].passthrough:
            if keyparsers[new_mode].passthrough:
                self._set_mode_text(new_mode.name)
            else:
                self.txt.set_text(self.txt.Text.normal, '')
        if old_mode in [usertypes.KeyMode.insert,
                        usertypes.KeyMode.command,
                        usertypes.KeyMode.caret,
                        usertypes.KeyMode.prompt,
                        usertypes.KeyMode.yesno,
                        usertypes.KeyMode.passthrough]:
            self.set_mode_active(old_mode, False)

    @pyqtSlot(browsertab.AbstractTab)
    def on_tab_changed(self, tab):
        """Notify sub-widgets when the tab has been changed."""
        self.url.on_tab_changed(tab)
        self.prog.on_tab_changed(tab)
        self.percentage.on_tab_changed(tab)
        self.backforward.on_tab_changed(tab)
        self.maybe_hide()
        assert tab.private == self._color_flags.private

    @pyqtSlot(bool)
    def on_caret_selection_toggled(self, selection):
        """Update the statusbar when entering/leaving caret selection mode."""
        log.statusbar.debug("Setting caret selection {}".format(selection))
        if selection:
            self._set_mode_text("caret selection")
            self._color_flags.caret = ColorFlags.CaretMode.selection
        else:
            self._set_mode_text("caret")
            self._color_flags.caret = ColorFlags.CaretMode.on
        config.set_register_stylesheet(self, update=False)

    def resizeEvent(self, e):
        """Extend resizeEvent of QWidget to emit a resized signal afterwards.

        Args:
            e: The QResizeEvent.
        """
        super().resizeEvent(e)
        self.resized.emit(self.geometry())

    def moveEvent(self, e):
        """Extend moveEvent of QWidget to emit a moved signal afterwards.

        Args:
            e: The QMoveEvent.
        """
        super().moveEvent(e)
        self.moved.emit(e.pos())

    def minimumSizeHint(self):
        """Set the minimum height to the text height plus some padding."""
        padding = config.val.statusbar.padding
        width = super().minimumSizeHint().width()
        height = self.fontMetrics().height() + padding.top + padding.bottom
        return QSize(width, height)
示例#20
0
class SourceWidget(QWidget):
    """
    Used to display summary information about a source in the list view.
    """
    def __init__(self, parent, source):
        """
        Set up the child widgets.
        """
        super().__init__(parent)
        self.source = source
        self.name = QLabel()
        self.updated = QLabel()

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.summary = QWidget(self)
        self.summary_layout = QHBoxLayout()
        self.summary.setLayout(self.summary_layout)

        self.attached = load_svg('paperclip.svg')
        self.attached.setMaximumSize(16, 16)

        self.summary_layout.addWidget(self.name)
        self.summary_layout.addStretch()
        self.summary_layout.addWidget(self.attached)

        layout.addWidget(self.summary)
        layout.addWidget(self.updated)

        self.delete = load_svg('cross.svg')
        self.delete.setMaximumSize(16, 16)
        self.delete.mouseReleaseEvent = self.delete_source

        self.summary_layout.addWidget(self.delete)
        self.update()

    def setup(self, controller):
        """
        Pass through the controller object to this widget.
        """
        self.controller = controller

    def display_star_icon(self):
        """
        Show the correct star icon
        """
        if getattr(self, 'starred', None):  # Delete icon if it exists.
            self.summary_layout.removeWidget(self.starred)

        if self.source.is_starred:
            self.starred = load_svg('star_on.svg')
        else:
            self.starred = load_svg('star_off.svg')

        self.summary_layout.addWidget(self.starred)
        self.starred.setMaximumSize(16, 16)
        self.starred.mousePressEvent = self.toggle_star

    def update(self):
        """
        Updates the displayed values with the current values from self.source.
        """
        self.updated.setText(arrow.get(self.source.last_updated).humanize())
        self.display_star_icon()
        self.name.setText("<strong>{}</strong>".format(
            html.escape(self.source.journalist_designation)))

        if self.source.document_count == 0:
            self.attached.hide()

    def toggle_star(self, event):
        """
        Called when the star is clicked.
        """
        self.controller.update_star(self.source)

    def delete_source(self, event):
        if self.controller.api is None:
            self.controller.on_action_requiring_login()
            return
        else:
            messagebox = DeleteSourceMessageBox(self, self.source,
                                                self.controller)
            messagebox.launch()
示例#21
0
class MessageBox(QWidget):
    def __init__(self, parent, error=None, helpword=None, index=choiceIndex):
        super().__init__()
        self.helpword = helpword
        self.layout = QHBoxLayout(self)
        self.parent = parent
        self.index = str(index)
        self.screen_geomtery = QDesktopWidget().screenGeometry(-1)
        self.width = self.screen_geomtery.width()
        self.height = self.screen_geomtery.height()
        self.path = None
        self.add_browser = None
        self.setWindowIcon(QIcon('resources/Python-logo-notext.svg_.png'))
        self.initUI()

    def initUI(self):
        self.label = QLabel()
        self.layout.addWidget(self.label)

        self.deleteButton = QPushButton("Yes")
        self.button = QPushButton("No")
        self.cancel = QPushButton("Cancel")
        self.getHelpButton = QPushButton("Yes")
        self.closeAnywayButton = QPushButton()
        self.getHelpButton.setAutoDefault(True)
        self.saveButton = QPushButton("Save")

        self.deleteButton.clicked.connect(self.delete)
        self.cancel.clicked.connect(self.dont)
        self.button.clicked.connect(self.dont)
        self.getHelpButton.clicked.connect(self.gettingHelp)

        self.saved = None
        self.center()
        self.font = QFont()
        self.font.setFamily("Iosevka")
        self.font.setPointSize(12)

        self.setFont(self.font)

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def run(self, str, fileName):
        self.fileName = fileName
        baseName = os.path.basename(self.fileName)
        self.label.setText(str + baseName + " ?")
        self.deleteButton.setAutoDefault(True)
        self.layout.addWidget(self.deleteButton)
        self.layout.addWidget(self.button)
        self.show()

    def delete(self):
        if os.path.isdir(self.fileName):  # If it is a directory
            shutil.rmtree(self.fileName)
        else:
            os.remove(self.fileName)
        self.hide()

    def dont(self):

        self.hide()

    def confirmation(self, index):

        self.label.setText \
            ("Theme " + str(index) + " selected\nNOTE: For some changes to work you need to restart PyPad")
        self.button.setText("Ok")
        self.button.setAutoDefault(True)

        self.button.setFocus()
        self.layout.addWidget(self.button)
        self.show()

    def success(self, directory):
        def _exit():
            self.hide()

        self.successButton = QPushButton("Ok")
        self.successButton.resize(10, 30)
        self.successLabel = QLabel()

        self.successLabel.setText("Successfully created a new project to: " +
                                  str(directory))
        self.successButton.clicked.connect(_exit)
        self.layout.addWidget(self.successLabel)
        self.layout.addWidget(self.successButton)

        self.show()

    def saveMaybe(self, file, tabCounter, tab, index):
        def _closeAnyway():
            try:
                file.deleteLater()
                tabCounter.pop(index)
                tab.removeTab(index)
                self.hide()
            except (IndexError, RuntimeError) as E:
                print(E, " on line 125 in the file Messagebox.py")

        def _hide():
            self.hide()

        self.label.setText("<b>Warning</b>, you have unsaved changes!")
        self.saveButton.setText("Ok")
        self.saveButton.setAutoDefault(True)

        self.closeAnywayButton.setText("Close anyway")
        self.saveButton.clicked.connect(_hide)
        self.closeAnywayButton.clicked.connect(_closeAnyway)
        self.layout.addWidget(self.saveButton)
        self.layout.addWidget(self.closeAnywayButton)
        self.show()

    def gettingHelp(self):

        self.url = "https://duckduckgo.com/?q=" + str(self.helpword)
        self.add_browser.showBrowser(
            self.url, self.helpword
        )  # self.add_browser should have the value <__main__.Main
        self.hide()

    # DONE
    def noMatch(self, word):

        self.label.setText("No matches found for word: " + str(word))
        self.button.setText("Ok")
        self.button.setAutoDefault(True)

        self.layout.addWidget(self.button)
        self.show()

    # DONE
    def newProject(self):

        cwd = os.getcwd()
        self.vertical = QVBoxLayout()

        def createFolder():
            try:
                folderName = self.textField.text()
                directory = self.ProjectDirectory.text()

                if not os.path.exists(folderName):
                    self.path = str(directory) + str(folderName)
                    os.makedirs(self.path)
                    self.hide()
                    self.success(self.path)

                else:
                    print("File already exists")

            except Exception as E:
                print(E, " on line 176 in the file Messagebox.py")

        self.setWindowTitle("New project")
        self.projectLabel = QLabel()
        self.directoryLabel = QLabel()

        self.directoryLabel.setText("Where do you want to create it?")
        self.projectLabel.setText("Enter a new project name: ")
        self.ProjectDirectory = QLineEdit()
        self.ProjectDirectory.setText(cwd)
        self.textField = QLineEdit()

        self.textFieldButton = QPushButton("Create")
        self.textFieldButton.clicked.connect(createFolder)
        self.vertical.addWidget(self.projectLabel)
        self.vertical.addWidget(self.textField)
        self.vertical.addWidget(self.directoryLabel)
        self.vertical.addWidget(self.ProjectDirectory)
        self.vertical.addWidget(self.textFieldButton)
        self.vertical.addWidget(self.cancel)
        self.layout.removeWidget(self.label)
        self.layout.addLayout(self.vertical)
        self.setLayout(self.layout)
        self.show()  #

    def getHelp(self, paren):
        self.add_browser = paren
        try:
            self.layout.removeWidget(self.deleteButton)
            self.layout.removeWidget(self.button)

        except AttributeError as E:
            print(E, " on line 208 in the file Messagebox.py")
        self.label.setText(
            "It seems like you made an error, would you like to get help?")
        self.layout.addWidget(self.getHelpButton)
        self.layout.addWidget(self.button)
        config = editor
        if config["errorMessages"] is True:
            self.show()

        else:
            self.hide()
class ESCPanel(QDialog):
    DEFAULT_INTERVAL = 0.1

    CMD_BIT_LENGTH = uavcan.get_uavcan_data_type(uavcan.equipment.esc.RawCommand().cmd).value_type.bitlen
    CMD_MAX = 2 ** (CMD_BIT_LENGTH - 1) - 1
    CMD_MIN = -(2 ** (CMD_BIT_LENGTH - 1))

    def __init__(self, parent, node):
        super(ESCPanel, self).__init__(parent)
        self.setWindowTitle('ESC Management Panel')
        self.setAttribute(Qt.WA_DeleteOnClose)              # This is required to stop background timers!

        self._node = node

        self._sliders = [PercentSlider(self) for _ in range(5)]

        self._num_sliders = QSpinBox(self)
        self._num_sliders.setMinimum(len(self._sliders))
        self._num_sliders.setMaximum(20)
        self._num_sliders.setValue(len(self._sliders))
        self._num_sliders.valueChanged.connect(self._update_number_of_sliders)

        self._bcast_interval = QDoubleSpinBox(self)
        self._bcast_interval.setMinimum(0.01)
        self._bcast_interval.setMaximum(1.0)
        self._bcast_interval.setSingleStep(0.1)
        self._bcast_interval.setValue(self.DEFAULT_INTERVAL)
        self._bcast_interval.valueChanged.connect(
            lambda: self._bcast_timer.setInterval(self._bcast_interval.value() * 1e3))

        self._stop_all = make_icon_button('hand-stop-o', 'Zero all channels', self, text='Stop All',
                                          on_clicked=self._do_stop_all)

        self._pause = make_icon_button('pause', 'Pause publishing', self, checkable=True, text='Pause')

        self._msg_viewer = QPlainTextEdit(self)
        self._msg_viewer.setReadOnly(True)
        self._msg_viewer.setLineWrapMode(QPlainTextEdit.NoWrap)
        self._msg_viewer.setFont(get_monospace_font())
        self._msg_viewer.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self._msg_viewer.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        self._bcast_timer = QTimer(self)
        self._bcast_timer.start(self.DEFAULT_INTERVAL * 1e3)
        self._bcast_timer.timeout.connect(self._do_broadcast)

        layout = QVBoxLayout(self)

        self._slider_layout = QHBoxLayout(self)
        for sl in self._sliders:
            self._slider_layout.addWidget(sl)
        layout.addLayout(self._slider_layout)

        layout.addWidget(self._stop_all)

        controls_layout = QHBoxLayout(self)
        controls_layout.addWidget(QLabel('Channels:', self))
        controls_layout.addWidget(self._num_sliders)
        controls_layout.addWidget(QLabel('Broadcast interval:', self))
        controls_layout.addWidget(self._bcast_interval)
        controls_layout.addWidget(QLabel('sec', self))
        controls_layout.addStretch()
        controls_layout.addWidget(self._pause)
        layout.addLayout(controls_layout)

        layout.addWidget(QLabel('Generated message:', self))
        layout.addWidget(self._msg_viewer)

        self.setLayout(layout)
        self.resize(self.minimumWidth(), self.minimumHeight())

    def _do_broadcast(self):
        try:
            if not self._pause.isChecked():
                msg = uavcan.equipment.esc.RPMCommand()
                for sl in self._sliders:
                    # raw_value = sl.get_value() / 100100
                    raw_value = sl.get_value()
                    # value = (-self.CMD_MIN if raw_value < 0 else self.CMD_MAX) * raw_value
                    value = (-30 if raw_value < 0 else 30) * raw_value
                    msg.rpm.append(int(value))

                self._node.broadcast(msg)
                self._msg_viewer.setPlainText(uavcan.to_yaml(msg))
            else:
                self._msg_viewer.setPlainText('Paused')
        except Exception as ex:
            self._msg_viewer.setPlainText('Publishing failed:\n' + str(ex))

    def _do_stop_all(self):
        for sl in self._sliders:
            sl.zero()

    def _update_number_of_sliders(self):
        num_sliders = self._num_sliders.value()

        while len(self._sliders) > num_sliders:
            removee = self._sliders[-1]
            self._sliders = self._sliders[:-1]
            self._slider_layout.removeWidget(removee)
            removee.close()
            removee.deleteLater()

        while len(self._sliders) < num_sliders:
            new = PercentSlider(self)
            self._slider_layout.addWidget(new)
            self._sliders.append(new)

        def deferred_resize():
            self.resize(self.minimumWidth(), self.height())

        deferred_resize()
        # noinspection PyCallByClass,PyTypeChecker
        QTimer.singleShot(200, deferred_resize)

    def __del__(self):
        global _singleton
        _singleton = None

    def closeEvent(self, event):
        global _singleton
        _singleton = None
        super(ESCPanel, self).closeEvent(event)
示例#23
0
class MyPlotWidget(QWidget):
    COLORS=('r','g','b','c','m')
    def __init__(self):
        QWidget.__init__(self)

        vBox = QVBoxLayout(self)

        self._labels = QHBoxLayout()
        #self._labels.setSpacing(0)
        self._labels.addStretch(1)
        vBox.addLayout(self._labels)

        self.pw = pg.PlotWidget()
        vBox.addWidget(self.pw)

        self.pw.setBackground('w')
        self.pw.showGrid(x=True, y=True)

        self.setAcceptDrops(True)
        self.pw.setAcceptDrops(True)

        self.cidx = 0

    def dragEnterEvent(self, e):
        if e.mimeData().hasFormat("application/x-DataItem"):
            e.accept()
        else:
            e.ignore()

    def dropEvent(self, e):
        data = e.mimeData()
        bstream = data.retrieveData("application/x-DataItem", QVariant.ByteArray)
        selected = pickle.loads(bstream)

        name = f"{e.source().filename} : {selected.var_name}"
        
        print(type(selected.data))
        item = self.pw.getPlotItem().plot(x=selected.time.to_numpy(),
                                          y=selected.data.to_numpy(),
                                          pen=pg.mkPen(color=MyPlotWidget.COLORS[self.cidx],
                                                       width=2),
                                          name=name)
        label = self.makeLabel(item)
        self._labels.insertWidget(self._labels.count()-1, label)
        e.source().onClose.connect(lambda : self.removeItem(item, label))
        
        self.pw.autoRange()
        self.cidx = (self.cidx + 1) % len(MyPlotWidget.COLORS)
        e.accept()

    def makeLabel(self, plot_item):
        label = QLabel(plot_item.name())
        label.setSizePolicy(QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed))

        palette = QPalette()
        color = plot_item.opts['pen'].color()
        palette.setColor(QPalette.WindowText, color)
        label.setPalette(palette)

        return label

    def removeItem(self, item, label):
        self.pw.removeItem(item)
        self._labels.removeWidget(label)
        # self._labels.takeAt(self._labels.indexOf(label))
        label.deleteLater()
示例#24
0
class RadioBox(QWidget):
    def __init__(self, parent=None, items=None, spread=True, **kwargs):
        # If spread is False, insert a spacer in the layout so that the items don't use all the
        # space they're given but rather align left.
        if items is None:
            items = []
        super().__init__(parent, **kwargs)
        self._buttons = []
        self._labels = items
        self._selected_index = 0
        self._spacer = horizontalSpacer() if not spread else None
        self._layout = QHBoxLayout(self)
        self._update_buttons()
    
    #--- Private
    def _update_buttons(self):
        if self._spacer is not None:
            self._layout.removeItem(self._spacer)
        to_remove = self._buttons[len(self._labels):]
        for button in to_remove:
            self._layout.removeWidget(button)
            button.setParent(None)
        del self._buttons[len(self._labels):]
        to_add = self._labels[len(self._buttons):]
        for _ in to_add:
            button = QRadioButton(self)
            self._buttons.append(button)
            self._layout.addWidget(button)
            button.toggled.connect(self.buttonToggled)
        if self._spacer is not None:
            self._layout.addItem(self._spacer)
        if not self._buttons:
            return
        for button, label in zip(self._buttons, self._labels):
            button.setText(label)
        self._update_selection()
    
    def _update_selection(self):
        self._selected_index = max(0, min(self._selected_index, len(self._buttons)-1))
        selected = self._buttons[self._selected_index]
        selected.setChecked(True)
    
    #--- Event Handlers
    def buttonToggled(self):
        for i, button in enumerate(self._buttons):
            if button.isChecked():
                self._selected_index = i
                self.itemSelected.emit(i)
                break
    
    #--- Signals
    itemSelected = pyqtSignal(int)
    
    #--- Properties
    @property
    def buttons(self):
        return self._buttons[:]
    
    @property
    def items(self):
        return self._labels[:]
    
    @items.setter
    def items(self, value):
        self._labels = value
        self._update_buttons()
    
    @property
    def selected_index(self):
        return self._selected_index
    
    @selected_index.setter
    def selected_index(self, value):
        self._selected_index = value
        self._update_selection()
示例#25
0
class WidgetView(QWidget):
    """
    Class to show a dynamically loaded widget (or dialog).
    """
    def __init__(self, uiFileName, parent=None, name=None):
        """
        Constructor
        
        @param uiFileName name of the UI file to load (string)
        @param parent parent widget (QWidget)
        @param name name of this widget (string)
        """
        super(WidgetView, self).__init__(parent)
        if name:
            self.setObjectName(name)
            self.setWindowTitle(name)
        
        self.__widget = None
        self.__uiFileName = uiFileName
        self.__layout = QHBoxLayout(self)
        self.__valid = False
        self.__timer = QTimer(self)
        self.__timer.setSingleShot(True)
        self.__timer.timeout.connect(self.buildWidget)
    
    def isValid(self):
        """
        Public method to return the validity of this widget view.
        
        @return flag indicating the validity (boolean)
        """
        return self.__valid
    
    def uiFileName(self):
        """
        Public method to retrieve the name of the UI file.
        
        @return filename of the loaded UI file (string)
        """
        return self.__uiFileName
    
    def buildWidget(self):
        """
        Public slot to load a UI file.
        """
        if self.__widget:
            self.__widget.close()
            self.__layout.removeWidget(self.__widget)
            del self.__widget
            self.__widget = None
        
        try:
            self.__widget = uic.loadUi(self.__uiFileName)
        except Exception:
            pass
        
        if not self.__widget:
            E5MessageBox.warning(
                self,
                self.tr("Load UI File"),
                self.tr(
                    """<p>The file <b>{0}</b> could not be loaded.</p>""")
                .format(self.__uiFileName))
            self.__valid = False
            return
        
        self.__widget.setParent(self)
        self.__layout.addWidget(self.__widget)
        self.__widget.show()
        self.__valid = True
        self.adjustSize()
        
        self.__timer.stop()
    
    def __rebuildWidget(self):
        """
        Private method to schedule a rebuild of the widget.
        """
        self.__timer.start(0)
示例#26
0
class ViewDataWindow(QDialog):
    formSubmitted = pyqtSignal()
    closeSignal = pyqtSignal()

    def __init__(self, LOGIN, parent=None):
        #super(ViewDataWindow, self).__init__(parent)
        super().__init__(parent)
        self.LOGIN = LOGIN
        self.db = db(self.LOGIN, "Brewing")
        self.displayNo = 0
        self.displayedBrewsH = []
        self.displayedBrewsVMash = []
        self.displayedBrewsVBoil = []
        self.displayedBrewsVFerment = []
        self.create_layout_viewData()
        self.setWindowTitle('Past Brew Viewer')
        self.activeColours = []
        self.colours = ["red", "green", "blue", "black",\
                        "cyan", "magenta", "yellow", "gray"]

    # Function to create layout of New Brew window
    def create_layout_viewData(self):

        # Create scroll boxes for filtering data
        filterGroupBox = QGroupBox("Filter by:")

        # Date edit box
        lab_date = QLabel("Date:")
        self.dateEdit = QDateEdit()
        # Set range of possible dates, current date is max date
        self.maxDate = QDate().currentDate()
        self.minDate = QDate(2019, 1, 1)
        self.dateEdit.setDate(self.maxDate)
        self.dateEdit.setDateRange(self.minDate, self.maxDate)
        self.dateEdit.setCalendarPopup(1)
        self.dateEdit.setDisplayFormat("dd/MM/yy")
        #self.dateEdit2 = QLineEdit()
        self.dateEdit.dateChanged.connect(self.filter_date)

        dateHLayout = QHBoxLayout()
        dateHLayout.addWidget(lab_date)
        dateHLayout.addWidget(self.dateEdit)

        ### Text edit filters ###
        # Batch ID search
        lab_batch = QLabel("Batch ID:")
        self.edit_batchID = QLineEdit()
        self.edit_batchID.setPlaceholderText("Enter Batch ID")
        self.but_IDsearch = QPushButton("Go")
        self.but_IDsearch.setAutoDefault(0)
        self.but_IDsearch.clicked.connect(self.filter_batchID)
        self.edit_batchID.returnPressed.connect(self.filter_batchID)
        batchHLayout = QHBoxLayout()
        batchHLayout.addWidget(lab_batch)
        batchHLayout.addWidget(self.edit_batchID)
        batchHLayout.addWidget(self.but_IDsearch)

        # Recipe search
        lab_recipe = QLabel("Recipe:")
        self.lineEdit_recipe = QLineEdit()
        self.lineEdit_recipe.setPlaceholderText("Enter Recipe")
        self.lineEdit_recipe.textChanged.connect(self.filter_recipe)
        self.lineEdit_recipe.returnPressed.connect(self.filter_recipe)
        recipeHLayout = QHBoxLayout()
        recipeHLayout.addWidget(lab_recipe)
        recipeHLayout.addWidget(self.lineEdit_recipe)

        # Clear filters button
        self.but_clearFilter = QPushButton("Clear Filters")
        self.but_clearFilter.setAutoDefault(0)
        clearHLayout = QHBoxLayout()
        clearHLayout.addStretch(1)
        clearHLayout.addWidget(self.but_clearFilter)
        clearHLayout.addStretch(0)
        self.but_clearFilter.clicked.connect(self.clearFilters)

        # Filter groupbox layout

        #recipeHLayout.addWidget(self.recipeEdit)
        #recipeVLayout = QVBoxLayout()
        #recipeVLayout.addLayout(recipeHLayout)
        #recipeVLayout.addWidget(self.lineEdit_recipe)
        filterHLayout = QHBoxLayout()
        filterHLayout.addStretch(1)
        filterHLayout.addWidget(lab_date)
        filterHLayout.addWidget(self.dateEdit)
        filterHLayout.addStretch(1)
        #filterHLayout.addLayout(recipeVLayout)
        filterHLayout.addStretch(1)
        filterHLayout.addWidget(self.edit_batchID)
        filterHLayout.addWidget(self.but_IDsearch)
        filterHLayout.addStretch(1)
        #filterGroupBox.setLayout(filterHLayout)

        # Alternate - Filter vertical layout
        filterVLayout = QVBoxLayout()
        filterVLayout.addLayout(batchHLayout)
        filterVLayout.addLayout(recipeHLayout)
        filterVLayout.addLayout(dateHLayout)
        filterVLayout.addLayout(clearHLayout)
        filterGroupBox.setLayout(filterVLayout)

        # scrollHLayout = QHBoxLayout()
        # scrollHLayout.addWidget(filterGroupBox)
        # scrollHLayout.addStretch(1)

        # Create QTableView of brew data
        header = ['Brew ID', 'Recipe', 'Date']
        self.model = MyTableModel(
            self.db.readFromTable("Brews", "id, Recipe, Date"), header, self)
        self.proxyModel = QSortFilterProxyModel(self)
        self.proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxyModel.setSourceModel(self.model)
        self.dataTable = QTableView()
        self.dataTable.setModel(self.proxyModel)
        self.dataTable.setSortingEnabled(True)
        self.dataTable.setSelectionBehavior(1)

        # Create bottom buttons
        self.but_quit = QPushButton("Close")
        self.but_quit.setAutoDefault(0)
        self.but_view = QPushButton("Display Brew")
        self.but_view.setAutoDefault(0)
        quitHLayout = QHBoxLayout()
        quitHLayout.addStretch(0)
        quitHLayout.addWidget(self.but_quit)
        quitHLayout.addStretch(3)
        quitHLayout.addWidget(self.but_view)
        quitHLayout.addStretch(0)

        # Main vertical layout for left area
        lWidget = QWidget()
        vLayoutL = QVBoxLayout(lWidget)
        vLayoutL.addWidget(filterGroupBox)
        vLayoutL.addWidget(self.dataTable)
        vLayoutL.addLayout(quitHLayout)

        # Widget for displayed brews - Widget allows fixed height to be set
        displayedWidget = QWidget()
        #displayedWidget.setFixedHeight(180)
        # h Layout to add groupboxes of displayed brews - added to in viewButtonClicked slot
        self.hLayoutDisplayed = QHBoxLayout()
        self.hLayoutDisplayed.addStretch(1)
        self.hLayoutDisplayed.setSizeConstraint(5)
        displayedWidget.setLayout(self.hLayoutDisplayed)
        # Scroll area for horizontal displayed brews
        hScrollArea = QScrollArea()
        hScrollArea.setWidget(displayedWidget)
        hScrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        hScrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        #hScrollArea.setFixedHeight(120)
        hScrollArea.setMinimumHeight(20)
        # Main v layout for displayed brews widget
        displayTitle = QLabel("Displayed Brews:")
        displayTitle.setMaximumHeight(20)
        hDisplayedWidget = QWidget()
        self.vLayoutDisplayed = QVBoxLayout(hDisplayedWidget)
        self.vLayoutDisplayed.addWidget(displayTitle)
        self.vLayoutDisplayed.addWidget(hScrollArea)

        # Main vertical layout for right area
        rWidget = QWidget()
        rSplitter = QSplitter()
        rSplitter.setOrientation(Qt.Orientation(2))
        #vLayoutR = QVBoxLayout(rWidget)
        self.tabs = QTabWidget()
        self.tabMash = MashTab()
        self.tabBoil = BoilTab()
        self.tabFerment = FermentTab()
        self.tabs.resize(100, 1000)
        self.tabs.setMinimumSize(400, 100)
        self.tabs.addTab(self.tabMash, "Mash")
        self.tabs.addTab(self.tabBoil, "Boil")
        self.tabs.addTab(self.tabFerment, "Ferment")
        #vLayoutR.addLayout(self.vLayoutDisplayed)
        #vLayoutR.addWidget(self.tabs)
        rSplitter.addWidget(hDisplayedWidget)
        rSplitter.addWidget(self.tabs)

        # Main layout for whole window - splitter so widget sizes are adjustable
        mainLayout = QHBoxLayout()
        mainSplitter = QSplitter()
        mainSplitter.addWidget(lWidget)
        mainSplitter.addWidget(rSplitter)
        mainLayout.addWidget(mainSplitter)
        mainSplitter.setSizes([260, 740])

        self.setLayout(mainLayout)
        #self.showFullScreen()
        self.setGeometry(0, 0, 1500, 1000)

        self.but_view.clicked.connect(self.viewButtonClicked)
        self.but_view.clicked.connect(self.viewButtonClickedTabs)
        self.but_quit.clicked.connect(self.quitButtonClicked)

    def quitButtonClicked(self):

        self.close()
        self.closeSignal.emit()

    # Slot for adding selected brew to widget
    def viewButtonClicked(self):

        self.brewInfo = []  # array to place brew info: ID, Recipe, Date
        self.displayNo = self.displayNo + 1
        # Add brew info to array based on selected row
        index = (self.dataTable.selectionModel().currentIndex())
        for i in range(3):
            self.brewInfo.append(
                QLabel(str(index.sibling(index.row(), i).data())))

        # Choose colour to use for this displayed brew
        self.colourToUse = self.chooseColour()

        # Create group box with all brew info displayed and Remove button
        brewGroupBox = QGroupBox(str(self.displayNo))
        brewGroupBox.setObjectName("ColouredGroupBox")
        brewGroupBox.setStyleSheet(
            "QGroupBox#ColouredGroupBox { border: 2px solid %s;}" %
            self.colourToUse)
        brewForm = QFormLayout()
        brewForm.addRow(QLabel('Brew ID:'), self.brewInfo[0])
        brewForm.addRow(QLabel('Recipe:'), self.brewInfo[1])
        brewForm.addRow(QLabel('Date:'), self.brewInfo[2])
        removeButHLayout = QHBoxLayout()
        removeButHLayout.addStretch(1)
        self.but_Remove = QPushButton("Remove")
        removeButHLayout.addWidget(self.but_Remove)
        brewForm.addRow(removeButHLayout)
        brewGroupBox.setLayout(brewForm)
        # Add group box to layout - use insert so that stretch stays on right side
        self.hLayoutDisplayed.insertWidget(self.displayNo - 1, brewGroupBox)
        self.displayedBrewsH.append(
            brewGroupBox)  # Add groupbox to array of displayed brews
        # Signal to connect remove brew button. Lambda function used to pass argument of specific
        # brew to be removed
        self.but_Remove.clicked.connect(
            lambda: self.removeBrewClickedMash(brewGroupBox))
        self.but_Remove.clicked.connect(
            lambda: self.removeBrewClickedBoil(brewGroupBox))
        self.but_Remove.clicked.connect(
            lambda: self.removeBrewClickedFerment(brewGroupBox))
        self.but_Remove.clicked.connect(
            lambda: self.removeBrewClicked(brewGroupBox))

    # Slot for adding brew info to each of the process tabs
    def viewButtonClickedTabs(self):

        batchID = self.brewInfo[0].text()
        # Query database to get recipe data for the brew selected to view
        # brewInfo[0].text() gives brew ID for selected brew from table
        sql = f"SELECT * FROM Brews WHERE id = '{self.brewInfo[0].text()}'"
        query = self.db.custom(sql)

        self.recipedata = {}
        self.recipedata['batchID'] = query[0][0]
        self.recipedata['recipeName'] = query[0][1]
        self.recipedata['recipeDate'] = query[0][2]
        self.recipedata['mashTemp'] = query[0][3]
        self.recipedata['mashTime'] = query[0][4]
        self.recipedata['boilTemp'] = query[0][5]
        self.recipedata['boilTime'] = query[0][6]
        self.recipedata['hop1'] = (query[0][7], query[0][8])
        self.recipedata['hop2'] = (query[0][9], query[0][10])
        self.recipedata['hop3'] = (query[0][11], query[0][12])
        self.recipedata['hop4'] = (query[0][13], query[0][14])
        self.recipedata['fermenttemp'] = query[0][15]

        # Create groupboxes for each of the process tabs to fill with brew info
        mashGroupBox = QGroupBox(str(self.displayNo))
        mashGroupBox.setObjectName("MashColouredGroupBox")
        mashGroupBox.setStyleSheet(
            "QGroupBox#MashColouredGroupBox { border: 2px solid %s;}" %
            self.colourToUse)
        mashFormLayout = QFormLayout()
        mashFormLayout.addRow(
            QLabel(f"Temp ({DEGREES}C): {self.recipedata['mashTemp']}"))
        mashFormLayout.addRow(
            QLabel(f"Time (mins): {self.recipedata['mashTime']}"))
        mashGroupBox.setLayout(mashFormLayout)
        self.tabMash.mashVLayout.insertWidget(self.displayNo - 1, mashGroupBox)
        self.displayedBrewsVMash.append(mashGroupBox)

        boilGroupBox = QGroupBox(str(self.displayNo))
        boilGroupBox.setObjectName("BoilColouredGroupBox")
        boilGroupBox.setStyleSheet(
            "QGroupBox#BoilColouredGroupBox { border: 2px solid %s;}" %
            self.colourToUse)
        boilFormLayout = QFormLayout()
        boilFormLayout.addRow(
            QLabel(f"Temp ({DEGREES}C):{self.recipedata['boilTemp']}"))
        boilFormLayout.addRow(
            QLabel(f"Time (mins): {self.recipedata['boilTime']}"))
        boilFormLayout.addRow(QLabel(f"Hop 1: {self.recipedata['hop1'][0]}"))
        boilFormLayout.addRow(
            QLabel(f"Time (mins): {self.recipedata['hop1'][1]}"))
        boilFormLayout.addRow(QLabel(f"Hop 2: {self.recipedata['hop2'][0]}"))
        boilFormLayout.addRow(
            QLabel(f"Time (mins): {self.recipedata['hop2'][1]}"))
        boilFormLayout.addRow(QLabel(f"Hop 3: {self.recipedata['hop3'][0]}"))
        boilFormLayout.addRow(
            QLabel(f"Time (mins): {self.recipedata['hop3'][1]}"))
        boilFormLayout.addRow(QLabel(f"Hop 4: {self.recipedata['hop4'][0]}"))
        boilFormLayout.addRow(
            QLabel(f"Time (mins): {self.recipedata['hop4'][1]}"))
        boilGroupBox.setLayout(boilFormLayout)
        self.tabBoil.boilVLayout.insertWidget(self.displayNo - 1, boilGroupBox)
        self.displayedBrewsVBoil.append(boilGroupBox)

        fermentGroupBox = QGroupBox(str(self.displayNo))
        fermentGroupBox.setObjectName("FermentColouredGroupBox")
        fermentGroupBox.setStyleSheet(
            "QGroupBox#FermentColouredGroupBox { border: 2px solid %s;}" %
            self.colourToUse)
        fermentFormLayout = QFormLayout()
        fermentFormLayout.addRow(
            QLabel(f"Temp ({DEGREES}C): {self.recipedata['fermenttemp']}"))
        #fermentFormLayout.addRow(QLabel('Time (mins):'))
        fermentGroupBox.setLayout(fermentFormLayout)
        self.tabFerment.fermentVLayout.insertWidget(self.displayNo - 1,
                                                    fermentGroupBox)
        self.displayedBrewsVFerment.append(fermentGroupBox)

        ### PUTTING DATA ONTO GRAPHS ###
        # Query database to get data to plot on graphs
        sqlMash = f"SELECT TimeStamp, Temp FROM Mash WHERE BatchID = '{batchID}'"
        sqlBoil = f"SELECT TimeStamp, Temp FROM BoilMonitor WHERE BatchID = '{batchID}'"
        sqlFermentTemp = f"SELECT TimeStamp, Temp FROM Ferment WHERE BatchID = '{batchID}'"
        sqlFermentSG = f"SELECT TimeStamp, Sg FROM Ferment WHERE BatchID = '{batchID}'"
        mashDataX, mashDataY = self.createData(sqlMash)
        boilDataX, boilDataY = self.createData(sqlBoil)
        fermentTempDataX, fermentTempDataY = self.createData(sqlFermentTemp)
        fermentSGDataX, fermentSGDataY = self.createData(sqlFermentSG)

        # Create and add curves to each of the plots
        self.tabMash.graph.createCurve(mashDataX, mashDataY, self.colourToUse)
        self.tabBoil.graph.createCurve(boilDataX, boilDataY, self.colourToUse)
        self.tabFerment.tempGraph.createCurve(fermentTempDataX[1:],
                                              fermentTempDataY[1:],
                                              self.colourToUse)
        self.tabFerment.gravGraph.createCurve(fermentSGDataX[1:],
                                              fermentSGDataY[1:],
                                              self.colourToUse)

    # Function to choose first available colour
    def chooseColour(self):

        # Loop through dictionary, checking if self.colours[j] appear
        for colours in self.colours:
            # If it does appear, continue to next colour
            if colours not in self.activeColours:
                # If it doesn't appear, add colour to dictionary and return colour
                self.activeColours.append(colours)
                return colours

    # Get data from database using sql query
    def createData(self, sql):
        timestamps = []
        tempdat = []
        try:
            for data in self.db.custom(sql):
                timestamps.append(data[0])
                tempdat.append(data[1])

            startTime = timestamps[0]
            for i in range(len(timestamps)):
                timestamps[i] = (timestamps[i] - startTime).seconds
        except IndexError:
            return [0], [0]

        return timestamps, tempdat

    # Slot for removing group boxes from horizontal tab
    def removeBrewClicked(self, brewToRemove):

        brewArrayPos = self.displayedBrewsH.index(brewToRemove)

        self.hLayoutDisplayed.removeWidget(
            brewToRemove)  # remove widget from layout
        brewToRemove.setParent(None)  # remove parent so widget dissappears
        self.displayNo = self.displayNo - 1
        self.displayedBrewsH.remove(
            brewToRemove)  # remove brew from array of displayed brews
        i = 0
        # Loop to renumber the remaining displayed groupboxes using the array
        for i in range(len(self.displayedBrewsH)):
            self.displayedBrewsH[i].setTitle(str(i + 1))

        del self.activeColours[brewArrayPos]

    # Slot for removing group boxes of brew info in mash tab
    def removeBrewClickedMash(self, brewToRemove):

        # Obtain position in array of displayed brews of brew to remove
        brewArrayPos = self.displayedBrewsH.index(brewToRemove)
        # Use position to remove widget from layout
        self.tabMash.mashVLayout.takeAt(brewArrayPos)
        # Use position to remove parent
        self.displayedBrewsVMash[brewArrayPos].setParent(None)
        # Use position to delete from vertical array
        del self.displayedBrewsVMash[brewArrayPos]
        # Renumber groupboxes in vertical display
        for i in range(len(self.displayedBrewsVMash)):
            self.displayedBrewsVMash[i].setTitle(str(i + 1))

        # Remove curve from graph
        self.tabMash.graph.removeCurve(brewArrayPos)

    # Slot for removing group boxes of brew info in boil tab
    def removeBrewClickedBoil(self, brewToRemove):

        # Obtain position in array of displayed brews of brew to remove
        brewArrayPos = self.displayedBrewsH.index(brewToRemove)
        # Use position to remove widget from layout
        self.tabBoil.boilVLayout.takeAt(brewArrayPos)
        # Use position to remove parent
        self.displayedBrewsVBoil[brewArrayPos].setParent(None)
        # Use position to delete from vertical array
        del self.displayedBrewsVBoil[brewArrayPos]
        # Renumber groupboxes in vertical display
        for i in range(len(self.displayedBrewsVBoil)):
            self.displayedBrewsVBoil[i].setTitle(str(i + 1))

        self.tabBoil.graph.removeCurve(brewArrayPos)

    # Slot for removing group boxes of brew info in ferment tab
    def removeBrewClickedFerment(self, brewToRemove):

        # Obtain position in array of displayed brews of brew to remove
        brewArrayPos = self.displayedBrewsH.index(brewToRemove)
        # Use position to remove widget from layout
        self.tabFerment.fermentVLayout.takeAt(brewArrayPos)
        # Use position to remove parent
        self.displayedBrewsVFerment[brewArrayPos].setParent(None)
        # Use position to delete from vertical array
        del self.displayedBrewsVFerment[brewArrayPos]
        # Renumber groupboxes in vertical display
        for i in range(len(self.displayedBrewsVFerment)):
            self.displayedBrewsVFerment[i].setTitle(str(i + 1))

        self.tabFerment.tempGraph.removeCurve(brewArrayPos)
        self.tabFerment.gravGraph.removeCurve(brewArrayPos)

    # Slot for filtering by Batch IDdisplayed
    def filter_batchID(self):
        self.lineEdit_recipe.clear()
        self.proxyModel.setFilterRegExp(self.edit_batchID.text())
        self.proxyModel.setFilterKeyColumn(0)

    # Slot for filtering by Recipe
    def filter_recipe(self):
        self.edit_batchID.clear()
        self.proxyModel.setFilterRegExp(self.lineEdit_recipe.text())
        self.proxyModel.setFilterKeyColumn(1)

    # Slot for filtering by date
    def filter_date(self):
        self.lineEdit_recipe.clear()
        self.edit_batchID.clear()
        self.proxyModel.setFilterRegExp(
            self.dateEdit.date().toString("dd/MM/yy"))
        self.proxyModel.setFilterKeyColumn(2)

    # Slot for clearing all filters
    def clearFilters(self):
        self.dateEdit.setDate(self.maxDate)
        self.proxyModel.setFilterRegExp('')
        self.proxyModel.setFilterKeyColumn(0)
        self.proxyModel.setFilterKeyColumn(1)
        self.proxyModel.setFilterKeyColumn(2)
        self.lineEdit_recipe.clear()
        self.edit_batchID.clear()
示例#27
0
class Main(QWidget):
    def __init__(self):
        super().__init__()
        simulation = Simulation(0.5, 100)
        simulation.run_interactively()
        self.state = MainState(simulation)
        self.music_window: QWidget = None
        self.music_thread = MusicPlayerThread(None, '')
        self.sidebar = None
        self.main_container: QHBoxLayout = None
        self.setStyleSheet(style.main)
        self.initWidgets()
        self.initMainContainer()
        self.initUI()

    def restart(self):
        self.__init__()

    def initWidgets(self):
        population = self.state.simulation.population[0:self.state.simulation.
                                                      selection_size]
        self.music_window = MusicWindow(MusicWindowViewModel(self, population))
        self.sidebar = Sidebar(self)

    def initMainContainer(self):
        self.main_container = QHBoxLayout()
        self.main_container.setContentsMargins(0, 0, 0, 0)
        self.main_container.setSpacing(0)
        self.main_container.addWidget(self.sidebar, 1)
        self.main_container.addWidget(self.music_window, 4)

    def initUI(self):
        self.setLayout(self.main_container)
        self.setGeometry(300, 300, 800, 600)
        self.setWindowTitle('EvoMusic')
        self.setObjectName('main')
        self.show()

    # def closeEvent(self, event):
    #
    #     reply = QMessageBox.question(self, 'Message',
    #                                  "Are you sure you want to quit?", QMessageBox.Yes |
    #                                  QMessageBox.No, QMessageBox.No)
    #
    #     if reply == QMessageBox.Yes:
    #         event.accept()
    #     else:
    #         event.ignore()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def initPopulation(self):
        corpus = modelTrainer.get_corpus()
        pitch_matrix = modelTrainer.train_pitch_matrix(corpus)
        duration_matrix = modelTrainer.train_duration_matrix(corpus)
        self.simulation.run_interactively(pitch_matrix, duration_matrix, None)

    def toNextGeneration(self):
        print(f"Generating next generation {self.state.currGeneration + 1}")
        self.state.simulation.update()
        self.state.currGeneration += 1
        self.state.curr_piece_index = 0
        self.state.curr_pieces = self.state.simulation.population[0:5]
        self.updateViews()

    def updateViews(self):
        self.main_container.removeWidget(self.music_window)
        self.music_window.deleteLater()
        musicViewModel = MusicWindowViewModel(
            self, self.state.curr_pieces,
            self.state.curr_pieces[self.state.curr_piece_index], None)

        self.music_window = MusicWindow(musicViewModel)
        self.main_container.addWidget(self.music_window)
        self.sidebar.setModel(self.state.currGeneration)
        self.update()

    def setPieceRating(self, piece_idx, rating):
        self.state.simulation.population[piece_idx].user_score = rating

    def setMeasureRating(self, piece_index, measure_index, rating):
        self.state.simulation.population[piece_index] \
            .measures[measure_index].user_score = rating

    def playMusicXml(self):
        curr = self.music_window.model.curr_piece
        musicPlayer.play_music_xml([curr])

    def toNextPiece(self):
        next_index = self.state.curr_piece_index + 1
        if next_index < len(self.state.curr_pieces):
            self.state.curr_individual = self.state.curr_pieces[next_index]
            self.state.curr_piece_index += 1
            self.updateViews()

    def toPreviousPiece(self):
        prev_index = self.state.curr_piece_index - 1
        if prev_index >= 0:
            self.state.curr_individual = self.state.curr_pieces[prev_index]
            self.state.curr_piece_index -= 1
            self.updateViews()

    def refreshWindows(self):
        self.main_container.removeWidget(self.main_container)
        self.music_window.deleteLater()
        self.main_container.addWidget()

    def play(self):
        self.music_thread.terminate()
        self.music_thread = MusicPlayerThread(
            [self.state.curr_pieces[self.state.curr_piece_index]], 'piece')
        self.music_thread.start()
class Module(QGroupBox):
    def __init__(self, mainWindow, name, devices):
        QGroupBox.__init__(self)

        self.mainWindow = mainWindow
        self.name = name
        self.devices = devices

        self.groupBox = []
        self.alarmGB = []
        self.divcoeff = 5

        self.cLayout = QHBoxLayout()
        self.alarmLayout = QHBoxLayout()
        self.gbLayout = QGridLayout()

        self.cLayout.addLayout(self.alarmLayout)
        self.cLayout.addLayout(self.gbLayout)

        self.setLayout(self.cLayout)

        self.initialize()
        self.waitforData()

    @property
    def actors(self):
        return list(OrderedDict.fromkeys([device.tablename.split('__')[0] for device in self.devices]))

    @property
    def isOffline(self):
        return True if self.mode == 'offline' else False

    def initialize(self):
        self.createGroupBox()

        self.eyeButton = EyeButton(self)
        self.acquisition = Acquisition(self)
        self.alarmLayout.addWidget(self.acquisition)

    def setAlarms(self, alarms):
        hide = self.cleanAlarms()
        self.mode = alarms[0].mode if alarms else 'offline'
        self.setTitle('%s - %s ' % (self.name, self.mode))

        for alarm in alarms:
            widget = AlarmGB(self, alarm)
            self.alarmGB.append(widget)
            self.alarmLayout.addWidget(widget)
            widget.hide() if hide else widget.show()

    def cleanAlarms(self):
        hide = False
        while self.alarmGB:
            alarm = self.alarmGB[0]
            hide = alarm.isHidden()
            self.alarmLayout.removeWidget(alarm)
            alarm.deleteLater()
            self.alarmGB.remove(alarm)

        return hide

    def moveEye(self):

        try:
            self.eyeButton.move(self.width() - 30, 0)
        except:
            pass

    def createGroupBox(self):
        for i, deviceConf in enumerate(self.devices):
            groupbox = DeviceGB(self, deviceConf)
            try:
                groupbox.testData()
                self.groupBox.append(groupbox)
                self.gbLayout.addWidget(groupbox, (i // self.divcoeff) + 1, i % self.divcoeff)
            except Exception as e:
                print (e, deviceConf.tablename)

    def showAll(self, bool):

        for groupbox in self.groupBox:
            groupbox.hide() if not bool else groupbox.show()

        for alarm in self.alarmGB:
            alarm.show() if not bool else alarm.hide()

        try:
            self.acquisition.hide() if bool else self.acquisition.show()
        except AttributeError:
            pass

        self.adjustSize()
        self.mainWindow.mainWidget.adjustSize()
        self.mainWindow.adjustSize()


    def waitforData(self):
        try:
            for groupbox in self.groupBox:
                groupbox.waitforData()
            for alarm in self.alarmGB:
                alarm.getValue()
            self.acquisition.network = True

        except psycopg2.OperationalError:
            self.acquisition.network = False
            self.mainWindow.db.close()

    def updateMode(self, mode):
        modes = readMode()
        for actor in self.actors:
            modes[actor] = mode

        writeMode(modes)

    def getGroupBox(self, tableName):
        for i, groupbox in enumerate(self.groupBox):
            if groupbox.tablename == tableName:
                return self.groupBox[i]

    def mouseReleaseEvent(self, QMouseEvent):
        if QMouseEvent.button() == Qt.RightButton:
            menu = QMenu(self)

            all_modes = [f[:-4] for f in next(os.walk(self.mainWindow.alarmPath))[-1] if '.cfg' in f]
            for mode in all_modes:
                action = QAction(mode, self)
                action.triggered.connect(partial(self.updateMode, mode))
                menu.addAction(action)

            menu.popup(QCursor.pos())

    def resizeEvent(self, QResizeEvent):
        self.moveEye()
        QGroupBox.resizeEvent(self, QResizeEvent)
示例#29
0
class StatusBar(QWidget):
    """The statusbar at the bottom of the mainwindow.

    Attributes:
        txt: The Text widget in the statusbar.
        keystring: The KeyString widget in the statusbar.
        percentage: The Percentage widget in the statusbar.
        url: The UrlText widget in the statusbar.
        prog: The Progress widget in the statusbar.
        cmd: The Command widget in the statusbar.
        _hbox: The main QHBoxLayout.
        _stack: The QStackedLayout with cmd/txt widgets.
        _win_id: The window ID the statusbar is associated with.

    Signals:
        resized: Emitted when the statusbar has resized, so the completion
                 widget can adjust its size to it.
                 arg: The new size.
        moved: Emitted when the statusbar has moved, so the completion widget
               can move to the right position.
               arg: The new position.
    """

    resized = pyqtSignal('QRect')
    moved = pyqtSignal('QPoint')

    STYLESHEET = _generate_stylesheet()

    def __init__(self, *, win_id, private, parent=None):
        super().__init__(parent)
        self.setObjectName(self.__class__.__name__)
        self.setAttribute(Qt.WA_StyledBackground)
        stylesheet.set_register(self)

        self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)

        self._win_id = win_id
        self._color_flags = ColorFlags()
        self._color_flags.private = private

        self._hbox = QHBoxLayout(self)
        self._set_hbox_padding()
        self._hbox.setSpacing(5)

        self._stack = QStackedLayout()
        self._hbox.addLayout(self._stack)
        self._stack.setContentsMargins(0, 0, 0, 0)

        self.cmd = command.Command(private=private, win_id=win_id)
        self._stack.addWidget(self.cmd)
        objreg.register('status-command',
                        self.cmd,
                        scope='window',
                        window=win_id)

        self.txt = textbase.TextBase()
        self._stack.addWidget(self.txt)

        self.cmd.show_cmd.connect(self._show_cmd_widget)
        self.cmd.hide_cmd.connect(self._hide_cmd_widget)
        self._hide_cmd_widget()

        self.url = url.UrlText()
        self.percentage = percentage.Percentage()
        self.backforward = backforward.Backforward()
        self.tabindex = tabindex.TabIndex()
        self.keystring = keystring.KeyString()
        self.prog = progress.Progress(self)
        self._text_widgets = []
        self._draw_widgets()

        config.instance.changed.connect(self._on_config_changed)
        QTimer.singleShot(0, self.maybe_hide)

    def __repr__(self):
        return utils.get_repr(self)

    @pyqtSlot(str)
    def _on_config_changed(self, option):
        if option == 'statusbar.show':
            self.maybe_hide()
        elif option == 'statusbar.padding':
            self._set_hbox_padding()
        elif option == 'statusbar.widgets':
            self._draw_widgets()

    def _draw_widgets(self):
        """Draw statusbar widgets."""
        self._clear_widgets()

        tab = self._current_tab()

        # Read the list and set widgets accordingly
        for segment in config.val.statusbar.widgets:
            if segment == 'url':
                self._hbox.addWidget(self.url)
                self.url.show()
            elif segment == 'scroll':
                self._hbox.addWidget(self.percentage)
                self.percentage.show()
            elif segment == 'scroll_raw':
                self._hbox.addWidget(self.percentage)
                self.percentage.set_raw()
                self.percentage.show()
            elif segment == 'history':
                self._hbox.addWidget(self.backforward)
                self.backforward.enabled = True
                if tab:
                    self.backforward.on_tab_changed(tab)
            elif segment == 'tabs':
                self._hbox.addWidget(self.tabindex)
                self.tabindex.show()
            elif segment == 'keypress':
                self._hbox.addWidget(self.keystring)
                self.keystring.show()
            elif segment == 'progress':
                self._hbox.addWidget(self.prog)
                self.prog.enabled = True
                if tab:
                    self.prog.on_tab_changed(tab)
            elif segment.startswith('text:'):
                cur_widget = textbase.TextBase()
                self._text_widgets.append(cur_widget)
                cur_widget.setText(segment.split(':', maxsplit=1)[1])
                self._hbox.addWidget(cur_widget)
                cur_widget.show()
            else:
                raise utils.Unreachable(segment)

    def _clear_widgets(self):
        """Clear widgets before redrawing them."""
        # Start with widgets hidden and show them when needed
        for widget in [
                self.url, self.percentage, self.backforward, self.tabindex,
                self.keystring, self.prog, *self._text_widgets
        ]:
            assert isinstance(widget, QWidget)
            widget.hide()
            self._hbox.removeWidget(widget)
        self._text_widgets.clear()

    @pyqtSlot()
    def maybe_hide(self):
        """Hide the statusbar if it's configured to do so."""
        strategy = config.val.statusbar.show
        tab = self._current_tab()
        if tab is not None and tab.data.fullscreen:
            self.hide()
        elif strategy == 'never':
            self.hide()
        elif strategy == 'in-mode':
            try:
                mode_manager = modeman.instance(self._win_id)
            except modeman.UnavailableError:
                self.hide()
            else:
                if mode_manager.mode == usertypes.KeyMode.normal:
                    self.hide()
                else:
                    self.show()
        elif strategy == 'always':
            self.show()
        else:
            raise utils.Unreachable

    def _set_hbox_padding(self):
        padding = config.val.statusbar.padding
        self._hbox.setContentsMargins(padding.left, 0, padding.right, 0)

    @pyqtProperty('QStringList')  # type: ignore[type-var]
    def color_flags(self):
        """Getter for self.color_flags, so it can be used as Qt property."""
        return self._color_flags.to_stringlist()

    def _current_tab(self):
        """Get the currently displayed tab."""
        window = objreg.get('tabbed-browser',
                            scope='window',
                            window=self._win_id)
        return window.widget.currentWidget()

    def set_mode_active(self, mode, val):
        """Setter for self.{insert,command,caret}_active.

        Re-set the stylesheet after setting the value, so everything gets
        updated by Qt properly.
        """
        if mode == usertypes.KeyMode.insert:
            log.statusbar.debug("Setting insert flag to {}".format(val))
            self._color_flags.insert = val
        if mode == usertypes.KeyMode.passthrough:
            log.statusbar.debug("Setting passthrough flag to {}".format(val))
            self._color_flags.passthrough = val
        if mode == usertypes.KeyMode.command:
            log.statusbar.debug("Setting command flag to {}".format(val))
            self._color_flags.command = val
        elif mode in [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno]:
            log.statusbar.debug("Setting prompt flag to {}".format(val))
            self._color_flags.prompt = val
        elif mode == usertypes.KeyMode.caret:
            if not val:
                # Turning on is handled in on_current_caret_selection_toggled
                log.statusbar.debug("Setting caret mode off")
                self._color_flags.caret = ColorFlags.CaretMode.off
        stylesheet.set_register(self, update=False)

    def _set_mode_text(self, mode):
        """Set the mode text."""
        if mode == 'passthrough':
            key_instance = config.key_instance
            all_bindings = key_instance.get_reverse_bindings_for('passthrough')
            bindings = all_bindings.get('mode-leave')
            if bindings:
                suffix = ' ({} to leave)'.format(' or '.join(bindings))
            else:
                suffix = ''
        else:
            suffix = ''
        text = "-- {} MODE --{}".format(mode.upper(), suffix)
        self.txt.setText(text)

    def _show_cmd_widget(self):
        """Show command widget instead of temporary text."""
        self._stack.setCurrentWidget(self.cmd)
        self.show()

    def _hide_cmd_widget(self):
        """Show temporary text instead of command widget."""
        log.statusbar.debug("Hiding cmd widget")
        self._stack.setCurrentWidget(self.txt)
        self.maybe_hide()

    @pyqtSlot(str)
    def set_text(self, text):
        """Set a normal (persistent) text in the status bar."""
        log.message.debug(text)
        self.txt.setText(text)

    @pyqtSlot(usertypes.KeyMode)
    def on_mode_entered(self, mode):
        """Mark certain modes in the commandline."""
        mode_manager = modeman.instance(self._win_id)
        if config.val.statusbar.show == 'in-mode':
            self.show()
        if mode_manager.parsers[mode].passthrough:
            self._set_mode_text(mode.name)
        if mode in [
                usertypes.KeyMode.insert, usertypes.KeyMode.command,
                usertypes.KeyMode.caret, usertypes.KeyMode.prompt,
                usertypes.KeyMode.yesno, usertypes.KeyMode.passthrough
        ]:
            self.set_mode_active(mode, True)

    @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode)
    def on_mode_left(self, old_mode, new_mode):
        """Clear marked mode."""
        mode_manager = modeman.instance(self._win_id)
        if config.val.statusbar.show == 'in-mode':
            self.hide()
        if mode_manager.parsers[old_mode].passthrough:
            if mode_manager.parsers[new_mode].passthrough:
                self._set_mode_text(new_mode.name)
            else:
                self.txt.setText('')
        if old_mode in [
                usertypes.KeyMode.insert, usertypes.KeyMode.command,
                usertypes.KeyMode.caret, usertypes.KeyMode.prompt,
                usertypes.KeyMode.yesno, usertypes.KeyMode.passthrough
        ]:
            self.set_mode_active(old_mode, False)

    @pyqtSlot(browsertab.AbstractTab)
    def on_tab_changed(self, tab):
        """Notify sub-widgets when the tab has been changed."""
        self.url.on_tab_changed(tab)
        self.prog.on_tab_changed(tab)
        self.percentage.on_tab_changed(tab)
        self.backforward.on_tab_changed(tab)
        self.maybe_hide()
        assert tab.is_private == self._color_flags.private

    @pyqtSlot(browsertab.SelectionState)
    def on_caret_selection_toggled(self, selection_state):
        """Update the statusbar when entering/leaving caret selection mode."""
        log.statusbar.debug(
            "Setting caret selection {}".format(selection_state))
        if selection_state is browsertab.SelectionState.normal:
            self._set_mode_text("caret selection")
            self._color_flags.caret = ColorFlags.CaretMode.selection
        elif selection_state is browsertab.SelectionState.line:
            self._set_mode_text("caret line selection")
            self._color_flags.caret = ColorFlags.CaretMode.selection
        else:
            self._set_mode_text("caret")
            self._color_flags.caret = ColorFlags.CaretMode.on
        stylesheet.set_register(self, update=False)

    def resizeEvent(self, e):
        """Extend resizeEvent of QWidget to emit a resized signal afterwards.

        Args:
            e: The QResizeEvent.
        """
        super().resizeEvent(e)
        self.resized.emit(self.geometry())

    def moveEvent(self, e):
        """Extend moveEvent of QWidget to emit a moved signal afterwards.

        Args:
            e: The QMoveEvent.
        """
        super().moveEvent(e)
        self.moved.emit(e.pos())

    def minimumSizeHint(self):
        """Set the minimum height to the text height plus some padding."""
        padding = config.cache['statusbar.padding']
        width = super().minimumSizeHint().width()
        height = self.fontMetrics().height() + padding.top + padding.bottom
        return QSize(width, height)
示例#30
0
class RadioBox(QWidget):
    def __init__(self, parent=None, items=None, spread=True, **kwargs):
        # If spread is False, insert a spacer in the layout so that the items don't use all the
        # space they're given but rather align left.
        if items is None:
            items = []
        super().__init__(parent, **kwargs)
        self._buttons = []
        self._labels = items
        self._selected_index = 0
        self._spacer = horizontalSpacer() if not spread else None
        self._layout = QHBoxLayout(self)
        self._update_buttons()

    # --- Private
    def _update_buttons(self):
        if self._spacer is not None:
            self._layout.removeItem(self._spacer)
        to_remove = self._buttons[len(self._labels):]
        for button in to_remove:
            self._layout.removeWidget(button)
            button.setParent(None)
        del self._buttons[len(self._labels):]
        to_add = self._labels[len(self._buttons):]
        for _ in to_add:
            button = QRadioButton(self)
            self._buttons.append(button)
            self._layout.addWidget(button)
            button.toggled.connect(self.buttonToggled)
        if self._spacer is not None:
            self._layout.addItem(self._spacer)
        if not self._buttons:
            return
        for button, label in zip(self._buttons, self._labels):
            button.setText(label)
        self._update_selection()

    def _update_selection(self):
        self._selected_index = max(
            0, min(self._selected_index,
                   len(self._buttons) - 1))
        selected = self._buttons[self._selected_index]
        selected.setChecked(True)

    # --- Event Handlers
    def buttonToggled(self):
        for i, button in enumerate(self._buttons):
            if button.isChecked():
                self._selected_index = i
                self.itemSelected.emit(i)
                break

    # --- Signals
    itemSelected = pyqtSignal(int)

    # --- Properties
    @property
    def buttons(self):
        return self._buttons[:]

    @property
    def items(self):
        return self._labels[:]

    @items.setter
    def items(self, value):
        self._labels = value
        self._update_buttons()

    @property
    def selected_index(self):
        return self._selected_index

    @selected_index.setter
    def selected_index(self, value):
        self._selected_index = value
        self._update_selection()
示例#31
0
class SongsTableToolbar(QWidget):
    play_all_needed = pyqtSignal()
    filter_albums_needed = pyqtSignal([list])
    filter_text_changed = pyqtSignal([str])

    def __init__(self, parent=None):
        super().__init__(parent)

        self._tmp_buttons = []

        self.play_all_btn = TextButton('播放全部', self)
        self.play_all_btn.clicked.connect(self.play_all_needed.emit)

        self.play_all_btn.setObjectName('play_all')

        # album filters
        self.filter_albums_combobox = QComboBox(self)
        self.filter_albums_combobox.addItems(
            ['所有专辑', '标准', '单曲与EP', '现场', '合辑'])
        self.filter_albums_combobox.currentIndexChanged.connect(
            self.on_albums_filter_changed)
        # 8 works on macOS, don't know if it works on various Linux DEs
        self.filter_albums_combobox.setMinimumContentsLength(8)
        self.filter_albums_combobox.hide()
        self._setup_ui()

    def albums_mode(self):
        self._before_change_mode()
        self.filter_albums_combobox.show()

    def songs_mode(self):
        self._before_change_mode()
        self.play_all_btn.show()

    def artists_mode(self):
        self._before_change_mode()

    def manual_mode(self):
        """fully customized mode

        .. versionadded:: 3.7.11
           You'd better use this mode and add_tmp_button to customize toolbar.
        """
        self._before_change_mode()

    def enter_state_playall_start(self):
        self.play_all_btn.setEnabled(False)
        # currently, this is called only when feeluown is fetching songs,
        # so when we enter state_playall_start, we set play all btn text
        # to this.
        self.play_all_btn.setText('获取所有歌曲...')

    def enter_state_playall_end(self):
        self.play_all_btn.setText('获取所有歌曲...done')
        self.play_all_btn.setEnabled(True)
        self.play_all_btn.setText('播放全部')

    def add_tmp_button(self, button):
        """Append text button"""
        if button not in self._tmp_buttons:
            # FIXME(cosven): the button inserted isn't aligned with other buttons
            index = len(self._tmp_buttons)
            if self.play_all_btn.isVisible():
                index = index + 1
            self._layout.insertWidget(index, button)
            self._tmp_buttons.append(button)

    def _setup_ui(self):
        self._layout = QHBoxLayout(self)
        # left margin of meta widget is 30, we align with it
        # bottom margin of meta widget is 15, we should be larger than that
        self._layout.setContentsMargins(30, 15, 30, 10)
        self._layout.addWidget(self.play_all_btn)
        self._layout.addStretch(0)
        self._layout.addWidget(self.filter_albums_combobox)

    def _before_change_mode(self):
        """filter all filter buttons"""
        for button in self._tmp_buttons:
            self._layout.removeWidget(button)
            button.close()
        self._tmp_buttons.clear()
        self.filter_albums_combobox.hide()
        self.play_all_btn.hide()

    def on_albums_filter_changed(self, index):
        # ['所有', '专辑', '单曲与EP', '现场', '合辑']
        if index == 0:
            types = []
        elif index == 1:
            types = [AlbumType.standard]
        elif index == 2:
            types = [AlbumType.single, AlbumType.ep]
        elif index == 3:
            types = [AlbumType.live]
        else:
            types = [AlbumType.compilation, AlbumType.retrospective]
        self.filter_albums_needed.emit(types)
示例#32
0
class LineEdit(QLineEdit):
    inactiveText  = QtDynamicProperty('inactiveText',  unicode)
    widgetSpacing = QtDynamicProperty('widgetSpacing', int)

    def __init__(self, parent=None, contents=u""):
        super(LineEdit, self).__init__(contents, parent)
        box_direction = QBoxLayout.RightToLeft if self.isRightToLeft() else QBoxLayout.LeftToRight
        self.inactiveText = u""
        self.left_widget = SideWidget(self)
        self.left_widget.resize(0, 0)
        self.left_layout = QHBoxLayout(self.left_widget)
        self.left_layout.setContentsMargins(0, 0, 0, 0)
        self.left_layout.setDirection(box_direction)
        self.left_layout.setSizeConstraint(QLayout.SetFixedSize)
        self.right_widget = SideWidget(self)
        self.right_widget.resize(0, 0)
        self.right_layout = QHBoxLayout(self.right_widget)
        self.right_layout.setContentsMargins(0, 0, 0, 0)
        self.right_layout.setDirection(box_direction)
        self.right_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum))
        self.widgetSpacing = 2
        self.left_widget.sizeHintChanged.connect(self._update_text_margins)
        self.right_widget.sizeHintChanged.connect(self._update_text_margins)

    @property
    def left_margin(self):
        return self.left_widget.sizeHint().width() + 2*self.left_layout.spacing()

    @property
    def right_margin(self):
        return self.right_widget.sizeHint().width() + 2*self.right_layout.spacing()

    def _update_text_margins(self):
        self.setTextMargins(self.left_margin, 0, self.right_margin, 0)
        self._update_side_widget_locations()

    def _update_side_widget_locations(self):
        option = QStyleOptionFrame()
        self.initStyleOption(option)
        spacing = self.right_layout.spacing()
        text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, option, self)
        text_rect.adjust(spacing, 0, -spacing, 0)
        mid_height = text_rect.center().y() + 1 - (text_rect.height() % 2)  # need -1 correction for odd heights -Dan
        if self.left_layout.count() > 0:
            left_height = mid_height - self.left_widget.height()/2
            left_width = self.left_widget.width()
            if left_width == 0:
                left_height = mid_height - self.left_widget.sizeHint().height()/2
            self.left_widget.move(text_rect.x(), left_height)
        text_rect.setX(self.left_margin)
        text_rect.setY(mid_height - self.right_widget.sizeHint().height()/2.0)
        text_rect.setHeight(self.right_widget.sizeHint().height())
        self.right_widget.setGeometry(text_rect)

    def event(self, event):
        event_type = event.type()
        if event_type == QEvent.LayoutDirectionChange:
            box_direction = QBoxLayout.RightToLeft if self.isRightToLeft() else QBoxLayout.LeftToRight
            self.left_layout.setDirection(box_direction)
            self.right_layout.setDirection(box_direction)
        elif event_type == QEvent.DynamicPropertyChange:
            property_name = event.propertyName()
            if property_name == 'widgetSpacing':
                self.left_layout.setSpacing(self.widgetSpacing)
                self.right_layout.setSpacing(self.widgetSpacing)
                self._update_text_margins()
            elif property_name == 'inactiveText':
                self.update()
        return QLineEdit.event(self, event)

    def resizeEvent(self, event):
        self._update_side_widget_locations()
        QLineEdit.resizeEvent(self, event)

    def paintEvent(self, event):
        QLineEdit.paintEvent(self, event)
        if not self.hasFocus() and not self.text() and self.inactiveText:
            options = QStyleOptionFrame()
            self.initStyleOption(options)
            text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, options, self)
            text_rect.adjust(self.left_margin+2, 0, -self.right_margin, 0)
            painter = QPainter(self)
            painter.setPen(self.palette().brush(QPalette.Disabled, QPalette.Text).color())
            painter.drawText(text_rect, Qt.AlignLeft | Qt.AlignVCenter, self.inactiveText)

    def addHeadWidget(self, widget):
        if self.isRightToLeft():
            self.right_layout.insertWidget(1, widget)
        else:
            self.left_layout.addWidget(widget)

    def addTailWidget(self, widget):
        if self.isRightToLeft():
            self.left_layout.addWidget(widget)
        else:
            self.right_layout.insertWidget(1, widget)

    def removeWidget(self, widget):
        self.left_layout.removeWidget(widget)
        self.right_layout.removeWidget(widget)
        widget.hide()
示例#33
0
class CPinUI(QWidget):
    def __init__(self, pinID, parent=None):
        super(CPinUI, self).__init__(parent)
        self.m_PinID = pinID
        self.m_NodeID = interface.GetNodeIDByPinID(pinID)
        self.m_GraphicID = interface.GetGraphicIDByNodeID(self.m_NodeID)
        self.m_Btn = None
        self.m_Label = None
        self.m_HLayout = None
        self.m_DefaultWidget = None  # 默认值控件
        self._InitUI()
        self.SetIcon()
        self.SetText()
        self.ShowDefaultWidget()
        GetUIMgr().AddPinUI(pinID, self)

    def __del__(self):
        GetUIMgr().DelPinUI(self.m_PinID)

    def _InitUI(self):
        hBox = QHBoxLayout(self)
        hBox.setContentsMargins(0, 0, 0, 0)
        hBox.setSpacing(6)
        self.m_Btn = CTypeButton(self.m_PinID, self)
        self.m_Label = QLabel(self)
        self.m_HLayout = QHBoxLayout()
        self.m_HLayout.setContentsMargins(0, 0, 0, 0)
        self.m_HLayout.setSpacing(6)
        hBox.addWidget(self.m_Btn)
        hBox.addWidget(self.m_Label)
        hBox.addLayout(self.m_HLayout)

    def contextMenuEvent(self, event):
        super(CPinUI, self).contextMenuEvent(event)
        lstLineID = interface.GetAllLineByPin(self.m_PinID)
        menu = QMenu()
        for lineID in lstLineID:
            oPinID = interface.GetLineOtherPin(lineID, self.m_PinID)
            sPinDisplayName = interface.GetPinAttr(oPinID, bddefine.PinAttrName.DISPLAYNAME)
            nodeID = interface.GetNodeIDByPinID(oPinID)
            sNodeDisplayName = interface.GetNodeAttr(nodeID, bddefine.NodeAttrName.DISPLAYNAME)
            sMsg = "删除与\"%s\"-\"%s\"的连线" % (sNodeDisplayName, sPinDisplayName)
            func = functor.Functor(interface.DelLine, lineID)
            menu.addAction(sMsg, func)
        menu.exec_(QCursor.pos())
        event.accept()

    def SetIcon(self, iDataType=None):
        if iDataType is None:
            iPinType = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.PIN_TYPE)
            if bddefine.PinIsFlow(iPinType):
                iDataType = -1
            else:
                iDataType = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.DATA_TYPE)
        icon = QIcon()
        pix = ":/icon/btn_%s.png" % iDataType
        icon.addPixmap(QPixmap(pix), QIcon.Normal, QIcon.Off)
        self.m_Btn.setIcon(icon)

    def SetText(self, sText=None):
        if sText is None:
            sText = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.DISPLAYNAME)
        self.m_Label.setText(sText)

    def ShowDefaultWidget(self):
        iPinType = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.PIN_TYPE)
        if iPinType != bddefine.PIN_INPUT_DATA_TYPE:
            return
        lstLine = interface.GetAllLineByPin(self.m_PinID)
        if lstLine:
            return
        oWidget = None
        iDataTye = interface.GetPinAttr(self.m_PinID, bddefine.PinAttrName.DATA_TYPE)
        if iDataTye in (bddefine.Type.INT, bddefine.Type.FLOAT, bddefine.Type.STR):
            oWidget = subpinui.CValidatorLineEdit(self.m_PinID, iDataTye)
        elif iDataTye == bddefine.Type.BOOL:
            oWidget = subpinui.CCheckBox(self.m_PinID)
        elif iDataTye == bddefine.Type.ENUM:
            oWidget = subpinui.CEnum(self.m_PinID)
        elif iDataTye == bddefine.Type.VECTOR3:
            oWidget = subpinui.CVector3(self.m_PinID)
        elif iDataTye == bddefine.Type.CHECKBOX:
            oWidget = subpinui.CComCheckBox(self.m_PinID)
        if oWidget:
            self.m_HLayout.addWidget(oWidget)
            self.m_DefaultWidget = oWidget
            self.adjustSize()

    def HideDefaultWidget(self):
        if not self.m_DefaultWidget:
            return
        self.m_DefaultWidget.setParent(None)
        index = self.m_HLayout.indexOf(self.m_DefaultWidget)
        item = self.m_HLayout.itemAt(index)
        self.m_HLayout.removeWidget(self.m_DefaultWidget)
        self.m_HLayout.removeItem(item)
        self.m_DefaultWidget = None
        self.adjustSize()

    def enterEvent(self, event):
        super(CPinUI, self).enterEvent(event)
        GetSignal().UI_LINE_CONNECT.emit(self.m_GraphicID, self.m_PinID)
        event.accept()
示例#34
0
class maedit_widget(QWidget, themed_window):
    def __init__(self, parent, theme = "default"):
        super().__init__()
 
        self.parent = parent
        
        self.file_types_names = [".bck", ".bca", ".btk", ".brk", ".btp", ".bpk", ".bla", ".blk", ".bva" ];
        
        #stuff that we want to return / have access to
        self.selected = None
        self.filepath = None
        
        self.values = []
        
        self.setup_ui()
        self.set_theme(theme)
    def setup_ui(self):

        
        self.horizontalLayout = QHBoxLayout()
        self.centralwidget = self.horizontalLayout
        #self.setCentralWidget(self.horizontalLayout)
        
        self.setLayout(self.centralwidget)
        
        #choose the animation type
        self.type_layout = QWidget(self)
        self.type_box = QVBoxLayout(self.type_layout)
        
        self.select_label = QLabel(self.type_layout)
        self.select_label.setText("Select Animation Type to Edit")
        self.file_types = QListWidget(self.type_layout)
        self.file_types.clear()
        for type in self.file_types_names:
            self.file_types.addItem(type)
        self.file_types.setCurrentRow(0)
        self.file_types.clicked.connect(self.edit_right_side)
        
        self.type_box.addWidget(self.select_label)
        self.type_box.addWidget(self.file_types)
        
        #other needed info
        self.other_info_layout = QWidget(self)
        self.other_info_layout.setGeometry(0, 0, 250, 250)
    
        self.other_info_box = self.get_right_side()
  
        #add stuff to horizontal layout
        self.horizontalLayout.addWidget(self.type_layout)
        self.horizontalLayout.addWidget(self.other_info_layout)
    
    def edit_right_side(self):
        self.horizontalLayout.removeWidget(self.other_info_layout)
        self.other_info_layout = QWidget(self)
        self.other_info_box = self.get_right_side()
        self.horizontalLayout.addWidget(self.other_info_layout)
        if self.filepath:
            for i in range( self.bmd_thing_select.count() ):
                self.bmd_thing_select.remove(i)
            
            if self.selected in [".bck", ".bca"]:
                self.bmd_thing_select.addItems( j3d.get_bones_from_bmd(self.filepath) )
            elif self.selected in [".btk", ".btp", ".bpk", ".brk"]:
                self.bmd_thing_select.addItems( j3d.get_materials_from_bmd(self.filepath) )
            elif self.selected in [".blk", ".bla", ".bva"]:
                self.bmd_thing_select.addItems( j3d.get_meshes_from_bmd(self.filepath) )
    
    def create_combo_box(self, widget_parent):
        combo_box = QComboBox(widget_parent)
        combo_box.addItems( ["+", "-", "*", "/", "Average / Set To"] )
        return combo_box
        
    def get_right_side(self):
        operations_box = QGridLayout(self.other_info_layout)
        widget_parent = self.other_info_layout
        self.selected = self.file_types.currentItem().text()

        label = QLabel(widget_parent)
        label.setText("Select File")
        operations_box.addWidget(label, 0, 0)
        
        button = QPushButton("Select .bmd / .bdl")
        button.clicked.connect(self.open_file_dialog)
        operations_box.addWidget(button , 0, 1)
        
        self.bmd_thing_select = QComboBox(widget_parent)
        operations_box.addWidget(self.bmd_thing_select, 0, 2)
        
        if self.selected in [".bck", ".bca"]:
            srt = ["Scale ", "Rotation ", "Translation "];
            axis = ["X:", "Y:", "Z:"]
            for i in range(len( srt )):
                for j in range(len( axis)):
                    label = QLabel(widget_parent)
                    label.setText(srt[i] + axis[j])
                    operations_box.addWidget( label ,3 * i + j + 1, 0 )
                    operations_box.addWidget( self.create_combo_box(widget_parent),  3* i + j+ 1,  1)
                    operations_box.addWidget( QLineEdit(widget_parent), 3 * i + j+ 1,  2)

        elif self.selected in [".brk", ".bpk"]:
            #color animation
            comp = ["Red:", "Green:", "Blue:", "Alpha:"];
            for i in range(len( comp )):
                label = QLabel(widget_parent)
                label.setText(comp[i])
                operations_box.addWidget( label ,i+ 1, 0 )
                operations_box.addWidget( self.create_combo_box(widget_parent),  i + 1,  1)
                operations_box.addWidget( QLineEdit(widget_parent), i+ 1,  2)
        
        elif self.selected == ".btk":
            #texture swapping animation
            
            srt = ["Scale ", "Rotation ", "Translation "];
            axis = ["U:", "V:", "W:"]
            for i in range(len( srt )):
                for j in range(len( axis)):
                    label = QLabel(widget_parent)
                    label.setText(srt[i] + axis[j])
                    operations_box.addWidget( label ,3 * i + j+ 1, 0 )
                    operations_box.addWidget( self.create_combo_box(widget_parent),  3* i + j+ 1,  1)
                    operations_box.addWidget( QLineEdit(widget_parent), 3 * i + j+ 1,  2)
        
        elif self.selected in [".blk", ".bla"]:
            #cluster animation
            label = QLabel(widget_parent)
            label.setText("Weight")
            operations_box.addWidget( label , 1, 0 )
            operations_box.addWidget( self.create_combo_box(widget_parent),  1,  1)
            operations_box.addWidget( QLineEdit(widget_parent), 1,  2)
            #button.setDisabled(True)
       
        elif self.selected == ".btp":
            #texture swapping animation
            label = QLabel(widget_parent)
            label.setText("Texture Index")
            operations_box.addWidget( label , 1, 0 )
            operations_box.addWidget( self.create_combo_box(widget_parent),  1,  1)
            operations_box.addWidget( QLineEdit(widget_parent), 1,  2)
        elif self.selected == ".bva":
            #visibility animation
            label = QLabel(widget_parent)
            label.setText("Visibility")
            operations_box.addWidget( label , 1, 0 )
            
            combo_box = QComboBox(widget_parent)
            combo_box.addItems( ["Swap", "Set To"] )
            operations_box.addWidget( combo_box,  1,  1)
            
            operations_box.addWidget( QLineEdit(widget_parent), 1,  2)
            #button.setDisabled(True)
            
        return operations_box

    

    def get_info(self):
        if self.selected is None:
            return None
        if self.filepath is None:
            return None
        values = []
        for i in range(1, self.other_info_box.rowCount() ):
            comp = []
            
            combo_box = self.other_info_box.itemAtPosition(i, 0).widget()
            comp.append( combo_box.text() )
            
            combo_box = self.other_info_box.itemAtPosition(i, 1).widget()
            comp.append( combo_box.currentIndex() )
            
            line_edit = self.other_info_box.itemAtPosition(i, 2).widget()
            comp.append( line_edit.text() )
            
            values.append(comp)
        if self.filepath.endswith(".bva"):
            # we KNOW that values only has one entry
            combo_box = self.other_info_box.itemAtPosition(i, 1).widget()
            if self.combo_box.currentIndex() == 0: #if swap
                values[0][2] = ""
            
        #print(self.selected, self.bmd_thing_select.currentText(), values)
        return ( [[self.selected, self.bmd_thing_select.currentText(), values]] )

         
    def open_file_dialog(self):
        filepath, choosentype = QFileDialog.getOpenFileName(self.other_info_layout, "Choose File Path", "", "j3d model files (*.bmd *.bdl)")
        if filepath:
            #self.filename_text.setText(filepath)
            self.filepath = filepath
            
            for i in range( self.bmd_thing_select.count() ):
                self.bmd_thing_select.remove(i)
            if self.selected in [".bck", ".bca"]:
                self.bmd_thing_select.addItems( j3d.get_bones_from_bmd(filepath) )
            elif self.selected in [".btk", ".btp", ".bpk", ".brk"]:
                self.bmd_thing_select.addItems( j3d.get_materials_from_bmd(filepath) )
            elif self.selected in [".blk", ".bla", ".bva"]:
                self.bmd_thing_select.addItems( j3d.get_meshes_from_bmd(filepath) )
示例#35
0
class E5LineEdit(QLineEdit):
    """
    Class implementing a line edit widget showing some inactive text.
    """
    LeftSide = 0
    RightSide = 1
    
    def __init__(self, parent=None, inactiveText=""):
        """
        Constructor
        
        @param parent reference to the parent widget (QWidget)
        @param inactiveText text to be shown on inactivity (string)
        """
        super(E5LineEdit, self).__init__(parent)
        
        self.setMinimumHeight(22)
        
        if qVersion() < "4.7.0":
            self.__inactiveText = inactiveText
        else:
            self.setPlaceholderText(inactiveText)
        
        self.__mainLayout = QHBoxLayout(self)
        self.__mainLayout.setContentsMargins(0, 0, 0, 0)
        self.__mainLayout.setSpacing(0)
        
        self.__leftMargin = 0
        self.__leftWidget = E5LineEditSideWidget(self)
        self.__leftWidget.resize(0, 0)
        self.__leftLayout = QHBoxLayout(self.__leftWidget)
        self.__leftLayout.setContentsMargins(0, 0, 2, 0)
        if QApplication.isRightToLeft():
            self.__leftLayout.setDirection(QBoxLayout.RightToLeft)
        else:
            self.__leftLayout.setDirection(QBoxLayout.LeftToRight)
        self.__leftLayout.setSizeConstraint(QLayout.SetFixedSize)
        
        self.__rightWidget = E5LineEditSideWidget(self)
        self.__rightWidget.resize(0, 0)
        self.__rightLayout = QHBoxLayout(self.__rightWidget)
        self.__rightLayout.setContentsMargins(0, 0, 2, 0)
        if self.isRightToLeft():
            self.__rightLayout.setDirection(QBoxLayout.RightToLeft)
        else:
            self.__rightLayout.setDirection(QBoxLayout.LeftToRight)
        
        horizontalSpacer = QSpacerItem(
            0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.__mainLayout.addWidget(
            self.__leftWidget, 0, Qt.AlignVCenter | Qt.AlignLeft)
        self.__mainLayout.addItem(horizontalSpacer)
        self.__mainLayout.addWidget(
            self.__rightWidget, 0, Qt.AlignVCenter | Qt.AlignRight)
        if self.isRightToLeft():
            self.__mainLayout.setDirection(QBoxLayout.RightToLeft)
        else:
            self.__mainLayout.setDirection(QBoxLayout.LeftToRight)
        
        self.setWidgetSpacing(3)
        self.__leftWidget.sizeHintChanged.connect(self._updateTextMargins)
        self.__rightWidget.sizeHintChanged.connect(self._updateTextMargins)
    
    def setLeftMargin(self, margin):
        """
        Public method to set the left margin.
        
        @param margin left margin in pixel (integer)
        """
        self.__leftMargin = margin
    
    def leftMargin(self):
        """
        Public method to get the size of the left margin.
        
        @return left margin in pixel (integer)
        """
        return self.__leftMargin
    
    def event(self, evt):
        """
        Public method to handle events.
        
        @param evt reference to the event (QEvent)
        @return flag indicating, whether the event was recognized (boolean)
        """
        if evt.type() == QEvent.LayoutDirectionChange:
            if self.isRightToLeft():
                self.__mainLayout.setDirection(QBoxLayout.RightToLeft)
                self.__leftLayout.setDirection(QBoxLayout.RightToLeft)
                self.__rightLayout.setDirection(QBoxLayout.RightToLeft)
            else:
                self.__mainLayout.setDirection(QBoxLayout.LeftToRight)
                self.__leftLayout.setDirection(QBoxLayout.LeftToRight)
                self.__rightLayout.setDirection(QBoxLayout.LeftToRight)
        return QLineEdit.event(self, evt)
    
    def paintEvent(self, evt):
        """
        Protected method handling a paint event.
        
        @param evt reference to the paint event (QPaintEvent)
        """
        super(E5LineEdit, self).paintEvent(evt)
        
        if qVersion() < "4.7.0":
            if not self.text() and \
               self.__inactiveText and \
               not self.hasFocus():
                panel = QStyleOptionFrame()
                self.initStyleOption(panel)
                textRect = self.style().subElementRect(
                    QStyle.SE_LineEditContents, panel, self)
                textRect.adjust(2, 0, 0, 0)
                left = self.textMargin(self.LeftSide)
                right = self.textMargin(self.RightSide)
                textRect.adjust(left, 0, -right, 0)
                painter = QPainter(self)
                painter.setPen(self.palette().brush(
                    QPalette.Disabled, QPalette.Text).color())
                painter.drawText(
                    textRect, Qt.AlignLeft | Qt.AlignVCenter,
                    self.__inactiveText)
    
    def _updateTextMargins(self):
        """
        Protected slot to update the text margins.
        """
        if self.__leftMargin == 0:
            left = self.__leftWidget.sizeHint().width()
        else:
            left = self.__leftMargin
        right = self.__rightWidget.sizeHint().width()
        top = 0
        bottom = 0
        self.setTextMargins(left, top, right, bottom)
    
    def addWidget(self, widget, position):
        """
        Public method to add a widget to a side.
        
        @param widget reference to the widget to add (QWidget)
        @param position position to add to (E5LineEdit.LeftSide,
            E5LineEdit.RightSide)
        """
        if widget is None:
            return
        
        if self.isRightToLeft():
            if position == self.LeftSide:
                position = self.RightSide
            else:
                position = self.LeftSide
        if position == self.LeftSide:
            self.__leftLayout.addWidget(widget)
        else:
            self.__rightLayout.insertWidget(1, widget)
    
    def removeWidget(self, widget):
        """
        Public method to remove a widget from a side.
        
        @param widget reference to the widget to remove (QWidget)
        """
        if widget is None:
            return
        
        self.__leftLayout.removeWidget(widget)
        self.__rightLayout.removeWidget(widget)
        widget.hide()
    
    def widgetSpacing(self):
        """
        Public method to get the side widget spacing.
        
        @return side widget spacing (integer)
        """
        return self.__leftLayout.spacing()
    
    def setWidgetSpacing(self, spacing):
        """
        Public method to set the side widget spacing.
        
        @param spacing side widget spacing (integer)
        """
        self.__leftLayout.setSpacing(spacing)
        self.__rightLayout.setSpacing(spacing)
        self._updateTextMargins()
    
    def textMargin(self, position):
        """
        Public method to get the text margin for a side.
        
        @param position side to get margin for (E5LineEdit.LeftSide,
            E5LineEdit.RightSide)
        @return text margin (integer)
        """
        spacing = self.__rightLayout.spacing()
        w = 0
        if position == self.LeftSide:
            w = self.__leftWidget.sizeHint().width()
        else:
            w = self.__rightWidget.sizeHint().width()
        if w == 0:
            return 0
        return w + spacing * 2
    
    def inactiveText(self):
        """
        Public method to get the inactive text.
        
        @return inactive text (string)
        """
        if qVersion() < "4.7.0":
            return self.__inactiveText
        else:
            return self.placeholderText()
    
    def setInactiveText(self, inactiveText):
        """
        Public method to set the inactive text.
        
        @param inactiveText text to be shown on inactivity (string)
        """
        if qVersion() < "4.7.0":
            self.__inactiveText = inactiveText
            self.update()
        else:
            self.setPlaceholderText(inactiveText)
示例#36
0
class ConfigBox(QGroupBox):
    modified = pyqtSignal()

    def __init__(self):
        super(ConfigBox, self).__init__()

        self._state_engine_option: List[ConfigParam] = []
        self._state_use_encryption = True
        self._state_engine_option_holder: List[Union[QButtonGroup,
                                                     QDoubleSpinBox]] = []

        self._setup_ui()

    def _setup_ui(self):
        self.setTitle('Options')

        self._main_layout = QFormLayout()

        # Label
        self._encrypt_option_label = QLabel()
        self._encrypt_option_label.setText('Encryption')
        self._encrypt_password_label = QLabel()
        self._encrypt_password_label.setText('Key')

        # Encryption radio
        self._encrypt_option_group = QButtonGroup()
        self._encrypt_option_layout = QHBoxLayout()

        self._encrypt_option = QRadioButton()
        self._encrypt_option.setText('Enabled')
        self._encrypt_option.setChecked(True)
        self._encrypt_option.clicked.connect(self._on_radio_selected)
        self._no_encrypt_option = QRadioButton()
        self._no_encrypt_option.setText('Disabled')
        self._no_encrypt_option.clicked.connect(self._on_radio_selected)

        self._encrypt_option_group.addButton(self._encrypt_option)
        self._encrypt_option_group.setId(self._encrypt_option, 1)
        self._encrypt_option_layout.addWidget(self._encrypt_option)

        self._encrypt_option_group.addButton(self._no_encrypt_option)
        self._encrypt_option_group.setId(self._no_encrypt_option, 0)
        self._encrypt_option_layout.addWidget(self._no_encrypt_option)

        self._encrypt_option_layout.addStretch()

        # Encryption password
        self._encrypt_password = QLineEdit()
        self._encrypt_password.setMaxLength(25)
        self._encrypt_password.setText(StringUtil.generate_random_string(6))

        # Engine options
        self._engine_option_layout = QVBoxLayout()

        # Add to layout
        self._main_layout.addRow(self._encrypt_option_label,
                                 self._encrypt_option_layout)
        self._main_layout.addRow(self._encrypt_password_label,
                                 self._encrypt_password)

        self.setLayout(self._main_layout)

    def disable_encrypt_option(self):
        self._encrypt_option_layout.removeWidget(self._encrypt_option)
        self._encrypt_option_layout.removeWidget(self._no_encrypt_option)
        label = QLabel()
        label.setText('Will be determined by file metadata')
        self._encrypt_option_layout.addWidget(label)

    def set_engine_option(self, engine_option: List[ConfigParam]):
        row_count = self._main_layout.rowCount()

        for i in range(row_count - 1, 1, -1):
            self._main_layout.removeRow(i)

        if len(engine_option) == 0:
            return

        self._state_engine_option = engine_option
        self._state_engine_option_holder.clear()

        for param in engine_option:
            engine_option_label = QLabel()
            engine_option_label.setText(param.title)

            if param.config_type == ConfigType.RADIO:
                assert isinstance(param, RadioParam)

                option_group = QButtonGroup()
                button_layout = QHBoxLayout()
                for idx, (key, value) in enumerate(param.options.items()):
                    radio_btn = QRadioButton()
                    radio_btn.setText(value)
                    if idx == 0:
                        radio_btn.setChecked(True)

                    radio_btn.clicked.connect(lambda: self.modified.emit())

                    option_group.addButton(radio_btn)
                    option_group.setId(radio_btn, idx)
                    button_layout.addWidget(radio_btn)

                self._main_layout.addRow(engine_option_label, button_layout)
                self._state_engine_option_holder.append(option_group)
            elif param.config_type == ConfigType.FLOAT:
                assert isinstance(param, FloatParam)
                spinbox = QDoubleSpinBox()
                spinbox.setValue(param.default)
                spinbox.setMinimum(0)
                spinbox.setSingleStep(param.step)
                spinbox.valueChanged.connect(lambda: self.modified.emit())
                self._state_engine_option_holder.append(spinbox)
                self._main_layout.addRow(engine_option_label, spinbox)

    @property
    def config(self) -> Tuple[str, List[Union[str, float, bool]]]:
        encryption_key = self._encrypt_password.text()

        engine_param = [self._state_use_encryption]
        for idx, param in enumerate(self._state_engine_option):
            holder = self._state_engine_option_holder[idx]
            if param.config_type == ConfigType.FLOAT:
                assert isinstance(holder, QDoubleSpinBox)
                engine_param.append(holder.value())
            else:
                assert isinstance(holder, QButtonGroup)
                assert isinstance(param, RadioParam)
                option = param.options
                engine_param.append(list(option.keys())[holder.checkedId()])

        return encryption_key, engine_param

    def _on_radio_selected(self):
        # self._encrypt_password.setDisabled(self._encrypt_option_group.checkedId() == 0)
        self._state_use_encryption = self._encrypt_option_group.checkedId(
        ) == 1
示例#37
0
class ESCPanel(QDialog):
    DEFAULT_INTERVAL = 0.1

    CMD_BIT_LENGTH = uavcan.get_uavcan_data_type(uavcan.equipment.esc.RawCommand().cmd).value_type.bitlen
    CMD_MAX = 2 ** (CMD_BIT_LENGTH - 1) - 1
    CMD_MIN = -(2 ** (CMD_BIT_LENGTH - 1))

    def __init__(self, parent, node):
        super(ESCPanel, self).__init__(parent)
        self.setWindowTitle("ESC Management Panel")
        self.setAttribute(Qt.WA_DeleteOnClose)  # This is required to stop background timers!

        self._node = node

        self._sliders = [PercentSlider(self) for _ in range(4)]

        self._num_sliders = QSpinBox(self)
        self._num_sliders.setMinimum(len(self._sliders))
        self._num_sliders.setMaximum(20)
        self._num_sliders.setValue(len(self._sliders))
        self._num_sliders.valueChanged.connect(self._update_number_of_sliders)

        self._bcast_interval = QDoubleSpinBox(self)
        self._bcast_interval.setMinimum(0.01)
        self._bcast_interval.setMaximum(1.0)
        self._bcast_interval.setSingleStep(0.1)
        self._bcast_interval.setValue(self.DEFAULT_INTERVAL)
        self._bcast_interval.valueChanged.connect(
            lambda: self._bcast_timer.setInterval(self._bcast_interval.value() * 1e3)
        )

        self._stop_all = make_icon_button(
            "hand-stop-o", "Zero all channels", self, text="Stop All", on_clicked=self._do_stop_all
        )

        self._pause = make_icon_button("pause", "Pause publishing", self, checkable=True, text="Pause")

        self._msg_viewer = QPlainTextEdit(self)
        self._msg_viewer.setReadOnly(True)
        self._msg_viewer.setLineWrapMode(QPlainTextEdit.NoWrap)
        self._msg_viewer.setFont(get_monospace_font())
        self._msg_viewer.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self._msg_viewer.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        self._bcast_timer = QTimer(self)
        self._bcast_timer.start(self.DEFAULT_INTERVAL * 1e3)
        self._bcast_timer.timeout.connect(self._do_broadcast)

        layout = QVBoxLayout(self)

        self._slider_layout = QHBoxLayout(self)
        for sl in self._sliders:
            self._slider_layout.addWidget(sl)
        layout.addLayout(self._slider_layout)

        layout.addWidget(self._stop_all)

        controls_layout = QHBoxLayout(self)
        controls_layout.addWidget(QLabel("Channels:", self))
        controls_layout.addWidget(self._num_sliders)
        controls_layout.addWidget(QLabel("Broadcast interval:", self))
        controls_layout.addWidget(self._bcast_interval)
        controls_layout.addWidget(QLabel("sec", self))
        controls_layout.addStretch()
        controls_layout.addWidget(self._pause)
        layout.addLayout(controls_layout)

        layout.addWidget(QLabel("Generated message:", self))
        layout.addWidget(self._msg_viewer)

        self.setLayout(layout)
        self.resize(self.minimumWidth(), self.minimumHeight())

    def _do_broadcast(self):
        try:
            if not self._pause.isChecked():
                msg = uavcan.equipment.esc.RawCommand()
                for sl in self._sliders:
                    raw_value = sl.get_value() / 100
                    value = (-self.CMD_MIN if raw_value < 0 else self.CMD_MAX) * raw_value
                    msg.cmd.append(int(value))

                self._node.broadcast(msg)
                self._msg_viewer.setPlainText(uavcan.to_yaml(msg))
            else:
                self._msg_viewer.setPlainText("Paused")
        except Exception as ex:
            self._msg_viewer.setPlainText("Publishing failed:\n" + str(ex))

    def _do_stop_all(self):
        for sl in self._sliders:
            sl.zero()

    def _update_number_of_sliders(self):
        num_sliders = self._num_sliders.value()

        while len(self._sliders) > num_sliders:
            removee = self._sliders[-1]
            self._sliders = self._sliders[:-1]
            self._slider_layout.removeWidget(removee)
            removee.close()
            removee.deleteLater()

        while len(self._sliders) < num_sliders:
            new = PercentSlider(self)
            self._slider_layout.addWidget(new)
            self._sliders.append(new)

        def deferred_resize():
            self.resize(self.minimumWidth(), self.height())

        deferred_resize()
        # noinspection PyCallByClass,PyTypeChecker
        QTimer.singleShot(200, deferred_resize)

    def __del__(self):
        global _singleton
        _singleton = None

    def closeEvent(self, event):
        global _singleton
        _singleton = None
        super(ESCPanel, self).closeEvent(event)
示例#38
0
class SecondTest(QWidget):
    def __init__(self):
        self.title = "test window"
        self.X = 100
        self.Y = 100
        self.Width = 300
        self.Height = 300
        super(SecondTest, self).__init__()
        self.init_window()

    def init_window(self):
        self.title = "It Is A Test Window"
        self.setWindowTitle(self.title)
        self.setGeometry(self.X, self.Y, self.Width, self.Height)
        self.create_gui()
        self.show()

    def create_gui(self):
        # creating spacer item
        self.VSpacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.HSpacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)

        self.MainLayout = QHBoxLayout()
        self.setLayout(self.MainLayout)

        # Menu Button's
        self.MenuLayout = QVBoxLayout()
        self.MainLayout.addLayout(self.MenuLayout)
        self.FirstSlide = QPushButton("First Slide")
        self.SecondSlide = QPushButton("Second Slide")
        self.ThirdSlide = QPushButton("Third Slide")
        self.FirstSlide.clicked.connect(lambda l: self.change_slide_count(1))
        self.SecondSlide.clicked.connect(lambda l: self.change_slide_count(2))
        self.ThirdSlide.clicked.connect(lambda l: self.change_slide_count(3))
        self.SlideNumber = QLabel("1..........")
        self.MenuLayout.addWidget(self.FirstSlide)
        self.MenuLayout.addWidget(self.SecondSlide)
        self.MenuLayout.addWidget(self.ThirdSlide)
        self.MenuLayout.addWidget(self.SlideNumber)
        self.MenuLayout.addItem(self.VSpacerItem)

        #self.MainSlideFrame = QFrame()
        #self.MainLayout.addWidget(self.MainSlideFrame)

        #slide 1st

        self.SlideFrame1 = QFrame()
        self.SlideLayout1 = QHBoxLayout()
        self.SlideFrame1.setLayout(self.SlideLayout1)
        button = QPushButton("111111111111111111")
        self.SlideLayout1.addWidget(button)

        # slide 2st

        self.SlideFrame2 = QFrame()
        self.SlideLayout2 = QHBoxLayout()
        self.SlideFrame2.setLayout(self.SlideLayout2)
        button = QPushButton("222222222222")
        self.SlideLayout2.addWidget(button)

        # slide 3st

        self.SlideFrame3 = QFrame()
        self.SlideLayout3 = QHBoxLayout()
        self.SlideFrame3.setLayout(self.SlideLayout3)
        button = QPushButton("333333")
        self.SlideLayout3.addWidget(button)

        #self.MainSlideFrame.setLayout(self.SlideLayout1)
        #self.LastSlide = self.SlideLayout1
        self.MainLayout.addWidget(self.SlideFrame1)
        self.MainLayout.addWidget(self.SlideFrame2)
        self.MainLayout.addWidget(self.SlideFrame3)


    def change_slide_count1(self, slide):
        if slide == 1:
            print(self.MainLayout)
            self.MainLayout.removeWidget(self.LastSlide)

            self.LastSlide = self.SlideFrame1
            self.MainLayout.addWidget(self.SlideFrame1)
            self.SlideNumber.setText("1.....")
        elif slide == 2:
            self.MainLayout.removeWidget(self.LastSlide)
            self.LastSlide = self.SlideFrame2
            self.MainLayout.addWidget(self.SlideFrame2)
            self.SlideNumber.setText("2.....")
        elif slide == 3:
            self.MainLayout.removeWidget(self.LastSlide)
            self.LastSlide = self.SlideFrame3
            self.MainLayout.addWidget(self.SlideFrame3)
            self.SlideNumber.setText("3.....")

    def change_slide_count2(self, slide):
        if slide == 1:
            self.MainSlideFrame.setLayout(self.SlideLayout1)
            self.SlideNumber.setText("1.....")
        if slide == 2:
            self.MainSlideFrame.setLayout(self.SlideLayout2)
            self.SlideNumber.setText("2.....")
        if slide == 3:
            self.MainSlideFrame.setLayout(self.SlideLayout3)
            self.SlideNumber.setText("3.....")

    def change_slide_count(self, slide):
        if slide == 1:
            self.SlideFrame1.show()
            self.SlideFrame2.hide()
            self.SlideFrame3.hide()
        if slide == 2:
            self.SlideFrame2.show()
            self.SlideFrame3.hide()
            self.SlideFrame1.hide()
        if slide == 3:
            self.SlideFrame3.show()
            self.SlideFrame2.hide()
            self.SlideFrame1.hide()