def __init__(self, parent, xml):
        super().__init__(parent)
        self.setWindowTitle("Information")

        tree = QTreeWidget()
        tree.setColumnCount(2)
        tree.setHeaderLabels(["Name", "Value"])
        tree.setColumnWidth(0, 200)
        tree.setColumnWidth(1, 350)

        for stream in xml:
            header = xml[stream][2]
            header.tag = "Header"
            footer = xml[stream][6]
            footer.tag = "Footer"

            root = et.Element(f"Stream {stream}")
            root.extend([header, footer])
            populate_tree(tree, root)

        tree.expandAll()

        vbox = QVBoxLayout(self)
        vbox.addWidget(tree)
        buttonbox = QDialogButtonBox(QDialogButtonBox.Ok)
        vbox.addWidget(buttonbox)
        buttonbox.accepted.connect(self.accept)

        self.resize(650, 550)
Beispiel #2
0
class Editor(QDialog):
    """Basic scene editor."""
    def __init__(self, parent: MainWindow, renderers: List[Renderer]) -> None:
        """Initialize the Editor."""
        super().__init__(parent=parent)
        self.renderers = renderers

        self.tree_widget = QTreeWidget()
        self.tree_widget.setHeaderHidden(True)
        self.stacked_widget = QStackedWidget()
        self.layout = QHBoxLayout()
        self.layout.addWidget(self.tree_widget)
        self.layout.addWidget(self.stacked_widget)

        def _selection_callback() -> None:
            for item in self.tree_widget.selectedItems():
                widget_idx = item.data(0, Qt.ItemDataRole.UserRole)
                self.stacked_widget.setCurrentIndex(widget_idx)

        self.tree_widget.itemSelectionChanged.connect(_selection_callback)

        self.setLayout(self.layout)
        self.setWindowTitle("Editor")
        self.setModal(True)

        self.update()

    def update(self) -> None:
        """Update the internal widget list."""
        self.tree_widget.clear()
        for idx, renderer in enumerate(self.renderers):
            actors = renderer._actors  # pylint: disable=protected-access
            widget_idx = self.stacked_widget.addWidget(
                _get_renderer_widget(renderer))
            top_item = QTreeWidgetItem(self.tree_widget,
                                       ["Renderer {}".format(idx)])
            top_item.setData(0, Qt.ItemDataRole.UserRole, widget_idx)
            self.tree_widget.addTopLevelItem(top_item)
            for name, actor in actors.items():
                if actor is not None:
                    widget_idx = self.stacked_widget.addWidget(
                        _get_actor_widget(actor))
                    child_item = QTreeWidgetItem(top_item, [name])
                    child_item.setData(0, Qt.ItemDataRole.UserRole, widget_idx)
                    top_item.addChild(child_item)
        self.tree_widget.expandAll()

    def toggle(self) -> None:
        """Toggle the editor visibility."""
        self.update()
        if self.isVisible():
            self.hide()
        else:
            self.show()
Beispiel #3
0
    def __init__(self, parent: QWidget, filename: str, torrent_info: TorrentInfo,
                 control_thread: 'ControlManagerThread'):
        super().__init__(parent)
        self._torrent_info = torrent_info
        download_info = torrent_info.download_info
        self._control_thread = control_thread
        self._control = control_thread.control

        vbox = QVBoxLayout(self)

        self._download_dir = get_directory(self._control.last_download_dir)
        vbox.addWidget(QLabel('Download directory:'))
        vbox.addWidget(self._get_directory_browse_widget())
        #tracker lists..
        vbox.addWidget(QLabel('Announce URLs:'))

        url_tree = QTreeWidget()
        url_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        url_tree.header().close()
        vbox.addWidget(url_tree)
        for i, tier in enumerate(torrent_info.announce_list):
            tier_item = QTreeWidgetItem(url_tree)
            #level 1 urls
            tier_item.setText(0, 'Tier {}'.format(i + 1))
            for url in tier:
                url_item = QTreeWidgetItem(tier_item)
                url_item.setText(0, url)
        url_tree.expandAll()
        vbox.addWidget(url_tree, 1)

        file_tree = QTreeWidget()
        file_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        file_tree.setHeaderLabels(('Name', 'Size'))
        file_tree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents)
        self._file_items = []
        self._traverse_file_tree(download_info.suggested_name, download_info.file_tree, file_tree)
        file_tree.sortItems(0, Qt.AscendingOrder)
        file_tree.expandAll()
        file_tree.itemClicked.connect(self._update_checkboxes)
        vbox.addWidget(file_tree, 3)

        self._selection_label = QLabel(TorrentAddingDialog.SELECTION_LABEL_FORMAT.format(
            len(download_info.files), humanize_size(download_info.total_size)))
        vbox.addWidget(self._selection_label)

        self._button_box = QDialogButtonBox(self)
        self._button_box.setOrientation(Qt.Horizontal)
        self._button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self._button_box.button(QDialogButtonBox.Ok).clicked.connect(self.submit_torrent)
        self._button_box.button(QDialogButtonBox.Cancel).clicked.connect(self.close)
        vbox.addWidget(self._button_box)

        self.setFixedSize(470, 550)
        self.setWindowTitle('Adding "{}"'.format(filename))
Beispiel #4
0
    def __init__(self, parent: QWidget, filename: str, torrent_info: TorrentInfo,
                 control_thread: 'ControlManagerThread'):
        super().__init__(parent)
        self._torrent_info = torrent_info
        download_info = torrent_info.download_info
        self._control_thread = control_thread
        self._control = control_thread.control

        vbox = QVBoxLayout(self)

        self._download_dir = get_directory(self._control.last_download_dir)
        vbox.addWidget(QLabel('Download directory:'))
        vbox.addWidget(self._get_directory_browse_widget())

        vbox.addWidget(QLabel('Announce URLs:'))

        url_tree = QTreeWidget()
        url_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        url_tree.header().close()
        vbox.addWidget(url_tree)
        for i, tier in enumerate(torrent_info.announce_list):
            tier_item = QTreeWidgetItem(url_tree)
            tier_item.setText(0, 'Tier {}'.format(i + 1))
            for url in tier:
                url_item = QTreeWidgetItem(tier_item)
                url_item.setText(0, url)
        url_tree.expandAll()
        vbox.addWidget(url_tree, 1)

        file_tree = QTreeWidget()
        file_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        file_tree.setHeaderLabels(('Name', 'Size'))
        file_tree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents)
        self._file_items = []
        self._traverse_file_tree(download_info.suggested_name, download_info.file_tree, file_tree)
        file_tree.sortItems(0, Qt.AscendingOrder)
        file_tree.expandAll()
        file_tree.itemClicked.connect(self._update_checkboxes)
        vbox.addWidget(file_tree, 3)

        self._selection_label = QLabel(TorrentAddingDialog.SELECTION_LABEL_FORMAT.format(
            len(download_info.files), humanize_size(download_info.total_size)))
        vbox.addWidget(self._selection_label)

        self._button_box = QDialogButtonBox(self)
        self._button_box.setOrientation(Qt.Horizontal)
        self._button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        self._button_box.button(QDialogButtonBox.Ok).clicked.connect(self.submit_torrent)
        self._button_box.button(QDialogButtonBox.Cancel).clicked.connect(self.close)
        vbox.addWidget(self._button_box)

        self.setFixedSize(450, 550)
        self.setWindowTitle('Adding "{}"'.format(filename))
Beispiel #5
0
class BasicTreeWidgetDemo(QMainWindow):

    def __init__(self, parent=None):
        super(BasicTreeWidgetDemo, self).__init__(parent)
        self.tree = QTreeWidget()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('QTreeWidget控件')
        self.resize(500, 400)

        # 指定列数
        self.tree.setColumnCount(2)

        # 指定列标签
        self.tree.setHeaderLabels(['key', 'value'])

        # 绑定事件
        self.tree.clicked.connect(self.clicked)

        # 根节点
        root = QTreeWidgetItem(self.tree)
        root.setText(0, '根')    # 设置文本
        root.setIcon(0, QIcon('./img/root.png'))  # 设置图标
        self.tree.setColumnWidth(0, 220)    # 设置列宽

        # 添加子节点
        child1 = QTreeWidgetItem(root)
        child1.setText(0, '子节点1')
        child1.setText(1, '这是子节点1')
        child1.setIcon(0, QIcon('./img/child1.png'))
        child1.setCheckState(0, Qt.Checked)     # 设置复选框

        # 添加子节点
        child2 = QTreeWidgetItem(root)
        child2.setText(0, '子节点2')
        child2.setText(1, '这是子节点2')
        child2.setIcon(0, QIcon('./img/child2.png'))

        # 添加孙节点
        g_child = QTreeWidgetItem(child2)
        g_child.setText(0, '孙节点1')
        g_child.setText(1, '孙节点1的值')
        g_child.setIcon(0, QIcon('./img/gChild.png'))

        # 展开所有节点
        self.tree.expandAll()
        self.setCentralWidget(self.tree)

    def clicked(self, item):
        pass
Beispiel #6
0
class Example(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.tree = QTreeWidget(self)
        self.tree.setColumnCount(2)
        self.tree.setHeaderLabels(["key","values"])

        root = QTreeWidgetItem()
        root.setText(0,"root")
        root.setCheckState(0, Qt.Checked)
        child1 = QTreeWidgetItem(root)
        child1.setText(0, 'child1')
        child1.setText(1, 'ios')
        child1.setCheckState(0, Qt.Checked)
        # root.addChild(child1)

        child2 = QTreeWidgetItem(root)
        child2.setText(0, 'child2')
        child2.setText(1, '')
        child2.setCheckState(0, Qt.Checked)


        child3 = QTreeWidgetItem(child2)
        child3.setText(0, 'child3')
        child3.setText(1, 'android')


        self.tree.addTopLevelItem(root)
        self.tree.expandAll()
        # self.setCentralWidget(self.tree)

        self.tree.clicked.connect(self.onClicked)


        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('QTreeWidget')
        self.show()



    def onClicked(self, qmodeLindex):
        item = self.tree.currentItem()
        print('Key=%s,value=%s,parent=%s,index=%s' % (item.text(0), item.text(1),item.parent().text(0),item.parent().indexOfChild(item)))
class InfoDialog(QDialog):
    def __init__(self, parent, info, title):
        super().__init__(parent)

        self.setWindowTitle(
            translate('MediaInfo', 'Media Info') + ' - ' + title)
        self.setWindowModality(QtCore.Qt.ApplicationModal)
        self.setMinimumSize(550, 300)
        self.resize(550, 500)

        self.vLayout = QVBoxLayout(self)

        self.infoTree = QTreeWidget(self)
        self.infoTree.setColumnCount(2)
        self.infoTree.setHeaderLabels(
            [translate('MediaInfo', 'Info'),
             translate('MediaInfo', 'Value')])
        self.infoTree.setAlternatingRowColors(True)
        self.infoTree.setSelectionMode(QAbstractItemView.NoSelection)
        self.infoTree.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.infoTree.header().setStretchLastSection(False)
        self.infoTree.header().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.vLayout.addWidget(self.infoTree)

        self.__generate_items(info)
        self.infoTree.expandAll()

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Close)
        self.vLayout.addWidget(self.buttonBox)

        self.buttonBox.rejected.connect(self.close)

    def __generate_items(self, info, parent=None):
        for key in sorted(info.keys()):
            if isinstance(info[key], dict):
                widget = QTreeWidgetItem([key])
                self.__generate_items(info[key], widget)
            else:
                widget = QTreeWidgetItem([key, info[key]])

            if parent is not None:
                parent.addChild(widget)
            else:
                self.infoTree.addTopLevelItem(widget)
class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(500, 300)  # 1
        self.tree = QTreeWidget(self)  # 2
        self.tree.setColumnCount(2)
        self.tree.setHeaderLabels(['Item', 'Path'])
        #self.tree.itemClicked.connect(self.change_func)#点击触发槽函数

        self._1stlevel = []
        self._2stlevel = []
        self._3stlevel = []
        self._4stlevel = []
        self._5stlevel = []
        self._6stlevel = []

        self.tree.expandAll()
        self.h_layout = QHBoxLayout()  #页面布局
        self.h_layout.addWidget(self.tree)
        #        self.h_layout.addWidget(self.label)
        self.setLayout(self.h_layout)

    def tree_process(self, path_list):
        path_root = path_list[0]
        self._1stlevel = QTreeWidgetItem(self.tree)
        first_item = path_root.split('\\')  # 3
        self._1stlevel.setText(0, first_item[-1])
        self._1stlevel.setCheckState(0, Qt.Unchecked)
        self._1stlevel.setText(1, path_root)
        #显示根目录下文件
        if path_list[1] != []:
            for files in path_list[1]:
                item = QTreeWidgetItem(self._1stlevel)
                item.setText(0, files)

        for item_tmp in path_list[2::2]:
            folder = item_tmp.split('\\')
            if folder.__len__ > first_item.__len__:
                self._2stlevel = QTreeWidgetItem()
                self._2stlevel.setText(0, folder[-1])
                self._2stlevel.setText(1, item_tmp)
                self._2stlevel.setCheckState(0, Qt.Unchecked)
                self._1stlevel.addChild(self._2stlevel)
Beispiel #9
0
 def setTreeWidgetJsonData(treeWidget: QTreeWidget, data={}, isExpand=True):
     """
     给TreeWidget设置数据
     :param treeWidget: TreeWidget
     :param data: json数据
     :param isExpand: isExpand是否全部展开
     """
     treeWidget.clear()
     root = None
     if DataTypeUtil.isDict(data):
         root = WidgetUtil.createTreeWidgetItem("{}")
     elif DataTypeUtil.isList(data):
         root = WidgetUtil.createTreeWidgetItem("[]")
     else:
         print("data is not json data")
         return
     items = WidgetUtil.createTreeWidgetItems(data)
     root.addChildren(items)
     treeWidget.addTopLevelItem(root)
     if isExpand:
         treeWidget.expandAll()
     pass
Beispiel #10
0
class EditFilesDialog:
    def __init__(self, model, owner_object):
        self.model = model
        self.__owner_object = owner_object

        self.__added_files = []

        self.__window = QDialog()
        layout = QVBoxLayout()
        self.__window.setLayout(layout)

        button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                      | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self.__window.accept)
        button_box.rejected.connect(self.__window.reject)

        self.__group_widget = QComboBox()
        self.__group_widget.addItem("- all -", None)
        for teacher in model.subject.teachers:
            for group in teacher.taught_groups:
                self.__group_widget.addItem(group.moodle_name, group)
        layout.addWidget(self.__group_widget)

        self.__files_widget = QTreeWidget()
        self.__files_widget.setHeaderHidden(True)
        layout.addWidget(self.__files_widget)

        layout.addWidget(button_box)

        self.__refresh_students()
        self.__group_widget.currentIndexChanged.connect(
            lambda *args: self.__refresh_students())

    def __refresh_students(self):
        self.__files_widget.clear()

        group = self.__group_widget.itemData(
            self.__group_widget.currentIndex())
        if group is None:
            students = self.model.subject.students
        else:
            students = list(group.get_students())

        for no, student in enumerate(students):
            name_item = QTreeWidgetItem()
            self.__files_widget.addTopLevelItem(name_item)
            name_widget = QWidget()
            name_layout = QHBoxLayout()
            name_layout.setAlignment(Qt.AlignLeft)
            name_layout.setContentsMargins(0, 0, 0, 0)
            name_layout.addWidget(QLabel(f"{student.name} {student.surname}"))
            add_button = QPushButton("Add")
            add_button.clicked.connect(
                partial(self.__choose_and_add_file, name_item, student))
            name_layout.addWidget(add_button)
            name_widget.setLayout(name_layout)
            self.__add_files(student.get_points_for(self.__owner_object),
                             name_item)
            self.__files_widget.setItemWidget(name_item, 0, name_widget)

        self.__files_widget.expandAll()

    def __add_files(self, points_object, parent_item):
        if points_object is None:
            return
        for file in points_object.files:
            self.__add_one_file(file, parent_item, False)

    def __add_one_file(self, file, parent_item, changed):
        file_item = QTreeWidgetItem([file.file_name])
        file_item.setIcon(0, fip.icon(QFileInfo(file.file_name)))
        if changed:
            file_item.setBackground(0, QBrush(QColor(255, 255, 0)))
        parent_item.addChild(file_item)

    def __choose_and_add_file(self, parent_item, student, *args):
        file_name, filter = QFileDialog.getOpenFileName(self.__window,
                                                        caption="Add File")

        if file_name:
            file = ExternalFile(file_name)
            self.__added_files.append((student, file))
            self.__add_one_file(file, parent_item, True)

    def run(self):
        if self.__window.exec() == QDialog.Accepted:
            for student, file in self.__added_files:
                student.add_file_for(self.__owner_object, file)
            self.model.data_edited()
class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.resize(500, 300)
        self.label = QLabel('No Click')                         # 1

        self.tree = QTreeWidget(self)                           # 2
        self.tree.setColumnCount(2)
        self.tree.setHeaderLabels(['Install Components', 'Test'])
        self.tree.itemClicked.connect(self.change_func)

        self.preview = QTreeWidgetItem(self.tree)               # 3
        self.preview.setText(0, 'Preview')

        # self.preview = QTreeWidgetItem()
        # self.preview.setText(0, 'Preview')
        # self.tree.addTopLevelItem(self.preview)

        self.qt5112 = QTreeWidgetItem()                         # 4
        self.qt5112.setText(0, 'Qt 5.11.2 snapshot')
        self.qt5112.setCheckState(0, Qt.Unchecked)
        self.preview.addChild(self.qt5112)

        choice_list = ['macOS', 'Android x86',
                       'Android ARMv7', 'Sources', 'iOS']
        self.item_list = []
        for i, c in enumerate(choice_list):                     # 5
            item = QTreeWidgetItem(self.qt5112)
            item.setText(0, c)
            item.setCheckState(0, Qt.Unchecked)
            self.item_list.append(item)

        self.test_item = QTreeWidgetItem(self.qt5112)           # 6
        self.test_item.setText(0, 'test1')
        self.test_item.setText(1, 'test2')

        self.tree.expandAll()                                   # 7

        self.h_layout = QHBoxLayout()
        self.h_layout.addWidget(self.tree)
        self.h_layout.addWidget(self.label)
        self.setLayout(self.h_layout)

    def change_func(self, item, column):
        self.label.setText(item.text(column))                   # 8

        print(item.text(column))
        print(column)
        if item == self.qt5112:                                 # 9
            if self.qt5112.checkState(0) == Qt.Checked:
                [x.setCheckState(0, Qt.Checked) for x in self.item_list]
            else:
                [x.setCheckState(0, Qt.Unchecked) for x in self.item_list]
        else:                                                   # 10
            check_count = 0
            for x in self.item_list:
                if x.checkState(0) == Qt.Checked:
                    check_count += 1

            if check_count == 5:
                self.qt5112.setCheckState(0, Qt.Checked)
            elif 0 < check_count < 5:
                self.qt5112.setCheckState(0, Qt.PartiallyChecked)
            else:
                self.qt5112.setCheckState(0, Qt.Unchecked)
Beispiel #12
0
class MenuEditor(AnimateableEditor):
    contentChanged = pyqtSignal(object)
    menuChanged = pyqtSignal(str)

    def __init__(self, win, menu, site):
        AnimateableEditor.__init__(self)
        self.win = win
        self.menu = menu
        self.site = site
        self.changed = False

        self.setAutoFillBackground(True)

        titleLabel = QLabel("Menu Editor")
        fnt = titleLabel.font()
        fnt.setPointSize(20)
        fnt.setBold(True)
        titleLabel.setFont(fnt)

        self.close = FlatButton(":/images/close_normal.png",
                                ":/images/close_hover.png")
        self.close.setToolTip("Close Content Editor")
        self.undo = FlatButton(":/images/undo_normal.png",
                               ":/images/undo_hover.png", "",
                               ":/images/undo_disabled.png")
        self.redo = FlatButton(":/images/redo_normal.png",
                               ":/images/redo_hover.png", "",
                               ":/images/redo_disabled.png")
        self.undo.setToolTip("Undo")
        self.redo.setToolTip("Redo")
        self.undo.setEnabled(False)
        self.redo.setEnabled(False)
        hbox = QHBoxLayout()
        hbox.addStretch(0)
        hbox.addWidget(self.undo)
        hbox.addWidget(self.redo)
        hbox.addWidget(self.close)

        addButton = QPushButton("Add Menuitem")
        addButton.setMaximumWidth(120)

        self.name = QLineEdit()
        self.name.setText(menu.name)
        self.name.setMaximumWidth(200)

        labels = ["Title", "Url", "Icon", "", "Sort"]

        self.tree = QTreeWidget()
        self.tree.setHeaderLabels(labels)
        self.tree.header().setSectionResizeMode(0, QHeaderView.Stretch)
        self.tree.header().hideSection(4)
        self.tree.setSelectionMode(QAbstractItemView.NoSelection)
        self.tree.setToolTip("Double Click To Edit")
        self.tree.setColumnWidth(2, 40)

        layout = QGridLayout()
        layout.addWidget(titleLabel, 0, 0)
        layout.addLayout(hbox, 0, 2)
        layout.addWidget(QLabel("Name"), 1, 0)
        layout.addWidget(self.name, 2, 0)
        layout.addWidget(addButton, 3, 0)
        layout.addWidget(self.tree, 4, 0, 1, 3)
        self.setLayout(layout)

        self.reloadMenu(menu)

        addButton.clicked.connect(self.addButtonClicked)
        self.close.clicked.connect(self.closeEditor)
        self.name.editingFinished.connect(self.nameChanged)
        self.redo.clicked.connect(self.redoEdit)
        self.undo.clicked.connect(self.undoEdit)
        self.tree.itemChanged.connect(self.itemChanged)

    def reloadMenu(self, menu):
        if not menu:
            self.close.emit()
            return

        self.menu = menu
        self.tree.clear()

        self.name.setText(menu.name)
        for i in range(0, len(self.menu.items)):
            item = self.menu.items[i]
            self.addTreeItem(item)

        self.tree.expandAll()
        self.tree.sortItems(4, Qt.AscendingOrder)
        self.updateButtonStates()

    def addTreeItem(self, item):
        twi = QTreeWidgetItem()
        twi.setFlags(twi.flags() | Qt.ItemIsEditable)
        twi.setText(0, item.title)
        twi.setText(1, item.url)

        twi.setText(4, str(self.tree.topLevelItemCount()))
        twi.setData(0, Qt.UserRole, item)
        self.tree.addTopLevelItem(twi)
        self.addTableCellButtons(item, twi)

        for i in range(len(item.items)):
            sub = item.items[i]
            stwi = QTreeWidgetItem()
            stwi.setFlags(stwi.flags() | Qt.ItemIsEditable)
            stwi.setText(0, sub.title)
            stwi.setText(1, sub.url)
            stwi.setText(4, str(i))
            stwi.setData(0, Qt.UserRole, sub)
            twi.addChild(stwi)
            self.addTableCellButtons(sub, stwi)

    def addTableCellButtons(self, item, twi):
        tcb = MenuEditorTableCellButtons()
        tcb.setMenuItem(item)
        self.tree.setItemWidget(twi, 3, tcb)
        self.tree.setColumnWidth(3, tcb.sizeHint().width())
        if item.isSubitem():
            tcb.deleteItem.connect(self.deleteSubItem)
            tcb.itemLeft.connect(self.itemLeft)
        else:
            tcb.deleteItem.connect(self.deleteItem)
            tcb.itemUp.connect(self.itemUp)
            tcb.itemDown.connect(self.itemDown)
            tcb.itemRight.connect(self.itemRight)
            tcb.editItem.connect(self.editItem)

        imgs = ImageSelector()
        imgs.setToolTip("Click to select image, right click to reset image")
        imgs.setItem(item)
        imgs.setMaximumSize(24, 24)
        isw = QWidget()
        vbox = QVBoxLayout()
        vbox.addWidget(imgs)
        isw.setLayout(vbox)
        if not item.icon:
            imgs.setImage(QImage(":/images/image_placeholder.png"))
        else:
            imgs.setImage(QImage(self.site.source_path + "/" + item.icon))
        self.tree.setItemWidget(twi, 2, isw)
        imgs.clicked.connect(self.iconClicked)

    def registerUndoStack(self, stack):
        self.undoStack = stack
        self.undoStack.canUndoChanged.connect(self.canUndoChanged)
        self.undoStack.canRedoChanged.connect(self.canRedoChanged)
        self.undoStack.undoTextChanged.connect(self.undoTextChanged)
        self.undoStack.redoTextChanged.connect(self.redoTextChanged)
        self.undo.setEnabled(self.undoStack.canUndo())
        self.redo.setEnabled(self.undoStack.canRedo())
        self.undo.setToolTip("Undo " + self.undoStack.undoText())
        self.redo.setToolTip("Redo " + self.undoStack.redoText())

    def canUndoChanged(self, can):
        self.undo.setEnabled(can)

    def canRedoChanged(self, can):
        self.redo.setEnabled(can)

    def undoTextChanged(self, text):
        self.undo.setToolTip("Undo " + text)

    def redoTextChanged(self, text):
        self.redo.setToolTip("Redo " + text)

    def getUndoRedoText(self, item, action):
        return "menuitem (" + item.title + ") from menu (" + self.menu.name + ") " + action

    def undoEdit(self):
        self.undoStack.undo()

    def redoEdit(self):
        self.undoStack.redo()

    def addButtonClicked(self):
        menuitem = MenuItem()
        self.menu.addMenuitem(menuitem)
        self.addTreeItem(menuitem)
        self.menuChanged.emit(self.getUndoRedoText(menuitem, "added"))

        self.updateButtonStates()
        item = self.tree.topLevelItem(self.getRow(menuitem))
        self.tree.editItem(item, 0)

    def closeEditor(self):
        self.closes.emit()

    def nameChanged(self):
        if self.menu.name != self.name.text:
            action = "menu name changed from \"" + self.menu.name + "\" to \"" + self.name.text + "\""
            self.menu.setName(self.name.text())
            self.contentChanged.emit(self.menu)
            self.menuChanged.emit(action)

    def itemChanged(self, twi, column):
        action = ""
        item = twi.data(0, Qt.UserRole)
        if column == 0:
            item.title = twi.text(0)
            action = "title changed"
        elif column == 1:
            item.url = twi.text(1)
            action = "url changed"
        self.menuChanged.emit(self.getUndoRedoText(item, action))

    def getRow(self, menuitem):
        for i in range(0, self.tree.topLevelItemCount()):
            item = self.tree.topLevelItem(i)
            mi = item.data(0, Qt.UserRole)
            if mi == menuitem:
                return i
        return -1

    def deleteSubItem(self, menuitem):
        row = self.getRow(menuitem.parentItem)
        parent = self.tree.topLevelItem(row)
        if parent:
            for i in range(0, parent.childCount()):
                child = parent.child(i)
                mi = child.data(0, Qt.UserRole)
                if mi == menuitem:
                    parent.removeChild(child)
                    del child
                    break

        if menuitem.parentItem:
            menuitem.parentItem.removeMenuitem(menuitem)

        self.updateButtonStates()
        self.menuChanged.emit(self.getUndoRedoText(menuitem, "deleted"))

    def itemLeft(self, menuitem):
        row = self.getRow(menuitem.parentItem())
        parent = self.tree.topLevelItem(row)
        for i in range(parent.childCount()):
            child = parent.child(i)
            mi = child.data(0, Qt.UserRole)
            if mi == menuitem:
                menuitem.parentItem().removeMenuitem(menuitem)
                menuitem.setSubitem(False)
                self.menu.addMenuitem(menuitem)
                parent.takeChild(i)
                self.addTreeItem(menuitem)
                break

        self.updateButtonStates()
        self.menuChanged.emit(
            self.getUndoRedoText(menuitem, "changed to top item"))

    def iconClicked(self, itemselector, button):
        mi = itemselector.item()
        action = ""
        if button == Qt.LeftButton:
            fileName = ""
            dialog = QFileDialog()
            dialog.setFileMode(QFileDialog.AnyFile)
            dialog.setNameFilter("Images (*.png *.gif *.jpg)All (*)")
            dialog.setWindowTitle("Load Image")
            dialog.setOption(QFileDialog.DontUseNativeDialog, True)
            dialog.setAcceptMode(QFileDialog.AcceptOpen)
            if dialog.exec_():
                fileName = dialog.selectedFiles().first()
            del dialog
            if not fileName:
                return

            # copy file to assets dir
            info = QFileInfo(fileName)
            name = info.fileName().replace(" ", "_")
            path = self.site.source_path + "/assets/images/" + name
            QFile.copy(fileName, path)

            # also copy file to deploy dir for previews
            dpath = self.site.deploy_path + "/assets/images/" + name
            QFile.copy(fileName, dpath)

            mi.setIcon(path.mid(path.indexOf("assets/images/")))
            itemselector.setImage(QImage(path))
            action = "icon changed"

        elif button == Qt.RightButton:
            action = "icon removed"
            mi.setIcon("")
            itemselector.setImage(QImage(":/images/image_placeholder.png"))

        self.menuChanged.emit(self.getUndoRedoText(mi, action))

    def updateButtonStates(self):
        for i in range(0, self.tree.topLevelItemCount()):
            twi = self.tree.topLevelItem(i)
            tcb = self.tree.itemWidget(twi, 3)
            menuitem = twi.data(0, Qt.UserRole)
            tcb.setEnableDown(i != self.tree.topLevelItemCount() - 1)
            tcb.setEnableUp(i != 0)
            tcb.setEnableRight(i != 0 and len(menuitem.items) == 0)
            tcb.setEnableLeft(False)
            for j in range(0, twi.childCount()):
                stwi = twi.child(j)
                stcb = self.tree.itemWidget(stwi, 3)
                stcb.setEnableLeft(True)
Beispiel #13
0
class HomeWorksTab:
    model: GuiModel

    def __init__(self, model):
        self.__home_work_list = QTreeWidget()
        self.__home_work_list.setHeaderLabel("Name")
        self.__home_work_list.itemSelectionChanged.connect(
            self.__home_work_selected)
        self.__home_work_list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.__home_work_list.customContextMenuRequested.connect(
            self.__home_work_context_menu)

        self.__home_work_details = QTreeWidget()
        self.__home_work_details.setColumnCount(2)
        self.__home_work_details.setHeaderLabels(["Student", "Points"])
        self.__home_work_details.itemActivated.connect(
            lambda item, column: file_double_clicked(self.model, item))
        self.__home_work_details.itemSelectionChanged.connect(
            self.__home_work_file_selected)

        self.__home_work_file_details = FileDetailsWidget(model)

        details_splitter = QSplitter(Qt.Horizontal)
        details_splitter.addWidget(self.__home_work_details)
        details_splitter.addWidget(self.__home_work_file_details.widget)

        self.widget = QSplitter(Qt.Vertical)
        self.widget.addWidget(self.__home_work_list)
        self.widget.addWidget(details_splitter)
        self.widget.setStretchFactor(0, 3)
        self.widget.setStretchFactor(1, 1)

        self.model = model
        self.__load_home_works()

        self.model.subject_changed.connect(self.__subject_changed)

    def __subject_changed(self):
        self.__load_home_works()

    def __load_home_works(self):
        self.__home_work_list.clear()
        self.__home_work_details.clear()
        self.__home_work_file_details.master_selection_changed([])

        if self.model.subject is not None:
            for category in self.model.subject.home_work_categories:
                category_item = QTreeWidgetItem([category.name])
                self.__home_work_list.addTopLevelItem(category_item)

                for home_work in category.home_works:
                    home_work_item = HomeWorkItem([home_work.name], home_work)
                    category_item.addChild(home_work_item)

        self.__home_work_list.expandAll()

    def __home_work_selected(self):
        self.__home_work_details.clear()
        self.__home_work_file_details.master_selection_changed([])

        home_work_items = self.__home_work_list.selectedItems()
        if home_work_items and isinstance(home_work_items[0], HomeWorkItem):
            home_work: HomeWork = home_work_items[0].home_work

            for home_work_points in home_work.get_submissions():
                student_item = StudentItem([
                    f"{home_work_points.student.surname} {home_work_points.student.name}",
                    points_or_none(home_work_points.points)
                ], home_work_points.student)

                self.__home_work_details.addTopLevelItem(student_item)
                add_file_items(home_work_points.files, student_item)

            self.__home_work_details.expandAll()

    def __home_work_file_selected(self):
        self.__home_work_file_details.master_selection_changed(
            self.__home_work_details.selectedItems())

    def __home_work_context_menu(self, pos):
        item = self.__home_work_list.itemAt(pos)

        if isinstance(item, HomeWorkItem):
            menu = QMenu()
            menu.addAction("Edit points...").triggered.connect(
                lambda *args: EditPointsDialog(self.model, item.home_work).run(
                ))
            menu.addAction("Edit files...").triggered.connect(
                lambda *args: EditFilesDialog(self.model, item.home_work).run(
                ))
            menu.exec(self.__home_work_list.viewport().mapToGlobal(pos))
Beispiel #14
0
class TemplateManagementTab(QWidget):
    def __init__(self, obj_mng: ObjectManager, tpl_mng: TemplateManager,
                 sgn_mng: SignageManager, mtm_mng: MultimediaManager,
                 chn_mng: ChannelManager):
        super().__init__()

        self._obj_mng = obj_mng
        self._tpl_mng = tpl_mng
        self._sgn_mng = sgn_mng
        self._mtm_mng = mtm_mng
        self._chn_mng = chn_mng
        self._multimedia_list = QTreeWidget()

        self._res = ResourceManager()

        def template_change_handler(change_type: utils.ChangeType,
                                    tpl_text: str = ''):
            get_selected = self._multimedia_list.selectedItems()
            if get_selected:
                item = get_selected[0]
                if change_type == utils.ChangeType.DELETE:
                    parent = item.parent()
                    parent.removeChild(item)

        self._template_widget = TemplateWidget(self._tpl_mng,
                                               template_change_handler)
        self.init_ui()

    def template_to_tree_item(self) -> [QTreeWidgetItem]:
        frame_label_item = QTreeWidgetItem([self._res['frameLabel']])
        for frame_tpl_id in self._tpl_mng.frame_templates.keys():
            frame_tpl = self._tpl_mng.get_frame_template(frame_tpl_id)
            frame_text = utils.gen_ui_text(frame_tpl.definition.name,
                                           frame_tpl.id)
            frame_item = QTreeWidgetItem([frame_text])
            frame_label_item.addChild(frame_item)

        scene_label_item = QTreeWidgetItem([self._res['sceneLabel']])
        for scene_tpl_id in self._tpl_mng.scene_templates.keys():
            scene_tpl = self._tpl_mng.get_scene_template(scene_tpl_id)
            scene_text = utils.gen_ui_text(scene_tpl.definition.name,
                                           scene_tpl.id)
            scene_item = QTreeWidgetItem([scene_text])
            scene_label_item.addChild(scene_item)
        return [frame_label_item, scene_label_item]

    def init_ui(self) -> None:
        # Left side of screen
        self._multimedia_list.setHeaderLabel(self._res['templateListLabel'])
        self._multimedia_list.addTopLevelItems(self.template_to_tree_item())
        self._multimedia_list.expandAll()
        self._multimedia_list.itemSelectionChanged.connect(
            self.list_item_clicked)

        # Gather altogether
        hbox_outmost = QHBoxLayout()
        hbox_outmost.addWidget(self._multimedia_list, 1)
        hbox_outmost.addWidget(self._template_widget, 4)
        self.setLayout(hbox_outmost)

    def list_item_clicked(self) -> None:
        get_selected = self.sender().selectedItems()
        if get_selected:
            item = get_selected[0]
            item_text = item.text(0)
            if item.parent() is None:
                # It is at topmost level
                # Selected one is Scene/Frame
                self._template_widget.clear_data_on_ui()
            else:
                # Selected one is frame/scene
                tpl_id = utils.ui_text_to_id(item_text)
                if item.parent().text(0) == self._res['frameLabel']:
                    # Selected one is frame template
                    tpl = self._tpl_mng.get_frame_template(tpl_id)
                else:
                    # Selected one is scene template
                    tpl = self._tpl_mng.get_scene_template(tpl_id)
                self._template_widget.load_data_on_ui(tpl)
class TorrentPreferencesDialog(QDialog):
    dataReady = pyqtSignal(dict)

    def __init__(self, parent, torrent_info):
        super().__init__(parent)
        self.torrentInfo = torrent_info

        self.setUp()

    def setUp(self):
        self.setWindowTitle("Torrent settings")

        parentRect = self.parentWidget().geometry()
        self.resize(parentRect.width() * 0.75, parentRect.height() * 0.9)
        self.setMinimumSize(self.size())

        # Create the dialog layout
        self.layout = QVBoxLayout(self)

        # Set up the destination folder selector
        self.setUpDialogHeader()
        # Set up the file lister for the torrent file
        self.setUpFileLister()
        # Set up the whole torrent priority combo box and buttons
        self.setUpDialogFooter()

    def setUpDialogHeader(self):
        headerLayout = QGridLayout()
        self.destinationFolder = paths.writableLocation(paths.DownloadLocation)
        torrentName = self.torrentInfo.name()

        # Show the torrent name row
        nameLabel = QLabel("Torrent name:", self)
        headerLayout.addWidget(nameLabel, 0, 0)

        nameEdit = QLineEdit(torrentName, self)
        nameEdit.setReadOnly(True)
        headerLayout.addWidget(nameEdit, 0, 1)

        # Show the destination folder row
        dirLabel = QLabel("Destination folder:", self)
        headerLayout.addWidget(dirLabel, 1, 0)

        self.textField = QLineEdit(self.destinationFolder, self)
        self.textField.setReadOnly(True)
        headerLayout.addWidget(self.textField, 1, 1)

        button = QPushButton("Browse", self)
        button.clicked.connect(self.selectFolder)
        headerLayout.addWidget(button, 1, 2)

        self.layout.addLayout(headerLayout)

    def selectFolder(self):
        newDir = str(QFileDialog.getExistingDirectory(self,
                                                      "Select Directory"))
        if newDir:
            self.textField.setText(newDir)
            self.destinationFolder = newDir

    def setUpFileLister(self):
        self.files = [(f.path, f.size) for f in self.torrentInfo.files()]
        self.treeView = QTreeWidget(self)
        self.treeView.setColumnCount(3)
        self.treeView.setColumnWidth(0, 350)
        self.treeView.setColumnWidth(1, 80)
        self.treeView.setHeaderLabels(["Name", "size", "Priority"])
        self.treeView.setExpandsOnDoubleClick(False)

        if len(self.files) == 1:
            tree = file_tree.FileTree(self.files[0][0], self.files[0][1])
        else:
            tree = file_tree.FileTree(self.files[0][0].split('/')[0], 0)
            for f in self.files:
                tree.add_file(f[0], f[1])

        rootItem = TreeNodeItem(tree.get_root(), self.treeView)
        self.treeView.addTopLevelItem(rootItem)
        self.treeView.expandAll()
        self.treeView.itemClicked.connect(self.rowClicked)
        self.layout.addWidget(self.treeView)

    def rowClicked(self, item, column):
        if item.checkState(0) == Qt.PartiallyChecked:
            item.setCheckState(0, Qt.Checked)

        if column == 2:
            priorityChanges = {'Normal': 'High',
                               'High': 'Low',
                               'Low': 'Normal',
                               'Mixed': 'Normal'}
            newPriority = priorityChanges[item.text(2)]
            self.changeTextOfAllChildren(item, 2, newPriority)

            self.reprioritize(item)

    def changeTextOfAllChildren(self, item, column, text):
        item.setText(column, text)
        for i in range(0, item.childCount()):
            self.changeTextOfAllChildren(item.child(i), column, text)

    def reprioritize(self, start_node):
        parent = start_node.parent()
        if parent:
            if self.allChildrenHaveSamePriority(parent):
                parent.setText(2, start_node.text(2))
            else:
                parent.setText(2, "Mixed")

            self.reprioritize(parent)

    def allChildrenHaveSamePriority(self, node):
        for i in range(1, node.childCount()):
            if node.child(i - 1).text(2) != node.child(i).text(2):
                return False

        return True

    def setUpDialogFooter(self):
        footerLayout = QGridLayout()
        footerLayout.setColumnStretch(0, 4)

        footerLayout.addWidget(QLabel("Torrent priority"), 0, 1)
        self.priorityComboBox = QComboBox(self)
        self.priorityComboBox.addItems(["High", "Normal", "Low"])
        self.priorityComboBox.setCurrentIndex(1)
        footerLayout.addWidget(self.priorityComboBox, 0, 2)

        secondRowLayout = QHBoxLayout()

        OKButton = QPushButton("Open", self)
        OKButton.setFocus()
        OKButton.clicked.connect(self.accept)
        cancelButton = QPushButton("Cancel", self)
        cancelButton.clicked.connect(self.reject)
        secondRowLayout.addWidget(OKButton)
        secondRowLayout.addWidget(cancelButton)
        footerLayout.addLayout(secondRowLayout, 1, 2)

        self.layout.addLayout(footerLayout)

    def accept(self):
        torrentPriorities = {"Low": 0, "Normal": 127, "High": 255}
        filePriorities = {"Low": 1, "Normal": 4, "High": 7}

        it = QTreeWidgetItemIterator(self.treeView,
                                     QTreeWidgetItemIterator.NoChildren)

        itemsInfo = {}
        while it.value():
            currentItem = it.value()
            if currentItem.checkState(0) == Qt.Unchecked:
                priority = 0
            else:
                priority = filePriorities[currentItem.text(2)]

            itemsInfo[self.getFullPath(currentItem)] = priority
            it += 1

        paths = [f.path for f in self.torrentInfo.files()]
        self.prioritiesList = [itemsInfo[p] for p in paths]

        comboBoxIndex = self.priorityComboBox.currentIndex()
        self.priority = torrentPriorities[self.priorityComboBox.itemText(
                                                                comboBoxIndex)]

        self.hide()
        self.dataReady.emit(self.getData())
        super().accept()

    def getFullPath(self, treeItem):
        items = [treeItem.text(0)]
        parent = treeItem.parent()

        while parent:
            items.append(parent.text(0))
            parent = parent.parent()

        return '/'.join(reversed(items))

    def getData(self):
        return {'info': self.torrentInfo,
                'destination_folder': self.destinationFolder,
                'torrent_priority': self.priority,
                'file_priorities': self.prioritiesList}
Beispiel #16
0
class Preferences(QDialog):
    #
    configuration = {}
    weight = 0
    #
    savePreferences = pyqtSignal()

    #
    def __init__(self, parent=None):
        super(Preferences, self).__init__(parent, Qt.Dialog)
        self.setWindowTitle(translations.TR_PREFERENCES_TITLE)
        self.setMinimumSize(QSize(900, 600))
        vbox = QVBoxLayout(self)
        hbox = QHBoxLayout()
        vbox.setContentsMargins(0, 0, 5, 5)
        hbox.setContentsMargins(0, 0, 0, 0)
        #
        self.tree = QTreeWidget()
        self.tree.header().setHidden(True)
        self.tree.setSelectionMode(QTreeWidget.SingleSelection)
        self.tree.setAnimated(True)
        self.tree.header().setHorizontalScrollMode(
            QAbstractItemView.ScrollPerPixel)
        self.tree.header().setSectionResizeMode(0,
                                                QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
        self.tree.setFixedWidth(200)
        self.stacked = QStackedLayout()
        hbox.addWidget(self.tree)
        hbox.addLayout(self.stacked)
        vbox.addLayout(hbox)
        #
        hbox_footer = QHBoxLayout()
        self._btnSave = QPushButton(translations.TR_SAVE)
        self._btnCancel = QPushButton(translations.TR_CANCEL)
        hbox_footer.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox_footer.addWidget(self._btnCancel)
        hbox_footer.addWidget(self._btnSave)
        vbox.addLayout(hbox_footer)
        #
        self.tree.itemSelectionChanged.connect(self._change_current)
        self._btnCancel.clicked['bool'].connect(self.close)
        self._btnSave.clicked['bool'].connect(self._save_preferences)
        #
        self.load_ui()
        self.tree.setCurrentItem(self.tree.topLevelItem(0))
#

    def _save_preferences(self):
        self.savePreferences.emit()
        self.close()
#

    def load_ui(self):
        sections = sorted(
            list(Preferences.configuration.keys()),
            key=lambda item: Preferences.configuration[item]['weight'])
        for section in sections:
            text = Preferences.configuration[section]['text']
            Widget = Preferences.configuration[section]['widget']
            widget = Widget(self)
            area = QScrollArea()
            area.setWidgetResizable(True)
            area.setWidget(widget)
            self.stacked.addWidget(area)
            index = self.stacked.indexOf(area)
            item = QTreeWidgetItem([text])
            item.setData(0, Qt.UserRole, index)
            self.tree.addTopLevelItem(item)
            #
            #Sort Item Children
            subcontent = Preferences.configuration[section].get(
                'subsections', {})
            subsections = sorted(list(subcontent.keys()),
                                 key=lambda item: subcontent[item]['weight'])
            for sub in subsections:
                text = subcontent[sub]['text']
                Widget = subcontent[sub]['widget']
                widget = Widget(self)
                area = QScrollArea()
                area.setWidgetResizable(True)
                area.setWidget(widget)
                self.stacked.addWidget(area)
                index = self.stacked.indexOf(area)
                subitem = QTreeWidgetItem([text])
                subitem.setData(0, Qt.UserRole, index)
                item.addChild(subitem)
#
        self.tree.expandAll()
#

    def _change_current(self):
        item = self.tree.currentItem()
        index = item.data(0, Qt.UserRole)
        self.stacked.setCurrentIndex(index)
#

    @classmethod
    def register_configuration(cls,
                               section,
                               widget,
                               text,
                               weight=None,
                               subsection=None):
        if weight is None:
            Preferences.weight += 1
            weight = Preferences.weight
        if not subsection:
            Preferences.configuration[section] = {
                'widget': widget,
                'weight': weight,
                'text': text
            }
        else:
            config = Preferences.configuration.get(section, {})
            if not config:
                config[section] = {'widget': None, 'weight': 100}
            subconfig = config.get('subsections', {})
            subconfig[subsection] = {
                'widget': widget,
                'weight': weight,
                'text': text
            }
            config['subsections'] = subconfig
            Preferences.configuration[section] = config
class TreeSymbolsWidget(QDialog):
    """ Class of Dialog for Tree Symbols """

    dockWidget = pyqtSignal('PyQt_PyObject')
    undockWidget = pyqtSignal('PyQt_PyObject')

    def __init__(self, parent=None):
        super(TreeSymbolsWidget, self).__init__(parent)
        vbox = QVBoxLayout(self)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setSpacing(0)
        self.tree = QTreeWidget()
        self.tree.setFrameShape(0)
        vbox.addWidget(self.tree)
        self.tree.header().setHidden(True)
        self.tree.setSelectionMode(self.tree.SingleSelection)
        self.tree.setAnimated(True)
        self.tree.header().setHorizontalScrollMode(
            QAbstractItemView.ScrollPerPixel)
        self.tree.header().setSectionResizeMode(
            0, QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
        self.actualSymbols = ('', {})
        self.docstrings = {}
        self.collapsedItems = {}
        self.__icons = {
            "function": QIcon(":img/function"),
            "attribute": QIcon(":img/statement"),
            "class": QIcon(":img/class")
        }

        self.tree.itemClicked.connect(self._go_to_definition)
        self.tree.itemActivated.connect(self._go_to_definition)
        self.tree.setContextMenuPolicy(Qt.CustomContextMenu)

        self.customContextMenuRequested['const QPoint &'].connect(
            self._menu_context_tree)
        # self.connect(
        #    self,
        #    SIGNAL("customContextMenuRequested(const QPoint &)"),
        #    self._menu_context_tree)
        # self.connect(self, SIGNAL("itemCollapsed(QTreeWidgetItem *)"),
        #             self._item_collapsed)
        # self.connect(self, SIGNAL("itemExpanded(QTreeWidgetItem *)"),
        #             self._item_expanded)

        IDE.register_service('symbols_explorer', self)
        ExplorerContainer.register_tab(translations.TR_TAB_SYMBOLS, self)

    def install_tab(self):
        """ Connect signals for goingdown """

        ide = IDE.get_service('ide')
        ide.goingDown.connect(self.close)

    def _menu_context_tree(self, point):
        """Context menu"""
        index = self.tree.indexAt(point)
        if not index.isValid():
            return

        menu = QMenu(self)
        f_all = menu.addAction(translations.TR_FOLD_ALL)
        u_all = menu.addAction(translations.TR_UNFOLD_ALL)
        menu.addSeparator()
        u_class = menu.addAction(translations.TR_UNFOLD_CLASSES)
        u_class_method = menu.addAction(
            translations.TR_UNFOLD_CLASSES_AND_METHODS)
        u_class_attr = menu.addAction(
            translations.TR_UNFOLD_CLASSES_AND_ATTRIBUTES)
        menu.addSeparator()
        # save_state = menu.addAction(self.tr("Save State"))

        # self.connect(f_all, SIGNAL("triggered()"),
        #             lambda: self.tree.collapseAll())
        # self.connect(u_all, SIGNAL("triggered()"),
        #             lambda: self.tree.expandAll())
        # self.connect(u_class, SIGNAL("triggered()"), self._unfold_class)
        # self.connect(u_class_method, SIGNAL("triggered()"),
        #             self._unfold_class_method)
        # self.connect(u_class_attr, SIGNAL("triggered()"),
        #              self._unfold_class_attribute)
        # self.connect(save_state, SIGNAL("triggered()"),
        #    self._save_symbols_state)

        menu.exec_(QCursor.pos())

    def _get_classes_root(self):
        """Return the root of classes"""
        class_root = None
        for i in range(self.tree.topLevelItemCount()):
            item = self.tree.topLevelItem(i)
            if item.isClass and not item.isClickable:
                class_root = item
                break
        return class_root

    def _unfold_class(self):
        """Method to Unfold Classes"""
        self.tree.collapseAll()
        classes_root = self._get_classes_root()
        if not classes_root:
            return

        classes_root.setExpanded(True)

    def _unfold_class_method(self):
        """Method to Unfold Methods"""
        self.tree.expandAll()
        classes_root = self._get_classes_root()
        if not classes_root:
            return
        # for each class!
        for i in range(classes_root.childCount()):
            class_item = classes_root.child(i)
            # for each attribute or functions
            for j in range(class_item.childCount()):
                item = class_item.child(j)
                # METHODS ROOT!!
                if not item.isMethod and not item.isClickable:
                    item.setExpanded(False)
                    break

    def _unfold_class_attribute(self):
        """Method to Unfold Attributes"""
        self.tree.expandAll()
        classes_root = self._get_classes_root()
        if not classes_root:
            return
        # for each class!
        for i in range(classes_root.childCount()):
            class_item = classes_root.child(i)
            # for each attribute or functions
            for j in range(class_item.childCount()):
                item = class_item.child(j)
                # ATTRIBUTES ROOT!!
                if not item.isAttribute and not item.isClickable:
                    item.setExpanded(False)
                    break

    def _save_symbols_state(self):
        """Method to Save a persistent Symbols state"""
        # filename = self.actualSymbols[0]
        # TODO: persist self.collapsedItems[filename] in QSettings
        pass

    def _get_expand(self, item):
        """
        Returns True or False to be used as setExpanded() with the items
        It method is based on the click that the user made in the tree
        """
        name = self._get_unique_name(item)
        filename = self.actualSymbols[0]
        collapsed_items = self.collapsedItems.get(filename, [])
        can_check = (not item.isClickable) or item.isClass or item.isMethod
        if can_check and name in collapsed_items:
            return False
        return True

    @staticmethod
    def _get_unique_name(item):
        """
        Returns a string used as unique name
        """
        # className_Attributes/className_Functions
        parent = item.parent()
        if parent:
            return "%s_%s" % (parent.text(0), item.text(0))
        return "_%s" % item.text(0)

    def clear(self):
        self.tree.clear()

    def update_symbols_tree(self, symbols, filename='', parent=None):
        """Method to Update the symbols on the Tree"""
        TIP = "{} {}"
        if not parent:
            if filename == self.actualSymbols[0] and \
                    self.actualSymbols[1] and not symbols:
                return

            if symbols == self.actualSymbols[1]:
                # Nothing new then return
                return

            # we have new symbols refresh it
            self.tree.clear()
            self.actualSymbols = (filename, symbols)
            self.docstrings = symbols.get('docstrings', {})
            parent = self.tree
        if 'attributes' in symbols:
            globalAttribute = ItemTree(parent, [translations.TR_ATTRIBUTES])
            globalAttribute.isClickable = False
            globalAttribute.isAttribute = True
            globalAttribute.setExpanded(self._get_expand(globalAttribute))
            globalAttribute.setToolTip(
                0, TIP.format(len(symbols['attributes']),
                              translations.TR_ATTRIBUTES))
            for glob in sorted(symbols['attributes']):
                globItem = ItemTree(globalAttribute, [glob],
                                    lineno=symbols['attributes'][glob])
                globItem.isAttribute = True
                globItem.setIcon(0, self.__icons["attribute"])
                globItem.setExpanded(self._get_expand(globItem))

        if 'functions' in symbols and symbols['functions']:
            functionsItem = ItemTree(parent, [translations.TR_FUNCTIONS])
            functionsItem.isClickable = False
            functionsItem.isMethod = True
            functionsItem.setExpanded(self._get_expand(functionsItem))
            functionsItem.setToolTip(0, TIP.format(len(symbols['functions']),
                                                   translations.TR_FUNCTIONS))
            for func in sorted(symbols['functions']):
                item = ItemTree(functionsItem, [func],
                                lineno=symbols['functions'][func]['lineno'])
                tooltip = self.create_tooltip(
                    func, symbols['functions'][func]['lineno'])
                item.isMethod = True
                item.setIcon(0, self.__icons["function"])
                # item.setIcon(
                #    0, ui_tools.colored_icon(":img/function", "#9FA8DA"))
                item.setToolTip(0, tooltip)
                item.setExpanded(self._get_expand(item))
                self.update_symbols_tree(
                    symbols['functions'][func]['functions'], parent=item)
        if 'classes' in symbols and symbols['classes']:
            classItem = ItemTree(parent, [translations.TR_CLASSES])
            classItem.isClickable = False
            classItem.isClass = True
            classItem.setExpanded(self._get_expand(classItem))
            classItem.setToolTip(0, TIP.format(len(symbols['classes']),
                                               translations.TR_CLASSES))
            for claz in sorted(symbols['classes']):
                line_number = symbols['classes'][claz]['lineno']
                item = ItemTree(classItem, [claz], lineno=line_number)
                item.isClass = True
                tooltip = self.create_tooltip(claz, line_number)
                item.setToolTip(0, tooltip)
                # item.setIcon(0, ui_tools.colored_icon(":img/class", "#FFCC80"))
                # item.setIcon(0, ui_tools.get_icon('class', '#FFCC80'))
                item.setIcon(0, self.__icons["class"])
                item.setExpanded(self._get_expand(item))
                self.update_symbols_tree(symbols['classes'][claz]['members'],
                                         parent=item)

    def _go_to_definition(self, item):
        """ Takes and item object and goes to definition on the editor """

        main_container = IDE.get_service('main_container')
        if item.isClickable and main_container:
            main_container.editor_go_to_line(item.lineno - 1)

    def create_tooltip(self, name, lineno):
        """Takes a name and line number and returns a tooltip"""
        doc = self.docstrings.get(lineno, None)
        if doc is None:
            doc = ''
        else:
            doc = '\n' + doc
        tooltip = name + doc
        return tooltip

    def _item_collapsed(self, item):
        """When item collapsed"""
        super(TreeSymbolsWidget, self).collapseItem(item)

        can_check = (not item.isClickable) or item.isClass or item.isMethod
        if can_check:
            n = self._get_unique_name(item)
            filename = self.actualSymbols[0]
            self.collapsedItems.setdefault(filename, [])
            if n not in self.collapsedItems[filename]:
                self.collapsedItems[filename].append(n)

    def _item_expanded(self, item):
        """When item expanded"""
        super(TreeSymbolsWidget, self).expandItem(item)

        n = self._get_unique_name(item)
        filename = self.actualSymbols[0]
        if n in self.collapsedItems.get(filename, []):
            self.collapsedItems[filename].remove(n)
            if not len(self.collapsedItems[filename]):
                # no more items, free space
                del self.collapsedItems[filename]

    def clean(self):
        """
        Reset the tree and reset attributes
        """
        self.tree.clear()
        self.collapsedItems = {}

    def reject(self):
        if self.parent() is None:
            self.dockWidget.emit(self)

    def closeEvent(self, event):
        """On Close event handling"""

        self.dockWidget.emit(self)
        # self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self)
        event.ignore()
Beispiel #18
0
class ClientForm(QMainWindow):
    """主页面"""
    def __init__(self):
        super().__init__()
        self.init = 0  # 0 代表初始情况,需要建立websocket连接,其他不用
        self.cur_user_t = ('', '')  # 当前用户的工号和姓名
        self.initUI()

    def initUI(self):
        """
        初始化UI
        :return:
        """
        self.setObjectName("mainWindow")
        self.setStyleSheet('#mainWindow{background-color:white}')
        self.setFixedSize(400, 770)
        self.setWindowTitle("cssrc消息盒子")
        self.setWindowIcon(QIcon('static/logo_title.png'))

        # 获取屏幕信息
        desktop = QApplication.desktop()
        self.move(desktop.width() - 400 - 10, 5)
        # 创建状态栏
        self.statusBar().showMessage("copyright@cssrc")

        # 创建菜单栏
        self.create_menu()

        # 创建用户信息部分
        uwidget = QWidget(self)
        uwidget.setObjectName("usrpart")
        uwidget.setStyleSheet(
            "#usrpart{border:1px solid #e1e2e2;border-left:none;border-right:none;}"
        )
        uwidget.setGeometry(0, 26, 400, 80)
        hbox_user = QHBoxLayout()
        uwidget.setLayout(hbox_user)

        # 创建用户头像
        pixmap = QPixmap("static/usr.png")
        label = QLabel(self)
        label.setPixmap(pixmap)
        hbox_user.addWidget(label, 1)

        # 用户信息
        uvbox = QVBoxLayout()
        usrname = self.cur_user_t[1] if self.cur_user_t is not None else "暂无"
        self.lbl_usrname = QLabel("%s, %s好" % (usrname, "下午"))
        self.lbl_usrname.setFont(QFont("Microsoft YaHei"))
        self.lbl_usrname.setStyleSheet("margin-left:10px")
        uvbox.addWidget(self.lbl_usrname)

        # 消息logo
        msg_logo_num = QWidget()
        msg_logo_num_lay = QHBoxLayout()
        msg_logo_num.setLayout(msg_logo_num_lay)  # 消息条数部分组件
        lbl_msgnum = QLabel()
        msgpixmap = QPixmap("static/msg_sm.png")
        lbl_msgnum.setPixmap(msgpixmap)
        msg_logo_num_lay.addWidget(lbl_msgnum)
        lbl_msg_number = QLabel("(12)")
        lbl_msg_number.setFont(QFont("Microsoft YaHei"))
        msg_logo_num_lay.addWidget(lbl_msg_number, 1)

        uvbox.addWidget(msg_logo_num)

        hbox_user.addLayout(uvbox, 4)

        # 创建消息列表部分
        unread_label = QLabel(self)
        unread_label.setObjectName("unread_label")
        unread_label.setText("未读消息")
        unread_label.setFont(QFont("Microsoft YaHei"))
        unread_label.setStyleSheet(
            "#%s{border:1px solid #e1e2e2;border-left:none;border-right:none;padding-left:20px;}"
            % "unread_label")
        unread_label.setGeometry(0, 105, 400, 50)
        # 消息列表具体内容
        self.msglist_widget = QWidget(self)
        self.msglist_widget.setGeometry(0, 155, 400, 580)
        self.msglist_widget.setObjectName("msglist")
        self.msglist_widget.setStyleSheet("#msglist{border:1px solid red}")

        # 在此动态添加内容
        self.tree = QTreeWidget(self.msglist_widget)  # 创建tree组件
        # 设置列数
        self.tree.setColumnCount(3)  # 设置列数
        # 设置树形控件的头部标题
        self.tree.setHeaderLabels(["消息描述", "推送时间", "url"])  # 给treeview设置标题
        # 设置隐藏
        self.tree.setColumnHidden(2, True)
        # 设置属性控件列的宽度
        self.tree.setColumnWidth(0, 280)
        self.tree.setColumnWidth(1, 80)

    def create_menu(self):
        """
        创建菜单
        :return:
        """

        menubar = self.menuBar()  # 创建菜单栏
        # 新建菜单项
        fileMenu = menubar.addMenu("&文件(F)")
        # 添加菜单子项
        selfAct = QAction(QIcon('exit.png'), '&个人设置(P)', self)
        selfAct.setShortcut('Ctrl+P')
        selfAct.setStatusTip("个人设置")
        selfAct.triggered.connect(self.go_self_setting)  # 查看个人信息页面
        fileMenu.addAction(selfAct)

        # 系统设置
        syssetAct = QAction("&系统设置(S)", self)
        syssetAct.setShortcut("Ctrl+S")
        syssetAct.setStatusTip("系统设置")
        syssetAct.triggered.connect(self.go_sys_setting)  # 去系统设置页面
        fileMenu.addAction(syssetAct)

        # 退出
        exitAct = QAction("&退出(X)", self)
        exitAct.setShortcut("Ctrl+X")
        exitAct.setStatusTip("退出系统")
        exitAct.triggered.connect(qApp.quit)  # 退出系统
        fileMenu.addAction(exitAct)

        # 新建帮助菜单项
        helpMenu = menubar.addMenu("&帮助(H)")
        # 添加帮助菜单项
        seeAct = QAction("&查看消息记录(M)", self)
        seeAct.setShortcut("Ctrl+M")
        seeAct.setStatusTip("查看消息记录")
        seeAct.triggered.connect(self.go_see_history)  # 查看历史消息
        helpMenu.addAction(seeAct)

        # 刷新系统组织
        refreshSys = QAction("&刷新系统组织(U)", self)
        refreshSys.setShortcut("Ctrl+U")
        refreshSys.setStatusTip("刷新系统组织")
        refreshSys.triggered.connect(self.go_fresh_sys)  # 刷新系统组织
        helpMenu.addAction(refreshSys)

        # 关于
        aboutAct = QAction("&关于(A)", self)
        aboutAct.setShortcut("Ctrl+A")
        aboutAct.setStatusTip("关于系统")
        aboutAct.triggered.connect(self.go_about)  # 关于系统
        helpMenu.addAction(aboutAct)

    def go_self_setting(self):
        """
        个人设置页面
        :return:
        """
        print("查看个人设置 页面")

    def go_sys_setting(self):
        """
        系统设置页面
        :return:
        """
        print("系统设置 页面")

    def go_see_history(self):
        """
        查看历史消息
        :return:
        """
        print("历史消息 页面")

    def go_fresh_sys(self):
        """
        刷新系统组织
        :return:
        """
        print("系统组织")

    def go_about(self):
        """
        查看关于系统
        :return:
        """
        print("关于系统")

    def do_fetch_data(self):
        """
        加载用户数据
        :return:
        """
        self.cur_user_t = getUsrTuples()
        print(self.cur_user_t)

    def onClicked(self, index):
        """
        点击单个选项事件
        :param index:
        :return:
        """
        item = self.tree.currentItem()  # 获取当前选中的节点
        if item and item.text(2) != "":
            param = item.text(2).split("|")
            if param is not None and param[2] != "WAITTING_READ":
                QtGui.QDesktopServices.openUrl(QtCore.QUrl(param[1]))
                return
            button = QMessageBox.warning(self, "提示", "是否前去查看?",
                                         QMessageBox.Ok | QMessageBox.Cancel,
                                         QMessageBox.Ok)
            if button == QMessageBox.Ok:  # 如果确定,就打开网页
                QtGui.QDesktopServices.openUrl(QtCore.QUrl(param[1]))
                # 发起一个Http请求告知后端该消息已被查看
                if param is not None and param[2] == "WAITTING_READ":
                    try:
                        result = update_msg_read(param[0])
                        print(result)
                    except:
                        pass

    def showEvent(self, *args, **kwargs):
        """
        显示
        1.建立socket连接
        2.加载数据
        3.绑定数据
        :param args:
        :param kwargs:
        :return:
        """
        if self.init == 0:  # 初次加载
            print("show...")
            self.do_fetch_data()
            self.lbl_usrname.setText(
                "%s, %s好" %
                (self.cur_user_t[1], MyDateInfoHelper.getTimeRange()))
            self.init += 1  # 累加
            # 建立socket连接,开启新线程自动刷新列表
            ChatNamespace.ContainerWidget = self.msglist_widget
            ChatNamespace.Parent = self
            refresh_thread = TreeRenderThread(self.cur_user_t[0])  # 传递工号
            refresh_thread.breakSignal.connect(self.createmsg_list)
            refresh_thread.start()  # 开启新线程

    def createmsg_list(self, msg_info_data):
        """
        添加信息列表
        :param msg_info_data:  消息列表
        :return:
        """
        # 先清空root根下面的所有的历史消息
        self.tree.clear()
        # 设置根节点
        self.root = QTreeWidgetItem(self.tree)  # 设置根节点
        self.root.setText(0, "cssrc消息盒子(未读消息)")  # 设置根节点的名字
        self.root.setIcon(0, QIcon("static/loc.png"))  # 设置 根节点的图片

        try:
            msg_list = msg_info_data.get('data').get('msgs')
            sys_list = msg_info_data.get('data').get('sys')
            for sys in sys_list:
                child = QTreeWidgetItem()
                child.setText(0, sys.get("sysname"))
                child.setIcon(0, QIcon("static/app.png"))
                child.setText(1, "")
                child.setText(2, "")
                # 添加到根节点上
                self.root.addChild(child)
                # 添加二级节点
                for msg in msg_list:
                    # 将该系统下的所有的消息加载到节点上
                    if msg.get("from_sys") == sys.get("id"):
                        status = msg.get("msg_status")
                        sec_child = QTreeWidgetItem(child)
                        # sec_child.setToolTip("")
                        sec_child.setText(0, msg.get("msg_title"))
                        sec_child.setText(1, msg.get("msg_push_time"))
                        sec_child.setText(
                            2,
                            str(msg.get("id")) + "|" +
                            str(msg.get("msg_url")) + "|" + status)
                        if status == "WAITTING_READ":
                            sec_child.setIcon(0, QIcon("static/msg_alert.png"))
                        else:
                            sec_child.setIcon(0, QIcon("static/xx.png"))
        except Exception as e:
            print("解析异常")

        # 加载根节点的所有属性 与子控件
        self.tree.addTopLevelItem(self.root)

        # 给节点点击添加响应事件
        try:
            self.tree.clicked.disconnect(self.onClicked)  # 先取消绑定
        except:
            pass
        self.tree.clicked.connect(self.onClicked)

        # 节点全部展开看
        self.tree.expandAll()

        # 添加到父容器中设置位置
        self.tree.setGeometry(0, 0, 400, 580)
Beispiel #19
0
class Preferences(QDialog):

    configuration = {}
    weight = 0
    # Signals
    savePreferences = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent, Qt.Dialog)
        self.setWindowTitle(translations.TR_PREFERENCES_TITLE)
        self.setMinimumSize(900, 600)
        box = QVBoxLayout(self)
        box.setContentsMargins(5, 5, 5, 5)
        # Header
        self._header_label = QLabel("")
        header_font = self._header_label.font()
        header_font.setBold(True)
        header_font.setPointSize(header_font.pointSize() + 4)
        self._header_label.setFont(header_font)

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

        self.tree = QTreeWidget()
        self.tree.header().setHidden(True)
        self.tree.setSelectionMode(QTreeWidget.SingleSelection)
        self.tree.setAnimated(True)
        self.tree.header().setSectionResizeMode(0,
                                                QHeaderView.ResizeToContents)
        self.tree.setFixedWidth(200)
        hbox.addWidget(self.tree)

        self.stacked = QStackedLayout()
        header_layout = QVBoxLayout()
        header_layout.addWidget(self._header_label)
        header_layout.addLayout(self.stacked)
        hbox.addLayout(header_layout)
        box.addLayout(hbox)

        # Footer buttons
        button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                      | QDialogButtonBox.Cancel)
        box.addWidget(button_box)

        # Connections
        button_box.rejected.connect(self.close)
        button_box.accepted.connect(self._save_preferences)
        self.tree.selectionModel().currentRowChanged.connect(
            self._change_current)

        self.load_ui()

    @pyqtSlot()
    def _save_preferences(self):
        self.savePreferences.emit()
        self.close()

    def load_ui(self):
        sections = sorted(
            Preferences.configuration.keys(),
            key=lambda item: Preferences.configuration[item]['weight'])
        for section in sections:
            text = Preferences.configuration[section]['text']
            Widget = Preferences.configuration[section]['widget']
            widget = Widget(self)
            area = QScrollArea()
            area.setWidgetResizable(True)
            area.setWidget(widget)
            self.stacked.addWidget(area)
            index = self.stacked.indexOf(area)
            item = QTreeWidgetItem([text])
            item.setData(0, Qt.UserRole, index)
            self.tree.addTopLevelItem(item)

            # Sort Item Children
            subcontent = Preferences.configuration[section].get(
                'subsections', {})
            subsections = subcontent.keys()
            for sub in subsections:
                text = subcontent[sub]['text']
                Widget = subcontent[sub]['widget']
                widget = Widget(self)
                area = QScrollArea()
                area.setWidgetResizable(True)
                area.setWidget(widget)
                self.stacked.addWidget(area)
                index = self.stacked.indexOf(area)
                subitem = QTreeWidgetItem([text])
                subitem.setData(0, Qt.UserRole, index)
                item.addChild(subitem)

        self.tree.expandAll()
        self.tree.setCurrentIndex(self.tree.model().index(0, 0))

    def _change_current(self):
        item = self.tree.currentItem()
        index = item.data(0, Qt.UserRole)
        self.stacked.setCurrentIndex(index)
        self._header_label.setText(item.text(0))

    @classmethod
    def register_configuration(cls,
                               section,
                               widget,
                               text,
                               weight=None,
                               subsection=None):
        if weight is None:
            Preferences.weight += 1
            weight = Preferences.weight
        if subsection is None:
            Preferences.configuration[section] = {
                'widget': widget,
                'weight': weight,
                'text': text
            }
        else:
            config = Preferences.configuration.get(section, {})
            if not config:
                config[section] = {'widget': None, 'weight': 100}
            subconfig = config.get('subsections', {})
            subconfig[subsection] = {
                'widget': widget,
                'weight': weight,
                'text': text
            }
            config['subsections'] = subconfig
            Preferences.configuration[section] = config
Beispiel #20
0
class FileExplorer(QWidget):
    PREVIEW_WIDTH = 450

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

        self.new_folder_path = ''
        self.folder_to_filename = defaultdict(list)
        self.item_clicked = None
        self.item_selected_image = None
        self.image_selected_data = None

        self.button_add_folder = QPushButton('Add Folder', self)
        self.button_add_folder.clicked.connect(self.on_clicked_add_folder)
        self.button_remove_folder = QPushButton('Remove Folder', self)
        self.button_remove_folder.clicked.connect(self.on_clicked_remove_folder)

        self.widget_tree = QTreeWidget(self)
        self.widget_tree.setColumnCount(2)
        self.widget_tree.setHeaderLabels(['Files', 'Format'])
        self.widget_tree.setColumnWidth(0, 350)
        # self.tree.setMaximumWidth(500)
        self.widget_tree.itemClicked.connect(self.on_clicked_tree_item)

        self.item_preview = QTreeWidgetItem(self.widget_tree)
        self.item_preview.setText(0, 'ALL Folders')

        ft1 = QFont()
        ft1.setPointSize(15)
        self.label_image_preview = QLabel('No Info')
        self.label_image_preview.setFont(ft1)
        self.label_image_preview.setAlignment(Qt.AlignCenter)
        self.label_image_preview.setWordWrap(True)

        self.hbox_layout = QHBoxLayout()
        self.hbox_layout.addWidget(self.button_add_folder)
        self.hbox_layout.addWidget(self.button_remove_folder)
        self.grid_layout = QGridLayout()
        self.grid_layout.addLayout(self.hbox_layout, 0, 0, 1, 1)
        self.grid_layout.addWidget(self.widget_tree, 1, 0, 5, 5)
        self.grid_layout.addWidget(self.label_image_preview, 1, 5, 5, 5)
        self.setLayout(self.grid_layout)

        self.widget_tree.expandAll()

    def on_clicked_tree_item(self, item, column):
        from image_inpainting_demo import set_label_image

        self.label_image_preview.setText(item.text(column))
        self.item_clicked = item

        # is select image
        if item.checkState(0) == Qt.Checked:
            if self.item_selected_image and self.item_selected_image is not item:
                self.item_selected_image.setCheckState(0, Qt.Unchecked)
            self.item_selected_image = item
            self.item_selected_image.setCheckState(0, Qt.Checked)

            image_path = self.item_selected_image.parent().text(0) + '/' + self.item_selected_image.text(0)
            print('select image path : ', image_path)
            # preview image
            new_img = Image.open(image_path)
            new_img = new_img.convert('RGB')
            self.image_selected_data = np.asarray(new_img)
            set_label_image(self.label_image_preview, self.PREVIEW_WIDTH, self.image_selected_data)
            self.parent.clip_area.set_image(self.image_selected_data)

    def on_clicked_add_folder(self):
        self.new_folder_path = QFileDialog.getExistingDirectory(self, "Add Folder", self.new_folder_path)
        if self.new_folder_path:
            if self.new_folder_path in self.folder_to_filename:
                QMessageBox.warning(self, 'warning', 'New folder has exist !')
                return

            print('add new folder path : ', self.new_folder_path)

            # add folder item
            folder_item = QTreeWidgetItem(self.item_preview)
            folder_item.setText(0, self.new_folder_path)
            folder_item.setText(1, 'Folder')

            images = os.listdir(self.new_folder_path)

            # filter images
            def is_image(path):
                suffix = path.split('.')[-1]
                if suffix in ('jpg', 'png', 'bmp', 'jpeg'):
                    return True
                return False

            images = list(filter(is_image, images))
            images.sort()
            self.folder_to_filename[self.new_folder_path] = images

            # add image item
            for i, image in enumerate(images):
                item = QTreeWidgetItem(folder_item)
                item.setText(0, image)
                item.setText(1, 'Image')
                item.setCheckState(0, Qt.Unchecked)

    def on_clicked_remove_folder(self):
        if self.item_clicked:
            if self.item_clicked.text(1) == 'Folder':
                if self.item_clicked.text(0) in self.folder_to_filename:
                    if self.item_selected_image:
                        self.item_selected_image.setCheckState(0, Qt.Unchecked)
                    del self.folder_to_filename[self.item_clicked.text(0)]
                    self.item_preview.removeChild(self.item_clicked)
                    self.item_clicked = None
                    self.item_selected_image = None
                    self.parent.setTabEnabled(1, False)
                    self.parent.setTabEnabled(2, False)
                    self.parent.setTabEnabled(3, False)
            else:
                QMessageBox.warning(self, 'warning', 'only allow to remove folder !')
Beispiel #21
0
class MainWindow(object):
    def __init__(self):
        self.setWindowTitle("50ETF期权监控系统")
        self.resize(1000, 600)
        self.setWindowIcon(QIcon("50ETF.ico"))

        self.code_lbl = QLabel("代码")
        self.name_lbl = QLabel("名称")
        self.last_lbl = QLabel("现价")
        self.chg_lbl = QLabel("涨跌")
        self.pct_chg_lbl = QLabel("涨跌幅")
        self.open_lbl = QLabel("今开")
        self.high_lbl = QLabel("最高")
        self.low_lbl = QLabel("最低")
        self.vol_lbl = QLabel("成交量")
        self.amt_lbl = QLabel("成交额")
        self.time_lbl = QLabel("时间")

        self.code_data_lbl = QLabel("510050")
        self.name_data_lbl = QLabel("50ETF")
        self.last_data_lbl = QLabel()
        self.chg_data_lbl = QLabel()
        self.pct_chg_data_lbl = QLabel()
        self.open_data_lbl = QLabel()
        self.high_data_lbl = QLabel()
        self.low_data_lbl = QLabel()
        self.vol_data_lbl = QLabel()
        self.amt_data_lbl = QLabel()
        self.time_data_lbl = QLabel()

        etf_layout = QGridLayout()
        etf_layout.setSpacing(10)
        etf_layout.addWidget(self.code_lbl, 0, 0)
        etf_layout.addWidget(self.code_data_lbl, 1, 0)
        etf_layout.addWidget(self.name_lbl, 0, 1)
        etf_layout.addWidget(self.name_data_lbl, 1, 1)
        etf_layout.addWidget(self.last_lbl, 0, 2)
        etf_layout.addWidget(self.last_data_lbl, 1, 2)
        etf_layout.addWidget(self.chg_lbl, 0, 3)
        etf_layout.addWidget(self.chg_data_lbl, 1, 3)
        etf_layout.addWidget(self.pct_chg_lbl, 0, 4)
        etf_layout.addWidget(self.pct_chg_data_lbl, 1, 4)
        etf_layout.addWidget(self.open_lbl, 0, 5)
        etf_layout.addWidget(self.open_data_lbl, 1, 5)
        etf_layout.addWidget(self.high_lbl, 0, 6)
        etf_layout.addWidget(self.high_data_lbl, 1, 6)
        etf_layout.addWidget(self.low_lbl, 0, 7)
        etf_layout.addWidget(self.low_data_lbl, 1, 7)
        etf_layout.addWidget(self.vol_lbl, 0, 8)
        etf_layout.addWidget(self.vol_data_lbl, 1, 8)
        etf_layout.addWidget(self.amt_lbl, 0, 9)
        etf_layout.addWidget(self.amt_data_lbl, 1, 9)
        etf_layout.addWidget(self.time_lbl, 0, 10)
        etf_layout.addWidget(self.time_data_lbl, 1, 10)

        self.call_lbl = QLabel("认购/看涨")
        self.put_lbl = QLabel("认沽/看跌")

        option_type_layout = QHBoxLayout()
        option_type_layout.addWidget(self.call_lbl)
        option_type_layout.addWidget(self.put_lbl)

        self.option_data_tree = QTreeWidget()
        self.option_data_tree.setColumnCount(13)
        self.option_data_tree.setHeaderLabels([
            "最新价", "涨跌幅", "成交量", "持仓量", "隐含波动率", "Delta", "行权价", "Delta",
            "隐含波动率", "持仓量", "成交量", "涨跌幅", "最新价"
        ])
        self.cur_month = QTreeWidgetItem(self.option_data_tree)
        self.cur_month.setText(0, "当月合约")
        self.cur_month_strike1 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike2 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike3 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike4 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike5 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike6 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike7 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike8 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike9 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike10 = QTreeWidgetItem(self.cur_month)
        self.cur_month_strike11 = QTreeWidgetItem(self.cur_month)
        self.next_month = QTreeWidgetItem(self.option_data_tree)
        self.next_month.setText(0, "下月合约")
        self.next_month_strike1 = QTreeWidgetItem(self.next_month)
        self.next_month_strike2 = QTreeWidgetItem(self.next_month)
        self.next_month_strike3 = QTreeWidgetItem(self.next_month)
        self.next_month_strike4 = QTreeWidgetItem(self.next_month)
        self.next_month_strike5 = QTreeWidgetItem(self.next_month)
        self.next_month_strike6 = QTreeWidgetItem(self.next_month)
        self.next_month_strike7 = QTreeWidgetItem(self.next_month)
        self.next_month_strike8 = QTreeWidgetItem(self.next_month)
        self.next_month_strike9 = QTreeWidgetItem(self.next_month)
        self.next_month_strike10 = QTreeWidgetItem(self.next_month)
        self.next_month_strike11 = QTreeWidgetItem(self.next_month)
        self.follew_quar_month1 = QTreeWidgetItem(self.option_data_tree)
        self.follew_quar_month1.setText(0, "随后季月1")
        self.follew_quar_month1_strike1 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike2 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike3 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike4 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike5 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike6 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike7 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike8 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike9 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike10 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month1_strike11 = QTreeWidgetItem(
            self.follew_quar_month1)
        self.follew_quar_month2 = QTreeWidgetItem(self.option_data_tree)
        self.follew_quar_month2.setText(0, "随后季月2")
        self.follew_quar_month2_strike1 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike2 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike3 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike4 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike5 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike6 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike7 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike8 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike9 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike10 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.follew_quar_month2_strike11 = QTreeWidgetItem(
            self.follew_quar_month2)
        self.option_data_tree.expandAll()

        option_data_layout = QVBoxLayout()
        option_data_layout.addWidget(self.option_data_tree)

        option_layout = QVBoxLayout()
        option_layout.addLayout(option_type_layout)
        option_layout.addLayout(option_data_layout)

        self.etf_mpl = MyMplCanvas()
        self.option_mpl = MyMplCanvas()
        self.iv_mpl = MyMplCanvas()

        plot_layout = QHBoxLayout()
        plot_layout.addWidget(self.etf_mpl)
        plot_layout.addWidget(self.option_mpl)
        plot_layout.addWidget(self.iv_mpl)

        main_layout = QGridLayout()
        main_layout.addLayout(etf_layout, 0, 0)
        main_layout.addLayout(option_layout, 1, 0)
        main_layout.addLayout(plot_layout, 2, 0)
        self.setLayout(main_layout)
        self.showMaximized()
Beispiel #22
0
class Shortcuts(preferences.Page):
    def __init__(self, dialog):
        super(Shortcuts, self).__init__(dialog)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        self.scheme = SchemeSelector(self)
        layout.addWidget(self.scheme)
        self.searchEntry = LineEdit()
        self.searchEntry.setPlaceholderText(_("Search..."))
        layout.addWidget(self.searchEntry)
        self.tree = QTreeWidget(self)
        self.tree.setHeaderLabels([_("Command"), _("Shortcut")])
        self.tree.setRootIsDecorated(False)
        self.tree.setColumnCount(2)
        self.tree.setAllColumnsShowFocus(True)
        self.tree.setAnimated(True)
        layout.addWidget(self.tree)

        self.edit = QPushButton(icons.get("preferences-desktop-keyboard-shortcuts"), '')
        layout.addWidget(self.edit)

        # signals
        self.searchEntry.textChanged.connect(self.updateFilter)
        self.scheme.currentChanged.connect(self.slotSchemeChanged)
        self.scheme.changed.connect(self.changed)
        self.tree.currentItemChanged.connect(self.slotCurrentItemChanged)
        self.tree.itemDoubleClicked.connect(self.editCurrentItem)
        self.edit.clicked.connect(self.editCurrentItem)

        # make a dict of all actions with the actions as key and the names as
        # value, with the collection prepended (for loading/saving)
        win = dialog.parent()
        allactions = {}
        for collection in actioncollectionmanager.manager(win).actionCollections():
            for name, action in collection.actions().items():
                allactions[action] = (collection, name)

        # keep a list of actions not in the menu structure
        left = list(allactions.keys())

        def add_actions(menuitem, actions):
            """Add actions to a QTreeWidgetItem."""
            for a in actions:
                if a.menu():
                    item = build_menu_item(a)
                    if item.childCount():
                        menuitem.addChild(item)
                elif a in left:
                    left.remove(a)
                    menuitem.addChild(ShortcutItem(a, *allactions[a]))
            menuitem.setFlags(Qt.ItemIsEnabled) # disable selection

        def build_menu_item(action):
            """Return a QTreeWidgetItem with children for all the actions in the submenu."""
            menuitem = QTreeWidgetItem()
            text = qutil.removeAccelerator(action.text())
            menuitem.setText(0, _("Menu {name}").format(name=text))
            add_actions(menuitem, action.menu().actions())
            return menuitem

        # present the actions nicely ordered as in the menus
        for a in win.menuBar().actions():
            menuitem = build_menu_item(a)
            if menuitem.childCount():
                self.tree.addTopLevelItem(menuitem)

        # sort leftover actions
        left.sort(key=lambda i: i.text())

        # show actions that are left, grouped by collection
        titlegroups = {}
        for a in left[:]: # copy
            collection, name = allactions[a]
            if collection.title():
                titlegroups.setdefault(collection.title(), []).append(a)
                left.remove(a)
        for title in sorted(titlegroups):
            item = QTreeWidgetItem(["{0}:".format(title)])
            for a in titlegroups[title]:
                item.addChild(ShortcutItem(a, *allactions[a]))
            self.tree.addTopLevelItem(item)
            item.setFlags(Qt.ItemIsEnabled) # disable selection

        # show other actions that were not in the menus
        item = QTreeWidgetItem([_("Other commands:")])
        for a in left:
            if a.text() and not a.menu():
                item.addChild(ShortcutItem(a, *allactions[a]))
        if item.childCount():
            self.tree.addTopLevelItem(item)
            item.setFlags(Qt.ItemIsEnabled) # disable selection

        self.tree.expandAll()

        item = self.tree.topLevelItem(0).child(0)
        if _lastaction:
            # find the previously selected item
            for i in self.items():
                if i.name == _lastaction:
                    item = i
                    break
        self.tree.setCurrentItem(item)
        self.tree.resizeColumnToContents(0)

    def items(self):
        """Yield all the items in the actions tree."""
        def children(item):
            for i in range(item.childCount()):
                c = item.child(i)
                if c.childCount():
                    for c1 in children(c):
                        yield c1
                else:
                    yield c
        for c in children(self.tree.invisibleRootItem()):
            yield c

    def item(self, collection, name):
        for item in self.items():
            if item.collection.name == collection and item.name == name:
                return item

    def saveSettings(self):
        self.scheme.saveSettings("shortcut_scheme", "shortcut_schemes", "shortcuts")
        for item in self.items():
            for scheme in self.scheme.schemes():
                item.save(scheme)
            item.clearSettings()
            item.switchScheme(self.scheme.currentScheme())

    def loadSettings(self):
        self.scheme.loadSettings("shortcut_scheme", "shortcut_schemes")
        # clear the settings in all the items
        for item in self.items():
            item.clearSettings()
            item.switchScheme(self.scheme.currentScheme())

    def slotSchemeChanged(self):
        """Called when the Scheme combobox is changed by the user."""
        for item in self.items():
            item.switchScheme(self.scheme.currentScheme())

    def slotCurrentItemChanged(self, item):
        if isinstance(item, ShortcutItem):
            self.edit.setText(
                _("&Edit Shortcut for \"{name}\"").format(name=item.text(0)))
            self.edit.setEnabled(True)
            global _lastaction
            _lastaction = item.name
        else:
            self.edit.setText(_("(no shortcut)"))
            self.edit.setEnabled(False)

    def import_(self, filename):
        from . import import_export
        import_export.importShortcut(filename, self, self.scheme)

    def export(self, name, filename):
        from . import import_export
        try:
            import_export.exportShortcut(self, self.scheme.currentScheme(), name, filename)
        except (IOError, OSError) as e:
            QMessageBox.critical(self, _("Error"), _(
                "Can't write to destination:\n\n{url}\n\n{error}").format(
                url=filename, error=e.strerror))

    def findShortcutConflict(self, shortcut):
        """Find the possible shortcut conflict and return the conflict name."""
        if shortcut:
            item = self.tree.currentItem()
            if not isinstance(item, ShortcutItem):
                return None
            scheme = self.scheme.currentScheme()
            for i in self.items():
                a = i.action(scheme)
                if i != item and a.shortcuts():
                    for s1 in a.shortcuts():
                        if s1.matches(shortcut) or shortcut.matches(s1):
                            return qutil.removeAccelerator(a.text())
        return None

    def editCurrentItem(self):
        item = self.tree.currentItem()
        if not isinstance(item, ShortcutItem):
            return

        dlg = ShortcutEditDialog(self, self.findShortcutConflict)
        scheme = self.scheme.currentScheme()
        action = item.action(scheme)
        default = item.defaultShortcuts() or None
        if dlg.editAction(action, default):
            shortcuts = action.shortcuts()
            # check for conflicts
            conflicting = []
            for i in self.items():
                if i is not item:
                    for s1, s2 in itertools.product(i.shortcuts(scheme), shortcuts):
                        if s1.matches(s2) or s2.matches(s1):
                            conflicting.append(i)
            if conflicting:
                for i in conflicting:
                    l = i.shortcuts(scheme)
                    for s1 in list(l): # copy
                        for s2 in shortcuts:
                            if s1.matches(s2) or s2.matches(s1):
                                l.remove(s1)
                    i.setShortcuts(l, scheme)

            # store the shortcut
            item.setShortcuts(shortcuts, scheme)
            self.changed.emit()

    def updateFilter(self):
        """Called when the search text changes."""
        search = self.searchEntry.text()
        scheme = self.scheme.currentScheme()
        def hidechildren(item):
            hideparent = True
            for n in range(item.childCount()):
                c = item.child(n)
                if c.childCount():
                    # submenu item
                    if hidechildren(c):
                        c.setHidden(True)
                    else:
                        c.setHidden(False)
                        c.setExpanded(True)
                        hideparent = False
                elif isinstance(c, ShortcutItem):
                    # shortcut item, should be the case
                    if c.matches(scheme, search):
                        c.setHidden(False)
                        hideparent = False
                    else:
                        c.setHidden(True)
            return hideparent
        hidechildren(self.tree.invisibleRootItem())
Beispiel #23
0
class PFSNet(QWidget):
    changed = pyqtSignal()

    def __init__(self, id: str, window, tempName=None):
        super(QWidget, self).__init__()
        self._filename = None
        self._filepath = None
        self._tempName = tempName
        self._id = id
        layout = QHBoxLayout()
        self._tab = QTabWidget()
        self._tab.currentChanged.connect(self.changeTab)
        self._tab.setTabsClosable(True)
        self._tab.tabCloseRequested.connect(self.closeTab)
        layout.addWidget(self._tab)
        self.setLayout(layout)
        self._prop = QTableWidget(20, 2)
        self._prop.itemChanged.connect(self.propertiesItemChanged)
        self._prop.verticalHeader().hide()
        self._prop.setColumnWidth(1, 180)
        self._prop.setMaximumWidth(300)
        lv = QVBoxLayout()
        lv.addWidget(self._prop)
        self._tree = QTreeWidget()
        self._tree.itemClicked.connect(self.treeItemClicked)
        self._tree.setMaximumWidth(300)
        lv.addWidget(self._tree)
        layout.addLayout(lv)
        self._pages = []
        self._idPage = 0
        self._sm = window._sm
        self._window = window
        self._distributorId = 0
        self._activityId = 0
        self._relationId = 0
        self._otherId = 0
        self._pageId = 0
        self._page = None
        self._elements = {}
        self.undoStack = QUndoStack(self)
        self.undoAction = self.undoStack.createUndoAction(self, "Desfazer")
        self.undoAction.setShortcuts(QKeySequence.Undo)
        self.undoAction.setIcon(
            QIcon.fromTheme("edit-undo", QIcon("icons/edit-undo.svg")))
        self.redoAction = self.undoStack.createRedoAction(self, "Refazer")
        self.redoAction.setShortcuts(QKeySequence.Redo)
        self.redoAction.setIcon(
            QIcon.fromTheme("edit-redo", QIcon("icons/edit-redo.svg")))
        self._pasteList = []

    def tree(self):
        tree = QTreeWidgetItem(self._tree, ["Net " + self._id], 0)
        child = self._page.tree(tree)
        self._tree.expandAll()
        return tree

    def prepareTree(self):
        self._tree.clear()
        self.tree()

    def showPage(self, widget):
        if widget in self._pages:
            self._tab.setCurrentWidget(widget)
        else:
            self._tab.addTab(widget, widget.name())
            self._pages.append(widget)
            self._tab.setCurrentWidget(widget)

    def removeTabWidget(self, widget):
        for i in range(self._tab.count()):
            if self._tab.widget(i) == widget:
                self._tab.removeTab(i)
                self._pages.remove(widget)

    def propertiesItemChanged(self, item: PFSTableValueText):
        if item.comparePrevious():
            item.edited.emit(item)

    def getAllPages(self):
        ans = []
        ans.append(self._page)
        aux = self._page.getAllSubPages()
        if len(aux) > 0:
            ans = ans + aux
        return ans

    def generateXml(self, xml: QXmlStreamWriter):
        xml.writeStartDocument()
        xml.writeStartElement("PetriNetDoc")
        xml.writeStartElement("net")
        xml.writeAttribute("id", self._id)
        pages = self.getAllPages()
        for p in pages:
            p.generateXml(xml)
        xml.writeEndElement()
        xml.writeEndElement()
        xml.writeEndDocument()

    def treeItemClicked(self, item, col):
        if isinstance(item, PFSTreeItem):
            item.clicked.emit()

    def createFromXml(doc: QDomDocument, window):
        el = doc.documentElement()
        nodes = el.childNodes()
        nets = []
        for i in range(nodes.count()):
            node = nodes.at(i)
            if node.nodeName() != "net":
                continue
            if not (node.hasAttributes() and node.attributes().contains("id")):
                continue
            id = node.attributes().namedItem("id").nodeValue()
            net = PFSNet(id, window)
            nodesPage = node.childNodes()
            pages = []
            for j in range(nodesPage.count()):
                nodePage = nodesPage.at(j)
                if nodePage.nodeName() != "page":
                    continue
                page = PFSPage.createFromXml(nodePage)
                if page is not None:
                    pages.append(page)
            if len(pages) == 0:
                continue
            aux = {}
            for page in pages:
                p = PFSPage.createFromContent(page, window._sm, net)
                if p is not None:
                    i = page._ref
                    if i is None or not i:
                        i = "main"
                    aux[i] = p
            if "main" not in aux.keys():
                continue
            for indice, page in aux.items():
                ids = page.getMaxIds()
                if net._activityId < ids[0] + 1:
                    net._activityId = ids[0] + 1
                if net._distributorId < ids[1] + 1:
                    net._distributorId = ids[1] + 1
                if net._relationId < ids[2] + 1:
                    net._relationId = ids[2] + 1
                if net._otherId < ids[3] + 1:
                    net._otherId = ids[3] + 1
                if net._pageId < int(page._id[1:]) + 1:
                    net._pageId = int(page._id[1:]) + 1
                if indice == "main":
                    net._tab.blockSignals(True)
                    net._tab.addTab(page, page.name())
                    net._tab.blockSignals(False)
                for indice2, page2 in aux.items():
                    elem = page2.getElementById(indice)
                    if elem is not None:
                        page._subRef = elem
                        elem.setSubPage(page)
                        page.setName("Ref_" + elem._id)
                        break
            net._page = aux["main"]
            net._pages.append(aux["main"])
            net.tree()
            nets.append(net)
        return nets

    def getTabName(self) -> str:
        if self._filename is None and self._tempName is None:
            ans = "New model"
        elif self._filename is None:
            ans = self._tempName
        else:
            ans = self._filename
        if self.undoStack.isClean():
            return ans
        return ans + "*"

    def newNet(id, window, tempName="newmodel.xml"):
        ans = PFSNet(id, window, tempName)
        page = PFSPage.newPage(ans.requestId(PFSPage), window._sm, ans)
        ans._page = page
        ans._pages.append(page)
        ans._tab.addTab(page, page.name())
        return ans

    def openPage(self, element):
        if isinstance(element, PFSPage):
            page = element
        elif isinstance(element, PFSActivity):
            page = element.subPage()
        else:
            return
        if page not in self._pages:
            self._tab.addTab(page, page.name())
            self._pages.append(page)
        self._tab.setCurrentWidget(page)

    def createPage(self, element=None):
        page = PFSPage.newPage(self.requestId(PFSPage), self._sm, self, 600,
                               120)
        if element is not None and element.setSubPage(page):
            page.setName("Ref_" + element._id)
            page._subRef = element
            openac = PFSOpenActivity(self.requestId(PFSOpenActivity), 20, 10,
                                     100)
            self.addItemNoUndo(openac, page)
            closeac = PFSCloseActivity(self.requestId(PFSCloseActivity),
                                       page._scene.sceneRect().width() - 20,
                                       10, 100)
            self.addItemNoUndo(closeac, page)
            self._idPage = self._idPage + 1
            self._sm.fixTransitions(page._scene)
            return page
        return None

    def deleteElements(self):
        if len(self._pages) == 0:
            return
        scene = self._tab.currentWidget()._scene
        itemsSeleted = scene.selectedItems()
        if len(itemsSeleted) == 0:
            if self._tab.currentWidget() == self._page:
                return
            x = PFSUndoDeletePage(self._tab.currentWidget())
            self.undoStack.push(x)
            return
        itemsDeleted = []
        for item in itemsSeleted:
            if not item.canDelete():
                continue
            if isinstance(item, PFSNode):
                item.deleted.emit()
            itemsDeleted.append(item)
        if len(itemsDeleted) > 0:
            x = PFSUndoDelete(itemsDeleted)
            self.undoStack.push(x)

    def pasteElements(self, elements):
        self._pasteList = elements

    def pasteItems(self, pos):
        ans = []
        aux = {}
        for elem in self._pasteList:
            if isinstance(elem, PFSRelationContent) or isinstance(
                    elem, PFSSecondaryFlowContent):
                continue
            oldId = elem._id
            id = self.requestId(elem)
            if isinstance(elem, PFSActivityContent):
                e = PFSActivity.paste(elem, id, pos.x(), pos.y())
                ans.append(e)
                aux[oldId] = e
            elif isinstance(elem, PFSDistributorContent):
                e = PFSDistributor.paste(elem, id, pos.x(), pos.y())
                ans.append(e)
                aux[oldId] = e
        for elem in self._pasteList:
            if isinstance(elem, PFSRelationContent):
                oldId = elem._id
                id = self.requestId(elem)
                e = PFSRelation.paste(elem, id, pos.x(), pos.y(), aux)
                ans.append(e)
            elif isinstance(elem, PFSSecondaryFlowContent):
                oldId = elem._id
                id = self.requestId(elem)
                e = PFSSecondaryFlow.paste(elem, id, pos.x(), pos.y(), aux)
                ans.append(e)
        x = PFSUndoAdd(ans, self._tab.currentWidget()._scene)
        self.undoStack.push(x)

    def export(self, filename):
        if len(self._pages) > 1:
            scene = self._tab.currentWidget()._scene
        elif len(self._pages) == 1:
            scene = self._pages[0]._scene
        else:
            return
        if filename.endswith(".png"):
            PFSImage.gravaPng(scene, filename)
        else:
            PFSImage.gravaSvg(scene, filename)

    def addItem(self, element, page: PFSPage):
        if isinstance(element, PFSRelation):
            if isinstance(element._source, PFSActive) and isinstance(
                    element._target, PFSActive):
                return False
            if isinstance(element._source, PFSPassive) and isinstance(
                    element._target, PFSPassive):
                return False
        x = PFSUndoAdd([element], page._scene)
        self.undoStack.push(x)
        return True

    def addItemNoUndo(self, element, page: PFSPage):
        if isinstance(element, PFSRelation):
            if isinstance(element._source, PFSActive) and isinstance(
                    element._target, PFSActive):
                return False
            if isinstance(element._source, PFSPassive) and isinstance(
                    element._target, PFSPassive):
                return False
        page._scene.addItem(element)
        page._scene.update()
        return True

    def requestId(self, element):
        if element == PFSActivity or isinstance(element, PFSActivityContent):
            ans = "A" + str(self._activityId)
            self._activityId = self._activityId + 1
        elif element == PFSDistributor or isinstance(element,
                                                     PFSDistributorContent):
            ans = "D" + str(self._distributorId)
            self._distributorId = self._distributorId + 1
        elif element == PFSRelation:
            ans = "R" + str(self._relationId)
            self._relationId = self._relationId + 1
        elif element == PFSPage:
            ans = "P" + str(self._pageId)
            self._pageId = self._pageId + 1
        else:
            ans = "O" + str(self._otherId)
            self._otherId = self._otherId + 1
        return ans

    def changeTab(self, index: int):
        self._prop.clear()
        self._tree.clear()
        self.tree()
        if index < 0:
            return
        self._tab.widget(index)._scene.clearSelection()
        self._window._main.tabChanged.emit()

    def fillProperties(self, props):
        if len(props) > 0:
            self._prop.setRowCount(0)
            self._prop.setRowCount(len(props))
            i = 0
            for line in props:
                if isinstance(line[0], QTableWidgetItem):
                    self._prop.setItem(i, 0, line[0])
                else:
                    self._prop.setCellWidget(i, 0, line[0])
                if isinstance(line[1], QTableWidgetItem):
                    self._prop.setItem(i, 1, line[1])
                else:
                    self._prop.setCellWidget(i, 1, line[1])
                if isinstance(line[0], PFSTableLabelTags):
                    self._prop.setRowHeight(i, 100)
                i = i + 1

    def closeTab(self, ind):
        w = self._tab.widget(ind)
        self._pages.remove(w)
        self._tab.removeTab(ind)
class BookmarksWindow(QDialog):
    """
    A simple UI for showing bookmarks and navigating to them.

    FIXME: For now, this window is tied to a particular lane.
           If your project has more than one lane, then each one
           will have it's own bookmark window, which is kinda dumb.
    """
    def __init__(self, parent, topLevelOperatorView):
        super(BookmarksWindow, self).__init__(parent)
        self.setWindowTitle("Bookmarks")
        self.topLevelOperatorView = topLevelOperatorView
        self.bookmark_tree = QTreeWidget(self)
        self.bookmark_tree.setHeaderLabels( ["Location", "Notes"] )
        self.bookmark_tree.setSizePolicy( QSizePolicy.Preferred, QSizePolicy.Preferred )
        self.bookmark_tree.setColumnWidth(0, 200)
        self.bookmark_tree.setColumnWidth(1, 300)

        self.note_edit = QLineEdit(self)
        self.add_bookmark_button = QPushButton("Add Bookmark", self, clicked=self.add_bookmark)

        geometry = self.geometry()
        geometry.setSize( QSize(520, 520) )
        self.setGeometry(geometry)
        
        layout = QVBoxLayout()
        layout.addWidget(self.bookmark_tree)
        layout.addWidget(self.note_edit)
        layout.addWidget(self.add_bookmark_button)
        self.setLayout(layout)

        self._load_bookmarks()
        
        self.bookmark_tree.setContextMenuPolicy( Qt.CustomContextMenu )
        self.bookmark_tree.customContextMenuRequested.connect( self.showContextMenu )
        
        self.bookmark_tree.itemDoubleClicked.connect(self._handle_doubleclick)

    def _handle_doubleclick(self, item, col):
        """
        Navigate to the bookmark
        """
        data = item.data(0, Qt.UserRole).toPyObject()
        if data is None:
            return

        (coord, notes) = data
        axes = self.topLevelOperatorView.InputImages.meta.getAxisKeys()
        axes = axes[:-1] # drop channel
        axes = sorted(axes)
        assert len(axes) == len(coord)
        tagged_coord = dict(list(zip(axes, coord)))
        tagged_location = OrderedDict(list(zip('txyzc', (0,0,0,0,0))))
        tagged_location.update(tagged_coord)
        t = list(tagged_location.values())[0]
        coord3d = list(tagged_location.values())[1:4]
        
        self.parent().editor.posModel.time = t
        self.parent().editor.navCtrl.panSlicingViews( coord3d, [0,1,2] )
        self.parent().editor.posModel.slicingPos = coord3d

    def showContextMenu(self, pos):
        item = self.bookmark_tree.itemAt(pos)
        data = item.data(0, Qt.UserRole).toPyObject()
        if data is None:
            return
        
        def delete_bookmark():
            (coord, notes) = data
            bookmarks = list(self.topLevelOperatorView.Bookmarks.value)
            i = bookmarks.index((coord, notes))
            bookmarks.pop(i)
            self.topLevelOperatorView.Bookmarks.setValue(bookmarks)
            self._load_bookmarks()

        menu = QMenu(parent=self)
        menu.addAction( QAction("Delete", menu, triggered=delete_bookmark) )
        globalPos = self.bookmark_tree.viewport().mapToGlobal( pos )
        menu.exec_( globalPos )
        #selection = menu.exec_( globalPos )
        #if selection is removeLanesAction:
        #    self.removeLanesRequested.emit( self._selectedLanes )

    def add_bookmark(self):
        coord_txyzc = self.parent().editor.posModel.slicingPos5D
        tagged_coord_txyzc = dict( list(zip('txyzc', coord_txyzc)) )
        axes = self.topLevelOperatorView.InputImages.meta.getAxisKeys()
        axes = axes[:-1] # drop channel
        axes = sorted(axes)
        coord = tuple(tagged_coord_txyzc[c] for c in axes)

        notes = str(self.note_edit.text())
        bookmarks = list(self.topLevelOperatorView.Bookmarks.value)
        bookmarks.append((coord, notes))
        self.topLevelOperatorView.Bookmarks.setValue(bookmarks)
        
        self._load_bookmarks()
    
    def _load_bookmarks(self):
        self.bookmark_tree.clear()
        lane_index = self.topLevelOperatorView.current_view_index()
        lane_nickname = self.topLevelOperatorView.InputImages.meta.nickname or "Lane {}".format(lane_index)
        bookmarks = self.topLevelOperatorView.Bookmarks.value
        group_item = QTreeWidgetItem( self.bookmark_tree, [lane_nickname] )

        for coord, notes in bookmarks:
            item = QTreeWidgetItem( group_item, [] )
            item.setText(0, str(coord))
            item.setData(0, Qt.UserRole, (coord, notes))
            item.setText(1, notes)

        self.bookmark_tree.expandAll()
Beispiel #25
0
class show_help_browser(QDialog):
    def __init__(self, parent=None):
        super(show_help_browser, self).__init__(parent)

        self.resize(900, 600)
        self.setWindowTitle('Functions help')
        ssDir = os.path.join(HERE, "..", "_tools", "")
        self.setWindowIcon(QIcon(os.path.join(ssDir, 'toto.ico')))

        sshFile = os.path.join(ssDir, 'TCobra.qss')
        with open(sshFile, "r") as fh:
            self.setStyleSheet(fh.read())

        layout = QHBoxLayout()
        self.tree = QTreeWidget()
        layout.addWidget(self.tree)

        self.message = QTextBrowser()
        #self.message.setReadOnly(False)
        self.message.setOpenExternalLinks(True)
        layout.addWidget(self.message)

        self.setLayout(layout)
        self.initTree()

        self.tree.selectionModel().selectionChanged.connect(
            self.update_message)

    def initTree(self):
        all_dirs = dir(toto)
        modules = [
            x for x in all_dirs if not x.startswith('_') and x != 'core'
        ]
        for module in modules:
            parent = QTreeWidgetItem(self.tree.invisibleRootItem())
            parent.setText(0, module)
            fcts = dir(getattr(toto, module))
            fcts = [x for x in fcts if not x.startswith('_')]
            for fct in fcts:
                child = QTreeWidgetItem(parent)
                child.setText(0, fct)
                if module == 'plugins':
                    subs = dir(getattr(getattr(toto, module), fct))
                    subs = [
                        x.replace('_', ' ') for x in subs
                        if not x.startswith('_')
                    ]
                    for sub in subs:
                        child2 = QTreeWidgetItem(child)
                        child2.setText(0, sub)

        self.tree.expandAll()
        self.tree.setHeaderLabel('Module')

    def update_message(self):
        item = self.tree.currentItem()
        if item:
            if item.parent():

                module = item.parent().text(0)
                fct = item.text(0)
                if item.parent().parent():
                    fct = fct.replace(' ', '_')
                    module0 = item.parent().parent().text(0)
                    f = getattr(getattr(getattr(toto, module0), module), fct)
                else:
                    f = getattr(getattr(toto, module), fct)
                mms = _str2html(inspect.getdoc(f))

                self.message.setText(mms)
class Preferences(QDialog):
#
    configuration = {}
    weight = 0
#
    savePreferences = pyqtSignal()
#
    def __init__(self, parent=None):
        super(Preferences, self).__init__(parent, Qt.Dialog)
        self.setWindowTitle(translations.TR_PREFERENCES_TITLE)
        self.setMinimumSize(QSize(900, 600))
        vbox = QVBoxLayout(self)
        hbox = QHBoxLayout()
        vbox.setContentsMargins(0, 0, 5, 5)
        hbox.setContentsMargins(0, 0, 0, 0)
#
        self.tree = QTreeWidget()
        self.tree.header().setHidden(True)
        self.tree.setSelectionMode(QTreeWidget.SingleSelection)
        self.tree.setAnimated(True)
        self.tree.header().setHorizontalScrollMode(
            QAbstractItemView.ScrollPerPixel)
        self.tree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
        self.tree.setFixedWidth(200)
        self.stacked = QStackedLayout()
        hbox.addWidget(self.tree)
        hbox.addLayout(self.stacked)
        vbox.addLayout(hbox)
#
        hbox_footer = QHBoxLayout()
        self._btnSave = QPushButton(translations.TR_SAVE)
        self._btnCancel = QPushButton(translations.TR_CANCEL)
        hbox_footer.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding))
        hbox_footer.addWidget(self._btnCancel)
        hbox_footer.addWidget(self._btnSave)
        vbox.addLayout(hbox_footer)
#
        self.tree.itemSelectionChanged.connect(self._change_current)
        self._btnCancel.clicked['bool'].connect(self.close)
        self._btnSave.clicked['bool'].connect(self._save_preferences)
#
        self.load_ui()
        self.tree.setCurrentItem(self.tree.topLevelItem(0))
#
    def _save_preferences(self):
        self.savePreferences.emit()
        self.close()
#
    def load_ui(self):
        sections = sorted(
            list(Preferences.configuration.keys()),
            key=lambda item: Preferences.configuration[item]['weight'])
        for section in sections:
            text = Preferences.configuration[section]['text']
            Widget = Preferences.configuration[section]['widget']
            widget = Widget(self)
            area = QScrollArea()
            area.setWidgetResizable(True)
            area.setWidget(widget)
            self.stacked.addWidget(area)
            index = self.stacked.indexOf(area)
            item = QTreeWidgetItem([text])
            item.setData(0, Qt.UserRole, index)
            self.tree.addTopLevelItem(item)
#
            #Sort Item Children
            subcontent = Preferences.configuration[section].get(
                'subsections', {})
            subsections = sorted(list(subcontent.keys()),
                                 key=lambda item: subcontent[item]['weight'])
            for sub in subsections:
                text = subcontent[sub]['text']
                Widget = subcontent[sub]['widget']
                widget = Widget(self)
                area = QScrollArea()
                area.setWidgetResizable(True)
                area.setWidget(widget)
                self.stacked.addWidget(area)
                index = self.stacked.indexOf(area)
                subitem = QTreeWidgetItem([text])
                subitem.setData(0, Qt.UserRole, index)
                item.addChild(subitem)
#
        self.tree.expandAll()
#
    def _change_current(self):
        item = self.tree.currentItem()
        index = item.data(0, Qt.UserRole)
        self.stacked.setCurrentIndex(index)
#
    @classmethod
    def register_configuration(cls, section, widget, text, weight=None,
                               subsection=None):
        if weight is None:
            Preferences.weight += 1
            weight = Preferences.weight
        if not subsection:
            Preferences.configuration[section] = {'widget': widget,
                                                  'weight': weight,
                                                  'text': text}
        else:
            config = Preferences.configuration.get(section, {})
            if not config:
                config[section] = {'widget': None, 'weight': 100}
            subconfig = config.get('subsections', {})
            subconfig[subsection] = {'widget': widget, 'weight': weight,
                                     'text': text}
            config['subsections'] = subconfig
            Preferences.configuration[section] = config
Beispiel #27
0
class May2SynthWidget(QWidget):

    paramChanged = pyqtSignal(Param)
    randomsChanged = pyqtSignal(list)
    activated = pyqtSignal()

    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.synth = None
        self.params = []
        self.selectedParam = None
        self.selectedSegment = None
        self.randoms = []
        self.selectedRandom = None

        self.active = False
        self.justUpdatingRandomWidget = False
        self.initLayout()
        self.initSignals()

    def initLayout(self):
        self.mainLayout = QHBoxLayout(self)

        self.paramEditLayout = QVBoxLayout()
        self.reloadFromSynButton = QPushButton("Reload from .syn", self)
        self.reloadFromSynButton.setEnabled(False)
        self.paramEditButton = QPushButton("Edit Selected", self)
        self.paramEditButton.setEnabled(False)
        self.newSegmentButton = QPushButton("New Segment", self)
        self.newSegmentButton.setEnabled(False)
        self.paramEditLayout.addWidget(self.reloadFromSynButton)
        self.paramEditLayout.addWidget(self.paramEditButton)
        self.paramEditLayout.addWidget(self.newSegmentButton)

        self.mainLayout.addLayout(self.paramEditLayout)

        self.paramWidget = QTreeWidget(self)
        self.paramWidget.setHeaderHidden(True)
        self.paramWidget.setItemsExpandable(False)
        self.mainLayout.addWidget(self.paramWidget)

        self.randomEditLayout = QVBoxLayout()
        self.reshuffleButton = QPushButton("reshuffle", self)
        self.reshuffleButton.setEnabled(False)
        self.hardcopyButton = QPushButton("hardcopy", self)
        self.hardcopyButton.setEnabled(False)
        self.setFixedButton = QPushButton("fix/free all", self)
        self.setFixedButton.setEnabled(False)
        self.randomEditLayout.addWidget(self.reshuffleButton)
        self.randomEditLayout.addWidget(self.hardcopyButton)
        self.randomEditLayout.addWidget(self.setFixedButton)
        self.mainLayout.addLayout(self.randomEditLayout)

        self.randomWidget = QTableWidget(self)
        self.randomWidget.setColumnCount(6)
        self.randomWidget.verticalHeader().hide()
        self.mainLayout.addWidget(self.randomWidget)

        self.setLayout(self.mainLayout)

    def initSignals(self):
        self.paramWidget.itemClicked.connect(self.selectParam)
        self.paramWidget.itemDoubleClicked.connect(self.editSelectedParam)
        self.reloadFromSynButton.clicked.connect(self.reloadFromSyn)
        self.paramEditButton.clicked.connect(self.editSelectedParam)
        self.newSegmentButton.clicked.connect(self.newSegment)
        self.randomWidget.currentItemChanged.connect(self.selectRandom)
        self.randomWidget.itemChanged.connect(self.editRandom)
        self.reshuffleButton.clicked.connect(self.reshuffleRandoms)
        self.hardcopyButton.clicked.connect(self.hardcopySynth)
        self.setFixedButton.clicked.connect(self.setAllFixedOrFree)

    def getSynthName(self):
        return self.synth.name if self.synth is not None else None

    def setSynth(self, synth):
        self.synth = synth
        self.params = []
        if self.synth is not None:
            for paramID in self.synth.usedParams:
                param = self.getParamOverride(paramID)
                if param is None:
                    param = Param(self.synth.usedParams[paramID])
                self.params.append(param)
        self.selectedParam = None
        self.selectedSegment = None
        self.updateParamWidget()

        self.randoms = []
        if self.synth is not None:
            for randomID in self.synth.usedRandoms:
                random = self.getRandom(randomID)
                if random is None:
                    random = RandomValue(self.synth.usedRandoms[randomID])
                self.randoms.append(random)
        self.selectedRandom = None
        self.updateRandomWidget()

############################## PARAMS ###############################

    def updateParamWidget(self):
        self.paramWidget.clear()
        for param in self.params:
            paramItem = QTreeWidgetItem([param.__str__()])
            for seg in param.segments:
                paramItem.addChild(QTreeWidgetItem([seg.__str__()]))
            self.paramWidget.addTopLevelItem(paramItem)
        self.paramWidget.expandAll()
        self.paramWidget.setStyleSheet("background-color: red;" if self.
                                       findParamSegmentCollisions() else "")
        self.updateParamButtons()

    def updateParamButtons(self):
        self.reloadFromSynButton.setEnabled(self.selectedParam is not None)
        self.paramEditButton.setEnabled(self.selectedParam is not None)
        self.newSegmentButton.setEnabled(self.selectedParam is not None)

    def selectParam(self, item, column=None):
        self.selectedParam = self.params[self.paramWidget.indexOfTopLevelItem(
            item)]
        if item.parent() is None:
            self.selectedSegment = None
        else:
            segmentIndex = self.paramWidget.indexFromItem(item).row()
            self.selectedSegment = self.selectedParam.getSegmentAtIndex(
                segmentIndex)
        self.updateParamButtons()

    def editSelectedParam(self, item=None, column=0):
        if self.selectedSegment is None:
            paramDefault, ok = QInputDialog.getDouble(
                self,
                'Edit Parameter Default',
                f'Default Value for Parameter:\n{self.selectedParam.id}',
                self.selectedParam.default,
                decimals=3)
            if not ok:
                return
            self.selectedParam.default = paramDefault
        else:
            print(self.selectedSegment)
            segmentDialog = SegmentDialog(self.parent,
                                          self.selectedParam,
                                          segment=self.selectedSegment)
            if not segmentDialog.exec_():
                return
            self.selectedParam.updateSegment(self.selectedSegment,
                                             segmentDialog.getSegment())
        self.paramChanged.emit(self.selectedParam)
        self.updateParamWidget()

    def newSegment(self):
        segmentDialog = SegmentDialog(self.parent, self.selectedParam)
        if segmentDialog.exec_():
            self.selectedParam.addSegment(segmentDialog.getSegment())
            self.paramChanged.emit(self.selectedParam)
            self.updateParamWidget()

    def findParamSegmentCollisions(self):
        for param in self.params:
            if param.hasCollidingSegments():
                return True
        return False

    def getParamOverride(self, paramID):
        return self.parent.synthModel.paramOverrides.get(paramID, None)

    def reloadFromSyn(self):
        if self.selectedParam is None:
            return
        print(
            "Reload From .Syn is not properly implemented yet. For now, just erase the paramOverride in the synthModel..."
        )
        self.parent.synthModel.deleteParamOverride(
            self.selectedParam.id)  # TODO: actually, do it via signal as well
        self.setSynth(self.synth)

############################## RANDOM VALUES ###############################

    def updateRandomWidget(self):
        self.randomWidget.clear()
        self.justUpdatingRandomWidget = True
        self.randomWidget.setRowCount(0)
        for row, random in enumerate(self.randoms):
            self.randomWidget.insertRow(row)
            for col, content in enumerate(random.getRow()):
                item = QTableWidgetItem(str(content))
                if col == random.idColumn:
                    item.setFlags(Qt.ItemIsEnabled)
                elif col == random.fixedColumn:
                    item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
                    item.setText('fixed')
                    item.setCheckState(Qt.Checked if content else Qt.Unchecked)
                else:
                    item.setFlags(Qt.ItemIsEditable | Qt.ItemIsEnabled)
                self.randomWidget.setItem(row, col, item)
        self.randomWidget.resizeColumnsToContents()
        self.randomWidget.setHorizontalHeaderLabels(
            ['ID', 'value', 'min', 'max', 'digits', 'fixed?'])
        self.justUpdatingRandomWidget = False
        self.updateRandomButtons()

    def updateRandomWidgetColumn(self, col):
        self.justUpdatingRandomWidget = True
        for row in range(self.randomWidget.rowCount()):
            item = self.randomWidget.item(row, col)
            newContent = self.randoms[row].getRow()[col]
            if col == RandomValue.fixedColumn:
                item.setCheckState(Qt.Checked if newContent else Qt.Unchecked)
            else:
                item.setText(str(newContent))
        self.randomWidget.resizeColumnsToContents()
        self.justUpdatingRandomWidget = False

    def updateRandomButtons(self):
        self.reshuffleButton.setEnabled(len(self.randoms) > 0)
        self.hardcopyButton.setEnabled(len(self.randoms) > 0)
        self.setFixedButton.setEnabled(len(self.randoms) > 0)

    def getRandom(self, randomID):
        return self.parent.synthModel.randomValues.get(randomID, None)

    def selectRandom(self, item, prevItem=None):
        validItem = item is not None and len(self.randoms) > item.row()
        self.selectedRandom = self.randoms[item.row()] if validItem else None

    def editRandom(self, item):
        if self.justUpdatingRandomWidget:
            return

        self.selectRandom(item)

        if self.selectedRandom is not None:
            if item.column() == RandomValue.idColumn:
                pass
            elif item.column() == RandomValue.valueColumn:
                self.selectedRandom.value = float(item.text())
            elif item.column() == RandomValue.minColumn:
                self.selectedRandom.min = float(item.text())
            elif item.column() == RandomValue.maxColumn:
                self.selectedRandom.max = float(item.text())
            elif item.column() == RandomValue.digitsColumn:
                self.selectedRandom.digits = int(item.text())
            elif item.column() == RandomValue.fixedColumn:
                self.selectedRandom.fixed = (item.checkState() == Qt.Checked)

            self.randomsChanged.emit([self.selectedRandom])

    def reshuffleRandoms(self):
        for random in self.randoms:
            random.reshuffle()
        self.randomsChanged.emit(self.randoms)
        self.updateRandomWidgetColumn(RandomValue.valueColumn)

    def hardcopySynth(self):
        print(
            "should implement this, but for now, just write the values to this terminal:"
        )
        for random in self.randoms:
            print(random.getRow())
        self.parent.hardcopySynth(self.synth, self.randoms)
        #TODO: "softcopy": connect this with storeValue

    def setAllFixedOrFree(self):
        anyFixed = any([random.fixed for random in self.randoms])
        for random in self.randoms:
            random.fixed = not anyFixed
        self.updateRandomWidgetColumn(RandomValue.fixedColumn)

################################################################################

    def debugOutput(self):
        print("RANDOM VALUES STORED IN SYNTH MODEL:")
        for r in self.parent.synthModel.randomValues:
            print(r)

        print("SYNTH FORMS WITH ARGUMENTS")
        for s in self.parent.synthModel.synths:
            print(s.name, ' --> ', s.args)
Beispiel #28
0
class ManageRooms(QWidget):
    """
        Summary: This class will display the manage rooms window
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # TODO: Fix table so that it only has entries for how many devices are in each room
        # TODO: Make add and remove device functions.
        # TODO: Add function to count devices based on room in db_interface

        self.path = os.path.dirname(os.path.abspath(__file__))
        os.chdir(self.path)

        # Connects the application to the database
        self.db = Database()
        self.db.connectToDatabase()

        # Initiates a layout and a tree widget
        self.layout = QVBoxLayout(self)
        self.roomTree = QTreeWidget()
        self.roomTree.setHeaderLabels(["Bedrooms"])

        self.populateTable()

        self.buttonLayout = QHBoxLayout()
        self.addDevice = QPushButton("Add Device")
        self.removeButton = QPushButton("Remove Device")

        self.buttonLayout.addWidget(self.addDevice)
        self.buttonLayout.addWidget(self.removeButton)

        self.addDevice.clicked.connect(self.deviceAdd)
        self.removeButton.clicked.connect(self.deviceRemove)

        # Adds the dock widget to the main layout for the manage room plane
        self.layout.addWidget(self.roomTree)
        self.layout.addLayout(self.buttonLayout)

    def populateTable(self):
        """
            Summary: Since this table will be updated regularly via adding and removing
                devices, it is given its own function which first destroys the table then
                rebuilds it from the top
        """
        rooms = self.db.getRooms()

        self.roomTree.clear()

        for room in range(0, len(rooms)):
            roomName = rooms[room][0]
            root = QTreeWidgetItem(self.roomTree, [roomName])

            devices = self.db.getDevices(roomName)

            # Adds all of the devices to the room specific tree
            for dev in range(0, len(devices)):
                deviceName = devices[dev][0]
                child = QTreeWidgetItem(root, [deviceName])

        self.roomTree.expandAll()

#///////////////////////////////////////////////////////////////////// Device add functions

    def deviceAdd(self):
        """
        """
        # Add to Custom Dialog class
        newAddition = QDialog()
        dialogLayout = QVBoxLayout(newAddition)

        # Widget for the access combo box
        self.accessBox = QComboBox()
        self.accessBox.setEditable(False)

        # Gets rooms from the database and adds them to the combo box
        rooms = self.db.getRooms()
        for room_index in range(0, self.db.countRooms()[0]):
            self.accessBox.addItem(rooms[room_index][0])

        self.deviceName = QLineEdit()
        self.deviceImportance = QLineEdit()
        self.devicePurpose = QLineEdit()

        # Form for the user to enter in new device information
        formLayout = QFormLayout()
        formLayout.addRow(QLabel("Device Name"), self.deviceName)
        formLayout.addRow(QLabel("Device Importance"), self.deviceImportance)
        formLayout.addRow(QLabel("Device Purpose"), self.devicePurpose)
        formLayout.addRow(QLabel("Device Location"), self.accessBox)

        # Adds the okay and cancel button at the bottom
        QBtn = QDialogButtonBox.Ok

        buttonBox = QDialogButtonBox(QBtn)
        buttonBox.accepted.connect(self.accept)

        dialogLayout.addLayout(formLayout)
        dialogLayout.addWidget(buttonBox)

        newAddition.setWindowTitle("Add Device")
        newAddition.exec_()

    def accept(self):
        """
            Summary: Loads new device information into the database
        """
        # adds the device to the database
        self.db.addDevice(self.deviceName.text(), self.devicePurpose.text(),
                          self.deviceImportance.text(),
                          self.accessBox.currentText())
        self.db.commitChanges()
        self.populateTable()

        # Logs the new addition
        logging.info("Added new device: {}".format(self.deviceName.text()))

        # Clears the from on the add button dialog
        self.deviceName.setText("")
        self.deviceImportance.setText("")
        self.devicePurpose.setText("")
        self.accessBox.setCurrentIndex(0)

#///////////////////////////////////////////////////////////////////// Device Remove Functions

    def deviceRemove(self):
        """
            Summary: Displays a table of ever device for users to remove
        """
        removeDeviceDialog = QDialog()

        dialogLayout = QVBoxLayout(removeDeviceDialog)

        devices = self.db.getDevices()
        deviceCount = len(devices)

        self.removeDeviceTable = QTableWidget(self.db.countDevices()[0], 5,
                                              self)
        self.removeDeviceTable.setHorizontalHeaderLabels(
            ["Name", "Purpose", "Importance", "Location", "Remove"])

        # Formats the table to fill up all avaliable space
        self.removeDeviceTable.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeMode(1))
        self.removeDeviceTable.horizontalHeader().setSectionResizeMode(
            4, QHeaderView.ResizeMode(2))

        # Here is where all of the information is unpacked and inserted into the table
        for deviceIndex in range(0, deviceCount):
            deviceName = QTableWidgetItem("{}".format(devices[deviceIndex][0]))
            devicePurpose = QTableWidgetItem("{}".format(
                devices[deviceIndex][1]))
            deviceImportance = QTableWidgetItem("{}".format(
                devices[deviceIndex][2]))
            deviceLocation = QTableWidgetItem("{}".format(
                devices[deviceIndex][3]))
            deviceRemove = QPushButton("Kill")

            self.removeDeviceTable.setItem(deviceIndex, 0, deviceName)
            self.removeDeviceTable.setItem(deviceIndex, 1, devicePurpose)
            self.removeDeviceTable.setItem(deviceIndex, 2, deviceImportance)
            self.removeDeviceTable.setItem(deviceIndex, 3, deviceLocation)
            self.removeDeviceTable.setCellWidget(deviceIndex, 4, deviceRemove)

            deviceRemove.clicked.connect(self.killDevice)

        dialogLayout.addWidget(self.removeDeviceTable)

        removeDeviceDialog.exec_()

    def killDevice(self):
        buttonClicked = self.sender()
        index = self.removeDeviceTable.indexAt(buttonClicked.pos())
        deviceRow = index.row()

        # User name is extracted from the table then removed
        item = self.removeDeviceTable.item(deviceRow, 0)
        deviceName = item.text()

        self.removeDeviceTable.removeRow(deviceRow)

        self.db.removeDevice(deviceName)
        self.db.commitChanges()

        self.populateTable()
Beispiel #29
0
class CenterWindow(QWidget):
	position_pattern = re.compile(".*?(\d+).*?(\d+).*")
	laster_status = 0  # 0是关闭 1是打开
	biglaster_status=0 # 0是关闭 1是打开

	movie_pattern = re.compile("[A-Za-z]+_(?P<time>\d+).avi")
	tree_firsttext_pattern = re.compile("\((.*?),(.*?)\)")

	def __init__(self):
		super().__init__()
		self.bag_positions_childs = []
		self.setupUi()
		# self.dock = QDockWidget("move_direct", self)
		# self.dock.resize(300,300)
		# self.dock_img =QLabel(self.dock)
		# self.dock_img.resize(300,300)
		# self.dock.setWidget(self.dock_img)
		self.plchandle = PlcHandle(plc_port=PLC_COM)
		self.step = 20  # 默认步长
		# self.process = IntelligentProcess(IMGHANDLE=None, img_play=self.final_picture_label, plchandle=self.plchandle,
		#                                   error_widget=self.checkerror_widget,dock_img_player=self.dock_img)
		self.process = IntelligentProcess(IMGHANDLE=None, img_play=self.final_picture_label, plchandle=self.plchandle)
		self.process.intelligentthread.add_scan_bag_signal.connect(self.add_scan_bag)
		self.process.intelligentthread.move_to_bag_signal.connect(self.move_to_bag_slot)
		self.process.intelligentthread.error_show_signal.connect(self.show_error_info)
		self.process.intelligentthread.ariver_advice.connect(self.arrive_show)
		self.process.intelligentthread.detectorhandle.send_warn_info.connect(self.show_warn_info)
		self.init_button()
		self.positions = set()
		self.big = True

	def mousePressEvent(self, event):
		if event.buttons() == Qt.LeftButton:
			if event.buttons() == Qt.LeftButton:
				self.big = not self.big
				if not self.isMaximized():
					self.showMaximized()
				else:
					self.showNormal()

	def setupUi(self):
		self.setObjectName("Form")
		all_layout = QHBoxLayout()

		# self.videoBox = QtWidgets.QGroupBox(self)
		# self.videoBox.setObjectName("videoBox")
		# all_layout.addWidget(self.videoBox)

		self.show_all = ShowWidget()

		# self.final_picture_label = QLabel(self)
		# self.final_picture_label.setObjectName("final_picture_label")
		self.final_picture_label = self.show_all.final_picture_label

		# video_layout = QtWidgets.QGridLayout()
		# video_layout.addWidget(self.show_all, 0, 0)
		# self.videoBox.setLayout(video_layout)

		all_layout.addWidget(self.show_all)

		# 右侧按钮操作区域
		self.operatorBox = QGroupBox(self)
		self.operatorBox.setObjectName("operatorBox")
		all_layout.addWidget(self.operatorBox)

		operator_layout = QVBoxLayout()

		# 准备区
		self.prepareBox = QGroupBox(self)
		self.prepareBox.setObjectName("prepareBox")
		self.prepareBox.setTitle("准备区")
		prepare_layout = QGridLayout()
		self.prepareBox.setLayout(prepare_layout)

		self.load_button = QPushButton(self)
		self.load_button.setToolTip("行车初始化")
		self.load_button.setText("行车加载")
		self.load_button.setIcon(QIcon(":icons/load.png"))
		self.load_button.setIconSize(QSize(40, 40))

		self.load_button.setObjectName("init_button")
		prepare_layout.addWidget(self.load_button, *(0, 0, 1, 1))
		self.open_sdkcamera_button = QPushButton(self)
		self.open_sdkcamera_button.setToolTip("打开摄像")
		self.open_sdkcamera_button.setText("打开摄像")
		self.open_sdkcamera_button.setIcon(QIcon(":icons/camera.png"))
		self.open_sdkcamera_button.setIconSize(QSize(40, 40))
		# self.open_sdkcamera_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.open_sdkcamera_button.setObjectName("open_sdkcamera_button")
		# self.open_sdkcamera_button.setStyleSheet("border:none")
		prepare_layout.addWidget(self.open_sdkcamera_button, 0, 1, 1, 1)
		self.lamp_open_button = QPushButton(self)
		# self.lamp_open_button.setToolTip("打开照明灯")
		self.lamp_open_button.setText("打开照明灯")
		self.lamp_open_button.setIcon(QIcon(":icons/lamp.png"))
		self.lamp_open_button.setIconSize(QSize(40, 40))
		# self.x_center_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.lamp_open_button.setObjectName("lamp_open_button")
		# self.x_center_button.setStyleSheet("border:none")
		prepare_layout.addWidget(self.lamp_open_button, *(0, 2, 1, 1))

		self.turnon_laster_button = QPushButton(self)
		self.turnon_laster_button.setToolTip("开启激光灯")
		self.turnon_laster_button.setText("开启激光灯")
		self.turnon_laster_button.setIcon(QIcon(":icons/laster.png"))
		self.turnon_laster_button.setIconSize(QSize(40, 40))
		self.turnon_laster_button.setObjectName("turnon_laster_button")
		prepare_layout.addWidget(self.turnon_laster_button, *(0, 3, 1, 1))

		self.turnon_biglaster_button = QPushButton(self)
		self.turnon_biglaster_button.setToolTip("开启大射灯")
		self.turnon_biglaster_button.setText("开启大射灯")
		self.turnon_biglaster_button.setIcon(QIcon(":icons/laster.png"))
		self.turnon_biglaster_button.setIconSize(QSize(40, 40))
		self.turnon_biglaster_button.setObjectName("turnon_biglaster_button")
		prepare_layout.addWidget(self.turnon_biglaster_button, *(1, 0, 1, 1))

		self.speed_label = QLabel(self)
		self.speed_label.setText("行车速度")
		prepare_layout.addWidget(self.speed_label, *(2, 0, 1, 1))
		# 步数设置
		self.speed_slide = QSlider(Qt.Horizontal)
		self.speed_slide.setToolTip("设置行车速度")
		# 最小值
		self.speed_slide.setMinimum(650)
		# # 设置最大值
		self.speed_slide.setMaximum(950)
		# self.speed_slide.setSingleStep(10)
		self.speed_slide.setValue(700)
		self.speed_slide.setTickPosition(QSlider.TicksBelow)
		self.speed_slide.setTickInterval(100)
		self.speed_slide.setStyleSheet("""
								QSlider:sub-page:horizontal
								{
								border: 1px solid yellow; 
								background:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 yellow, stop:1 yellow); 
								border-radius: 3px;
								height: 8px; 
								}
							""")
		prepare_layout.addWidget(self.speed_slide, 2, 1, 1, 2)

		self.speed_value = QLCDNumber(3, self)
		self.speed_value.display(700)

		prepare_layout.addWidget(self.speed_value, 2, 3, 1, 1)

		prepare_layout.setAlignment(Qt.AlignLeft)

		self.prepareBox.setLayout(prepare_layout)
		# self.prepareBox.setStyleSheet("""background: gray;  color: #fff;""")

		# 手动区域
		self.manual_operation_box = QGroupBox()
		self.manual_operation_box.setTitle("手动区")

		manual_operation_layout = QGridLayout()

		self.forward_button = QPushButton(self)
		# self.forward_button.setToolTip("向东")
		self.forward_button.setText("向东")
		# self.forward_button.setIcon(QIcon(":icons/forward.png"))
		self.forward_button.setIconSize(QSize(60, 60))
		# self.forward_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.forward_button.setObjectName("forward_button")
		self.forward_button.setStyleSheet("border:none")

		# manual_operation_layout.addWidget(self.forward_button, *(0, 1))

		manual_operation_layout.addWidget(self.forward_button, *(0, 0))

		self.backward_button = QPushButton(self)
		self.backward_button.setText("向西")
		# self.backward_button.setIcon(QIcon(":icons/backward.png"))
		self.backward_button.setIconSize(QSize(60, 60))
		# self.backward_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.backward_button.setObjectName("backward_button")
		self.backward_button.setStyleSheet("border:none")
		manual_operation_layout.addWidget(self.backward_button, *(0, 1))
		# self.manual_operation_box.resize(300,300)

		self.left_button = QPushButton(self)
		self.left_button.setText("向北")
		# self.left_button.setIcon(QIcon(":icons/left.png"))
		self.left_button.setIconSize(QSize(60, 60))
		# self.left_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.left_button.setObjectName("left_button")
		self.left_button.setStyleSheet("border:none")
		manual_operation_layout.addWidget(self.left_button, *(0, 2))

		self.right_button = QPushButton(self)
		self.right_button.setText("向南")
		# self.right_button.setIcon(QIcon(":icons/right.png"))
		self.right_button.setIconSize(QSize(60, 60))
		# self.right_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.right_button.setObjectName("right_button")
		self.right_button.setStyleSheet("border:none")
		manual_operation_layout.addWidget(self.right_button, *(0, 3))
		self.manual_operation_box.setLayout(manual_operation_layout)
		# self.manual_operation_box.resize(300,300)

		self.up_hock_button = QPushButton(self)
		self.up_hock_button.setText("定位上升")
		# self.up_hock_button.setIcon(QIcon(":icons/up_hock.png"))
		self.up_hock_button.setIconSize(QSize(60, 60))
		# self.up_hock_button.resize(60,60)
		# self.up_hock_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.up_hock_button.setObjectName("up_hock_button")
		self.up_hock_button.setStyleSheet("border:none")
		manual_operation_layout.addWidget(self.up_hock_button, *(1, 0, 1, 1))

		self.down_hock_button = QPushButton(self)
		self.down_hock_button.setText("定位下降")
		# self.down_hock_button.setIcon(QIcon(":icons/down_hock.png"))
		self.down_hock_button.setIconSize(QSize(60, 60))
		# self.down_hock_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.down_hock_button.setObjectName("down_hock_button")
		self.down_hock_button.setStyleSheet("border:none")
		manual_operation_layout.addWidget(self.down_hock_button, 1, 1, 1, 1)
		#

		self.up_cargohook_button = QPushButton(self)
		self.up_cargohook_button.setText("货钩上升")
		# self.up_cargohook_button.setIcon(QIcon(":icons/up_hock.png"))
		self.up_cargohook_button.setIconSize(QSize(60, 60))
		# self.up_cargohook_button.resize(60,60)
		# self.up_cargohook_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.up_cargohook_button.setObjectName("up_cargohook_button")
		self.up_cargohook_button.setStyleSheet("border:none")
		manual_operation_layout.addWidget(self.up_cargohook_button, 1, 2, 1, 1)

		self.down_cargohook_button = QPushButton(self)
		self.down_cargohook_button.setText("货钩下降")
		# self.down_cargohook_button.setIcon(QIcon(":icons/down_hock.png"))
		self.down_cargohook_button.setIconSize(QSize(60, 60))
		# self.down_cargohook_button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
		self.down_cargohook_button.setObjectName("down_cargohook_button")
		self.down_cargohook_button.setStyleSheet("border:none")
		manual_operation_layout.addWidget(self.down_cargohook_button, 1, 3, 1, 1)

		self.step_label = QLabel(self)
		self.step_label.setText("设置步长")
		# self.step_label.setStyleSheet("""
		# color: rgb(0,0,255);
		#
		# """)
		manual_operation_layout.addWidget(self.step_label, *(2, 0, 1, 1))
		self.step_slide = QSlider(Qt.Horizontal)
		self.step_slide.setToolTip("设置步数")
		self.step_slide.setMinimum(0)
		self.step_slide.setMaximum(200)
		self.step_slide.setSingleStep(10)
		self.step_slide.setValue(20)
		self.step_slide.setTickPosition(QSlider.TicksBelow)
		self.step_slide.setTickInterval(50)
		self.step_slide.setStyleSheet("""
									QSlider:sub-page:horizontal
									{
									border: 1px solid yellow;
									background:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 yellow, stop:1 yellow);
									border-radius: 3px;
									height: 8px;
									}
								""")

		manual_operation_layout.addWidget(self.step_slide, *(2, 1, 1, 2))

		self.step_value = QLCDNumber(3, self)
		self.step_value.display(20)

		manual_operation_layout.addWidget(self.step_value, *(2, 3, 1, 1))

		self.manual_operation_box.setLayout(manual_operation_layout)
		# self.manual_operation_box.setStyleSheet("""background: gray;  color: #fff;""")

		# 执行区域
		self.carryout_box = QGroupBox()
		self.carryout_box.setTitle("扫描区")

		carryout_layout = QVBoxLayout(self)

		carryout_horizotal_layout = QGridLayout(self)

		self.zero_button = QPushButton(self)
		self.zero_button.setText("重置")
		self.zero_button.setObjectName("zero_button")
		carryout_horizotal_layout.addWidget(self.zero_button, 0, 0, 1, 1)

		self.clear_button = QPushButton(self)
		self.clear_button.setText("清零")
		self.clear_button.setObjectName("zero_button")
		carryout_horizotal_layout.addWidget(self.clear_button, 0, 1, 1, 1)

		self.stop_button = QPushButton(self)
		self.stop_button.setText("急停")
		self.stop_button.setObjectName("stop_button")
		carryout_horizotal_layout.addWidget(self.stop_button, 0, 2, 1, 1)

		self.scan_button = QPushButton(self)
		self.scan_button.setText("自动扫描袋子")

		self.scan_button.setObjectName("zero_button")

		carryout_horizotal_layout.addWidget(self.scan_button, 1, 0, 1, 1)

		self.scan_handmove_button = QPushButton(self)
		self.scan_handmove_button.setText("手动扫描袋子")

		self.scan_handmove_button.setObjectName("zero_button")
		carryout_horizotal_layout.addWidget(self.scan_handmove_button, 1, 1, 1, 1)

		self.clean_bags_button = QPushButton(self)
		self.clean_bags_button.setText("清空袋子坐标")
		self.clean_bags_button.setObjectName("clean_bags_button")
		carryout_horizotal_layout.addWidget(self.clean_bags_button, 1, 2, 1, 1)

		carryout_layout.addLayout(carryout_horizotal_layout)

		self.carryout_box.setLayout(carryout_layout)

		self.moveandput_box = QGroupBox()
		self.moveandput_box.setTitle("搬运区")
		moveandput_layout = QGridLayout()

		self.build_bagpositions_tree()
		moveandput_layout.addWidget(self.position_tree, 0, 0, 4, 3)

		self.giveup_close_pushbutton = QPushButton(self)
		self.giveup_close_pushbutton.setText("放弃抓取")
		# self.grab_bag_pushbutton.setIcon(QIcon(":icons/grab.png"))
		self.giveup_close_pushbutton.setIconSize(QSize(60, 60))
		self.giveup_close_pushbutton.setObjectName("grab_bag_pushbutton")
		self.giveup_close_pushbutton.setStyleSheet("border:none")
		moveandput_layout.addWidget(self.giveup_close_pushbutton, 4, 0, 1, 1)

		# 抓取袋子
		self.grab_bag_pushbutton = QPushButton(self)
		self.grab_bag_pushbutton.setText("抓取袋子")
		# self.grab_bag_pushbutton.setIcon(QIcon(":icons/grab.png"))
		self.grab_bag_pushbutton.setIconSize(QSize(60, 60))
		self.grab_bag_pushbutton.setObjectName("grab_bag_pushbutton")
		self.grab_bag_pushbutton.setStyleSheet("border:none")
		moveandput_layout.addWidget(self.grab_bag_pushbutton, 4, 1, 1, 1)

		# 放下袋子按钮
		self.putdown_bag_pushbutton = QPushButton(self)
		self.putdown_bag_pushbutton.setText("放下袋子")
		# self.putdown_bag_pushbutton.setIcon(QIcon(":icons/putdown.png"))
		self.putdown_bag_pushbutton.setIconSize(QSize(60, 60))
		self.putdown_bag_pushbutton.setObjectName("putdown_bag_pushbutton")
		self.putdown_bag_pushbutton.setStyleSheet("border:none")
		moveandput_layout.addWidget(self.putdown_bag_pushbutton, 4, 2, 1, 1)

		self.moveandput_box.setLayout(moveandput_layout)

		operator_layout.addWidget(self.prepareBox)
		operator_layout.addWidget(self.manual_operation_box)
		operator_layout.addWidget(self.carryout_box)
		operator_layout.addWidget(self.moveandput_box)
		# operator_layout.addWidget(self.check_error_box)
		self.operatorBox.setLayout(operator_layout)
		# self.operatorBox.setStyleSheet("""background: gray; color: #fff;""")

		self.setStyleSheet("""
									QPushButton
									{
									height: 37px;
									}
								""")

		# all_layout.setStretch(0, 2)
		all_layout.setStretch(0, 7)
		all_layout.setStretch(1, 3)
		self.setLayout(all_layout)
		self.retranslateUi()

	# 构建视频树形列表
	def build_bagpositions_tree(self):

		self.position_tree = QTreeWidget()
		self.position_tree.setHeaderLabels(['袋子坐标', '抵达状态', '抓取状态'])
		self.position_tree.setColumnCount(3)
		self.position_tree.setColumnWidth(0, 150)
		self.position_tree.setColumnWidth(1, 150)
		self.position_tree.setColumnWidth(2, 150)

		self.saved_root = QTreeWidgetItem(self.position_tree)
		self.saved_root.setText(0, "点击执行")
		# self.saved_root.setText(1, "点击执行")
		self.position_tree.clicked.connect(self.onTreeClicked)
		self.position_tree.expandAll()

	def retranslateUi(self):

		self.setWindowTitle("视频识别机械手")
		self.operatorBox.setTitle("操作区域")

	# self.videoBox.setTitle(_translate("MainWindow", "视频区域"))

	def turn_on_off_biglaster(self):
		if self.biglaster_status == 1:
			self.biglaster_status = 0
			self.turnon_biglaster_button.setIcon(QIcon(":icons/turnoff.png"))
			self.turnon_biglaster_button.setText('关闭激光灯')
			self.turnon_biglaster_button.setToolTip("关闭激光灯")
			# self.plchandle.laster = 0
			self.plchandle.biglaster = 0
			self.process.intelligentthread.detectorhandle.laster_status = False
		else:
			self.biglaster_status = 1
			self.plchandle.biglaster = 1
			self.turnon_biglaster_button.setIcon(QIcon(":icons/laster.png"))
			self.turnon_biglaster_button.setText('打开激光灯')
			self.turnon_biglaster_button.setToolTip("打开激光灯")
			self.process.intelligentthread.detectorhandle.laster_status = True

	# 打开或关闭激光灯
	def turn_on_off_laster(self):
		if self.laster_status == 1:
			self.laster_status = 0
			self.turnon_laster_button.setIcon(QIcon(":icons/turnoff.png"))
			self.turnon_laster_button.setText('关闭激光灯')
			self.turnon_laster_button.setToolTip("关闭激光灯")
			self.plchandle.laster = 0
			# self.plchandle.biglaster = 0
			self.process.intelligentthread.detectorhandle.laster_status = False
		else:
			self.laster_status = 1
			self.turnon_laster_button.setIcon(QIcon(":icons/laster.png"))
			self.turnon_laster_button.setText('打开激光灯')
			self.turnon_laster_button.setToolTip("打开激光灯")
			self.plchandle.laster = 1
			self.process.intelligentthread.detectorhandle.laster_status = True

	def arrive_show(self, X, Y):
		info = "->->->已经抵达该袋子,坐标X:{},Y:{}".format(X, Y)
		self.show_all.workrecord.append(info)

		for item in self.bag_positions_childs:
			self.saved_root.removeChild(item)

		self.bag_positions_childs.clear()
		X, Y = int(X), int(Y)

		for index, point in enumerate(self.bagpositions):
			child = QTreeWidgetItem(self.saved_root)
			child.setText(0, "({},{})".format(point[0], point[1]))

			if abs(X - point[0]) < 20 and abs(Y - point[1]) < 20:
				child.setText(1, "已抵达")
			else:
				child.setText(1, "未抵达")
			child.setText(2, "未抓取")
			self.bag_positions_childs.append(child)

	# ------------------------------------------------
	# show_warn_info
	# 功能:展示所有异常
	# 状态:在用
	# 参数: [wraninfo]   ---警告信息
	# 返回: [None]   ---无
	# 作者:王杰  2020-7-*
	# ------------------------------------------------
	def show_warn_info(self, wraninfo):

		infoBox = QMessageBox()
		infoBox.setIcon(QMessageBox.Information)
		infoBox.setText(wraninfo)
		infoBox.setWindowTitle("提示")
		infoBox.setStandardButtons(QMessageBox.Ok)
		infoBox.button(QMessageBox.Ok).animateClick(1 * 1000)  # 3秒自动关闭
		infoBox.exec_()

	def move_to_bag_slot(self, position):
		self.show_all.workrecord.append("\n")
		self.show_all.workrecord.append("命令移到行车到指定位置:({},{})".format(position[0], position[1]))

	# ------------------------------------------------
	# show_error_info
	# 功能:展示所有错误
	# 状态:在用
	# 参数: [None]   ---
	# 返回: [None]   ---
	# 作者:王杰  2020-7-*
	# ------------------------------------------------
	def show_error_info(self, error_info):
		# self.show_all.text.clear()

		if 'south_north' in error_info:
			SOUTH_NORTH_SERVER_FLAG = error_info['south_north']
			# self.show_all.text.append(
			# 	'南北伺服报警' if SOUTH_NORTH_SERVER_FLAG is not None and SOUTH_NORTH_SERVER_FLAG == 1 else "南北伺服正常")
			if SOUTH_NORTH_SERVER_FLAG == 1:
				self.show_all.south_north_server.setIcon(QIcon(":icons/sifu1.png"))

			if 'south' in error_info:
				SOUTH_LIMIT_FLAG = error_info['south']
				# self.show_all.text.append(
				# 	'->->->南限位报警' if SOUTH_LIMIT_FLAG is not None and SOUTH_LIMIT_FLAG == 1 else '->->->南限位正常')
				if SOUTH_LIMIT_FLAG == 1:
					self.show_all.south_xianwei.setIcon(QIcon(":icons/xianweiqi1.png"))

			if 'north' in error_info:
				NORTH_LIMIT_FLAG = error_info['north']
				# self.show_all.text.append(
				# 	'->->->北限位报警' if NORTH_LIMIT_FLAG is not None and NORTH_LIMIT_FLAG == 1 else '->->->北限位正常')
				if NORTH_LIMIT_FLAG == 1:
					self.show_all.north_xianwei.setIcon(QIcon(":icons/xianweiqi1.png"))

		if 'east_server' in error_info:
			EAST_SERVER_FLAG = error_info['east_server']
			# self.show_all.text.append(
			# 	'东伺服报警' if EAST_SERVER_FLAG is not None and EAST_SERVER_FLAG == 1 else '东伺服正常')

			if EAST_SERVER_FLAG == 1:
				self.show_all.east_server.setIcon(QIcon(":icons/sifu1.png"))

			if 'east' in error_info:
				EAST_LIMIT_FLAG = error_info['east']
				# self.show_all.text.append(
				# 	'->->->东限位报警' if EAST_LIMIT_FLAG is not None and EAST_LIMIT_FLAG == 1 else '->->->东限位正常')

				if EAST_LIMIT_FLAG == 1:
					self.show_all.east_xianwei.setIcon(QIcon(":icons/xianweiqi1.png"))

		if 'west_server' in error_info:
			WEST_SERVER_FLAG = error_info['west_server']
			# self.show_all.text.append(
			# 	'西伺服报警' if WEST_SERVER_FLAG is not None and WEST_SERVER_FLAG == 1 else '西伺服正常')
			if WEST_SERVER_FLAG is not None and WEST_SERVER_FLAG == 1:
				self.show_all.west_server.setIcon(QIcon(":icons/sifu1.png"))
			if 'west' in error_info:
				WEST_LIMIT_FLAG = error_info['west']
				# self.show_all.text.append(
				# 	'->->->西限位报警' if WEST_LIMIT_FLAG is not None and WEST_LIMIT_FLAG == 1 else '->->->西限位正常')
				if WEST_LIMIT_FLAG == 1:
					self.show_all.west_xianwei.setIcon(QIcon(":icons/xianweiqi1.png"))

		# 	跳闸报警
		if 'sourth_north_server_trip_warn' in error_info:
			sourth_north_server_trip_warn = error_info['sourth_north_server_trip_warn']
			# self.show_all.text.append(
			# 	'南北伺服跳闸' if sourth_north_server_trip_warn is not None and sourth_north_server_trip_warn == 1 else '南北伺服通电正常')
			if sourth_north_server_trip_warn == 1:
				self.show_all.south_north_server_trip.setIcon(QIcon(":icons/sifu1.png"))

		if 'east_west_server1_trip_warn' in error_info:
			east_west_server1_trip_warn = error_info['east_west_server1_trip_warn']
			# self.show_all.text.append(
			# 	'东西伺服1跳闸' if east_west_server1_trip_warn is not None and east_west_server1_trip_warn == 1 else '东西伺服1通电正常')
			if east_west_server1_trip_warn == 1:
				self.show_all.eastwest_server1_trip.setIcon(QIcon(":icons/dianzha1.png"))

		if 'east_west_server2_trip_warn' in error_info:
			east_west_server2_trip_warn = error_info['east_west_server2_trip_warn']
			# self.show_all.text.append(
			# 	'东西伺服2跳闸' if east_west_server2_trip_warn is not None and east_west_server2_trip_warn == 1 else '东西伺服2通电正常')
			if east_west_server2_trip_warn == 1:
				self.show_all.eastwest_server2_trip.setIcon(QIcon(":icons/dianzha1.png"))

	# ------------------------------------------------
	# 名称:init_button
	# 功能:初始化所有的按钮
	# 状态:在用
	# 参数: [None]   ---
	# 返回: [None]   ---
	# 作者:王杰  2020-7-01
	# ------------------------------------------------
	def init_button(self):
		self.load_button.clicked.connect(self.load_plc_module)
		self.open_sdkcamera_button.clicked.connect(self.open_haikang_camera)
		self.lamp_open_button.clicked.connect(self.open_lamp)
		self.turnon_laster_button.clicked.connect(self.turn_on_off_laster)
		self.turnon_biglaster_button.clicked.connect(self.turn_on_off_biglaster)
		# self.save_video_button.clicked.connect(self.save_video)
		self.speed_slide.valueChanged.connect(self.speed_change)

		self.forward_button.clicked.connect(self.forward)
		self.backward_button.clicked.connect(self.backward)
		self.left_button.clicked.connect(self.left)
		self.right_button.clicked.connect(self.right)

		self.up_hock_button.clicked.connect(self.up_hock)
		self.down_hock_button.clicked.connect(self.down_hock)

		self.up_cargohook_button.clicked.connect(self.up_cargohook)
		self.down_cargohook_button.clicked.connect(self.down_cargohook)

		self.step_slide.valueChanged.connect(self.step_change)

		self.zero_button.clicked.connect(self.reset_plc)
		self.clear_button.clicked.connect(self.clear_plc)
		self.stop_button.clicked.connect(self.quickly_stop_work)
		self.scan_button.clicked.connect(self.scan_bags)
		self.scan_handmove_button.clicked.connect(self.scan_bag_byhand)
		self.clean_bags_button.clicked.connect(self.clean_bag_positions)
		self.giveup_close_pushbutton.clicked.connect(self.giveup_close_bag)
		self.grab_bag_pushbutton.clicked.connect(self.grab_bag)
		self.putdown_bag_pushbutton.clicked.connect(self.putdown_bag)

	# --------------------------------------------------------------------------------
	# 方法名:clean_bag_positions
	# 用途:清除上依次检索的袋子坐标
	# 参数:---None-------
	# 作者:王杰
	# --------------------------------------------------------------------------------#
	def clean_bag_positions(self):
		for item in self.bag_positions_childs:
			self.saved_root.removeChild(item)
		self.process.intelligentthread.detectorhandle.bags.clear()
		self.process.intelligentthread.detectorhandle.bag_detect.bags.clear()
		self.process.intelligentthread.detectorhandle.temp_bag_positions.clear()
		self.process.intelligentthread.detectorhandle.hock_detect.has_stable = False

	def scan_bag_byhand(self):
		self.handmove_window = ScanBagByHandWindow(self.process)
		self.handmove_window.show()

	def add_scan_bag(self, bagpositions: list):
		for item in self.bag_positions_childs:
			self.saved_root.removeChild(item)

		self.show_all.workrecord.clear()

		self.show_all.workrecord.append("扫描到的袋子坐标为:")

		self.bagpositions = bagpositions

		for index, point in enumerate(bagpositions):
			child = QTreeWidgetItem(self.saved_root)
			child.setText(0, "({},{})".format(point[0], point[1]))
			child.setText(1, "未抵达")
			child.setText(2, "未抓取")
			self.bag_positions_childs.append(child)
			self.show_all.workrecord.append("->->->第{}个袋子坐标为:({},{})".format(index + 1, point[0], point[1]))

	def giveup_close_bag(self):
		print("stop")
		self.process.intelligentthread.detectorhandle.keep_y_move = False
		self.process.intelligentthread.detectorhandle.keep_x_move = False
		self.process.intelligentthread.move_close = False
		if self.process.intelligentthread.target_bag_position is not None or len(
				self.process.intelligentthread.target_bag_position) > 0:
			self.process.intelligentthread.detectorhandle.bags.clear()
			self.process.intelligentthread.detectorhandle.bag_detect.bags.clear()
			self.process.intelligentthread.detectorhandle.temp_bag_positions.clear()
			self.process.intelligentthread.detectorhandle.hock_detect.has_stable = False

	def grab_bag(self):
		# TODO  抓取袋子
		if self.process.intelligentthread.move_to_bag_x == False and self.process.intelligentthread.move_to_bag_y == False:
			self.process.intelligentthread.grab_bag = True
			QMessageBox.about(self, '提示', '抓取成功!')
		else:
			QMessageBox.about(self, '错误提示', '还未到达袋子,无法执行放下指令!')

	# TODO 放下袋子
	def putdown_bag(self):

		if self.process.intelligentthread.grab_bag == True and self.process.intelligentthread.putdown_bag == False:
			# TODO  袋子区域计算是实时的,也是十分无序的,想一个完全之策
			# TODO 计算放置袋子的X,Y坐标,以及需要摆放的层数
			# TODO 计算当前袋子与放置坐标的距离
			# TODO 计算最高障碍物高度(不一定准确),让钩子吊着袋子顺利过去
			# TODO 位移到摆放区域X,Y  向下落钩,直到拉力传感器数值为0,控制PLC释放袋子
			self.process.intelligentthread.putdown_bag = True
		else:
			QMessageBox.about(self, '错误提示', '抓取袋子还未成功,无法执行放下指令!')

	# ------------------------------------------------
	# 名称:save_video
	# 功能:录制视频
	# 状态:在用
	# 参数: [None]   ---
	# 返回: [None]   ---
	# 作者:王杰  2020-7-23
	# ------------------------------------------------
	def save_video(self):
		if self.process is not None and self.process.intelligentthread is not None and \
				self.process.intelligentthread.play == True:
			self.process.intelligentthread.save_video = True

	# ------------------------------------------------
	# 名称:open_haikang_camera
	# 功能:打开海康摄像头
	# 状态:在用
	# 参数: [None]
	# 返回: [None]
	# 作者:王杰  2020-7-02
	# ------------------------------------------------
	def open_haikang_camera(self):
		try:
			imagehandle = ImageProvider()
			self.process.IMGHANDLE = imagehandle
			if self.process.IMGHANDLE:
				self.process.IMGHANDLE = imagehandle
				self.process.intelligentthread.play = True
				self.process.intelligentthread.start()
		except Exception as e:
			QMessageBox.about(self, '警告信息', '打开失败')

	# ------------------------------------------------
	# 名称:scan
	# 功能:扫描袋子
	# 状态:在用
	# 参数: [None]
	# 返回: [None]
	# 作者:王杰  2020-7-01
	# ------------------------------------------------
	def scan_bags(self):

		scan_status = self.process.intelligentthread.scan_bag
		self.process.intelligentthread.detectorhandle.bags.clear()
		self.process.intelligentthread.detectorhandle.bag_detect.bags.clear()
		self.process.intelligentthread.detectorhandle.temp_bag_positions.clear()

		if scan_status == False:
			self.process.plchandle.go_and_back()
			self.scan_button.setIcon(QIcon(":icons/stop_scan.png"))
			self.scan_button.setText('停止扫描')
			self.scan_button.setToolTip("停止扫描")
			self.process.intelligentthread.detectorhandle.hock_detect.has_stable = False
		else:
			self.scan_button.setIcon(QIcon(":icons/scan.png"))
			self.scan_button.setText('扫描袋子')
			self.scan_button.setToolTip("扫描袋子")

		self.process.intelligentthread.scan_bag = not scan_status

	def step_change(self):
		value = self.step_slide.value()
		self.step = value
		self.step_value.display(value)

	def speed_change(self):
		value = self.speed_slide.value()
		self.plchandle.speed = value
		self.speed_value.display(value)

	# ------------------------------------------------
	# 名称:forward
	# 功能:向前移动
	# 状态:在用
	# 参数: [None]
	# 返回: [None]
	# 作者:王杰  2020-7-1
	# ------------------------------------------------
	def forward(self):
		self.process.move(east=self.step)

	# ------------------------------------------------
	# 名称:backward
	# 功能:向后移动
	# 状态:在用
	# 参数: [None]
	# 返回: [None]
	# 作者:王杰  2020-7-1
	# ------------------------------------------------
	def backward(self):
		self.process.move(west=self.step)

	# ------------------------------------------------
	# 名称:left
	# 功能:向左移动
	# 状态:在用
	# 参数: [None]   ---
	# 返回: [None]   ---
	# 作者:王杰  2020-7-1
	# ------------------------------------------------
	def left(self):
		self.process.move(nourth=self.step)

	# ------------------------------------------------
	# 名称:right
	# 功能:向左移动
	# 状态:在用
	# 参数: [None]   ---
	# 返回: [None]   ---
	# 作者:王杰  2020-7-1
	# ------------------------------------------------
	def right(self):
		self.process.move(south=self.step)

	# ------------------------------------------------
	# 名称:load_plc_module
	# 功能:开启plc梯形图
	# 状态:在用
	# 参数: [None]   ---
	# 返回: [None]   ---
	# 作者:王杰  2020-7-1
	# ------------------------------------------------
	def load_plc_module(self):
		reply = QMessageBox.information(self,  # 使用infomation信息框
		                                "加载",
		                                "加载系统启动参数",
		                                QMessageBox.Yes | QMessageBox.No)
		finish = reload()
		if reply == QMessageBox.Yes:
			self.process.switch_power()
			QMessageBox.about(self, '反馈', '已重新加载系统参数')

	# ------------------------------------------------
	# 名称:open_lamp
	# 功能:打开照明灯
	# 状态:在用
	# 参数: [None]   ---
	# 返回: [None]   ---
	# 作者:王杰  2020-7-1
	# ------------------------------------------------
	def open_lamp(self):
		# reply = QMessageBox.information(self,  # 使用infomation信息框
		#                                 "准备工作",
		#                                 "钩子移动到X轴中心",
		#                                 QMessageBox.Yes | QMessageBox.No)
		# if reply == QMessageBox.Yes:
		# 	self.process.turnon_lamp()
		# QMessageBox.about(self, '反馈', '已置中')
		self.process.turnon_lamp()

	def check_test_status(self):
		self.test_status_edit.setText('测试' if DEBUG else "正式")

	def check_plc_status(self):
		'''
		检测plc状态
		'''
		print(self.plchandle.is_open())
		self.plc_status_edit.setText('连接' if self.plchandle.is_open() else "断开")

	def check_ladder_status(self):
		'''检测梯形图开启状态'''
		self.ladder_edit.setText('启动' if self.plchandle.power else "未开启")

	def onTreeClicked(self, qmodeLindex):
		item = self.position_tree.currentItem()
		self.process.intelligentthread.detectorhandle.hock_detect.has_stable = False
		match_result = re.match(self.position_pattern, item.text(0))
		try:
			if match_result is not None:
				QMessageBox.about(self, '反馈', '定位坐标({},{})'.format(match_result.group(1), match_result.group(2)))
				self.process.intelligentthread.target_bag_position = [match_result.group(1), match_result.group(2)]
				self.process.intelligentthread.move_close = True
				self.process.intelligentthread.move_to_bag_x = True
				self.process.intelligentthread.move_to_bag_y = True

		except:
			print("not match")

	def play(self):
		'''开始播放'''
		if self.process.IMGHANDLE:
			self.process.intelligentthread.play = True
			self.process.intelligentthread.start()
		else:
			QMessageBox.warning(self, "警告",
			                    self.tr("还没有开启摄像头或者选择播放视频!"))
			print("关闭")

	def step_to_millsecond(self):
		# 20cm/1000ms
		speed = 20 / 1000
		millseconds = int(self.step / speed)
		return millseconds

	# 定位钩上升
	def up_hock(self):
		# self.final_picture_label.resize(IMG_WIDTH, IMG_HEIGHT)
		millseconds = self.step_to_millsecond()
		self.process.move(up=millseconds)

	# 定位钩下降
	def down_hock(self):
		# self.final_picture_label.resize(IMG_WIDTH, IMG_HEIGHT)
		millseconds = self.step_to_millsecond()
		self.process.move(down=millseconds)

	# 货钩上升
	def up_cargohook(self):
		# self.final_picture_label.resize(IMG_WIDTH, IMG_HEIGHT)
		millseconds = self.step_to_millsecond()
		self.process.move(up_cargohook=millseconds)

	# 货钩下降
	def down_cargohook(self):
		# self.final_picture_label.resize(IMG_WIDTH, IMG_HEIGHT)
		millseconds = self.step_to_millsecond()
		self.process.move(down_cargohook=millseconds)

	def startwork(self):
		self.process.intelligentthread.work = True
		try:
			if self.process.IMGHANDLE is not None:
				self.process.intelligentthread.play = True
				self.process.intelligentthread.start()
			else:
				imagehandle = ImageProvider(videofile=None)
				self.process.IMGHANDLE = imagehandle
				if self.process.IMGHANDLE:
					self.process.IMGHANDLE = imagehandle
					self.process.intelligentthread.play = True
					self.process.intelligentthread.start()

		except:
			QMessageBox.warning(self, "警告",
			                    self.tr("您只是在模拟行车软件,因为没有连接行车摄像头!"))

	def init_process_status_show(self):
		pass

	# 启动行车梯形图
	def switch_power(self):
		print("切换梯形图power")
		self.process.switch_power()

	def quickly_stop_work(self):
		self.process.quickly_stop_work()

	def re_work(self):
		self.process.re_work()

	# QMessageBox.about(self, '反馈', '紧急停止,防止行车越界')

	def reset_plc(self):
		'''
		PLC复位
		:return:
		'''
		self.process.resetplc()
		QMessageBox.about(self, '反馈', '重置PLC')

	def clear_plc(self):
		'''
		PLC清零
		'''
		self.process.clear_plc()

	def save_video(self):
		'''
		留存,数据处理留存
		:return:
		'''
		self.process.save_video()

	def stop(self):
		'''暂停摄像机'''
		print("关闭摄像")
		self.process.intelligentthread.play = False
		self.process.intelligentthread.move_to_bag_x = False
		self.process.intelligentthread.move_to_bag_y = False
		self.process.intelligentthread.scan_bag = False
		self.process.intelligentthread.detectorhandle.hock_detect.has_stable = False

	def fresh_all(self):
		self.check_test_status()
		self.check_plc_status()
		self.check_ladder_status()
Beispiel #30
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.dbm_obj = Dbm()
        self.curFile = ''
        self.textEdit = QTextEdit()
        self.sectionTreeWidget = QTreeWidget()

        self.notesListWidget = QListWidget()
        self.createHorizontalGroupBox()
        self.setCentralWidget(self.horizontalGroupBox)

        self.createActions()
        self.createMenus()
        # self.createToolBars()
        self.createStatusBar()
        self.readSettings()

        [self.hierarchy_dict, self.notebook_dict, self.section_dict, self.page_dict] = [{}, {}, {}, {}]

        self.setCurrentFile('')

        # For binding slots and signals
        self.fetchPageThread = FetchPage()
        self.fetchPageThread.setObjectName('fetchPageThread')
        self.syncAllThread = SyncAllThread()
        self.syncAllThread.setObjectName('syncAllThread')
        self.textEdit.document().contentsChanged.connect(self.documentWasModified)
        self.sectionTreeWidget.setObjectName("sectionTreeWidget")
        self.notesListWidget.setObjectName("notesListWidget")
        QMetaObject.connectSlotsByName(self)
        self.readDB()

    @pyqtSlot()
    def on_sectionTreeWidget_itemSelectionChanged(self):
        for x in self.sectionTreeWidget.selectedItems():
            if x.text(1) in self.section_dict.keys():
                self.populate_notes_list(x.parent().text(1), x.text(1))

    @pyqtSlot()
    def on_notesListWidget_itemSelectionChanged(self):
        for x in self.notesListWidget.selectedItems():
            self.fetchPageThread.fetchSignal.connect(self.on_fetchPageThread_fetchComplete)
            self.titleLabel.setText("Syncing")
            self.statusBar().showMessage("Syncing")
            # self.fetchPageThread.fetchSignal.connect(lambda:self.view.setHtml("<body>hello world</body>"))
            self.fetchPageThread.fetch(self.page_dict[x.data(1)])

    def on_fetchPageThread_fetchComplete(self, string):
        self.view.setHtml(string)
        self.titleLabel.setText(self.view.title())
        self.statusBar().showMessage("Page fetched")

    def on_syncAllThread_syncComplete(self, dbm):
        self.dbm_obj = dbm
        self.statusBar().showMessage("Sync complete")

    def createHorizontalGroupBox(self):
        self.horizontalGroupBox = QGroupBox()
        layout = QHBoxLayout()

        self.sectionTreeWidget.setHeaderHidden(1)
        layout.addWidget(self.sectionTreeWidget, 0)
        self.sectionTreeWidget.setStyleSheet("background-color: rgb(215,227,229)")
        self.notesListWidget.setWindowTitle('Notes')
        layout.addWidget(self.notesListWidget, 0)
        self.notesListWidget.setStyleSheet("QListWidget {background-color: rgb(196,226,233)}")

        subVBox = QGroupBox()
        vLayout = QVBoxLayout()

        self.titleLabel = QLabel()
        vLayout.addWidget(self.titleLabel, 0)

        self.view = QWebView()
        vLayout.addWidget(self.view, 1)

        subVBox.setLayout(vLayout)

        layout.addWidget(subVBox, 1)

        self.horizontalGroupBox.setLayout(layout)

    def closeEvent(self, event):
        if self.maybeSave():
            self.writeSettings()
            event.accept()
        else:
            event.ignore()

    def newFile(self):
        self.readDB()
        # if self.maybeSave():
        #     self.textEdit.clear()
        #     self.setCurrentFile('')

    def open(self):
        if self.maybeSave():
            fileName, _ = QFileDialog.getOpenFileName(self)
            if fileName:
                self.loadFile(fileName)

    def save(self):
        if self.curFile:
            return self.saveFile(self.curFile)

        return self.saveAs()

    def saveAs(self):
        fileName, _ = QFileDialog.getSaveFileName(self)
        if fileName:
            return self.saveFile(fileName)
        return False

    def on_sectionList_selection_changed(self):
        print('selected item index changed '),

    def populate_section_list(self, hierarchy, notebook_dict, section_dict):
        self.sectionTreeWidget.clear()
        for notebook_id in hierarchy.keys():
            notebook_sectionTreeWidget = QTreeWidgetItem(self.sectionTreeWidget,
                                                         [notebook_dict[notebook_id].name, notebook_id])
            for section_id in hierarchy[notebook_id].keys():
                QTreeWidgetItem(notebook_sectionTreeWidget, [section_dict[section_id].name, section_id])
        self.sectionTreeWidget.show()
        self.sectionTreeWidget.expandAll()

    def populate_notes_list(self, notebook_id, section_id):
        self.notesListWidget.clear()
        for page_id in self.hierarchy_dict[notebook_id][section_id]:
            item = QListWidgetItem(self.page_dict[page_id].title, self.notesListWidget)
            item.setData(1, QVariant(page_id))

    def readDB(self):

        self.dbm_obj.read()
        [self.hierarchy_dict, self.notebook_dict, self.section_dict, self.page_dict] = self.dbm_obj.get_hierarchy_dict()
        self.populate_section_list(self.hierarchy_dict, self.notebook_dict, self.section_dict)

    def sync(self):
        self.syncAllThread.syncCompleteSignal.connect(self.on_syncAllThread_syncComplete)
        self.statusBar().showMessage("Syncing")
        self.syncAllThread.sync()

    def about(self):
        QMessageBox.about(self, "About Application",
                          "The <b>Application</b> example demonstrates how to write "
                          "modern GUI applications using Qt, with a menu bar, "
                          "toolbars, and a status bar.")

    def documentWasModified(self):
        self.setWindowModified(self.textEdit.document().isModified())

    def createActions(self):
        root = QFileInfo(__file__).absolutePath()

        self.newAct = QAction(QIcon(root + '/images/new.png'), "&New", self,
                              shortcut=QKeySequence.New, statusTip="Create a new file",
                              triggered=self.newFile)

        self.openAct = QAction(QIcon(root + '/images/open.png'), "&Open...",
                               self, shortcut=QKeySequence.Open,
                               statusTip="Open an existing file", triggered=self.open)

        self.saveAct = QAction(QIcon(root + '/images/save.png'), "&Save", self,
                               shortcut=QKeySequence.Save,
                               statusTip="Save the document to disk", triggered=self.save)

        self.saveAsAct = QAction("Save &As...", self,
                                 shortcut=QKeySequence.SaveAs,
                                 statusTip="Save the document under a new name",
                                 triggered=self.saveAs)

        self.syncAct = QAction("S&ync", self,
                               statusTip="Sync everything",
                               triggered=self.sync)

        self.readDBAct = QAction("Read DB", self, statusTip="Read stored DB",
                                 triggered=self.readDB)

        self.exitAct = QAction("E&xit", self, shortcut="Ctrl+Q",
                               statusTip="Exit the application", triggered=self.close)

        self.cutAct = QAction(QIcon(root + '/images/cut.png'), "Cu&t", self,
                              shortcut=QKeySequence.Cut,
                              statusTip="Cut the current selection's contents to the clipboard",
                              triggered=self.textEdit.cut)

        self.copyAct = QAction(QIcon(root + '/images/copy.png'), "&Copy", self,
                               shortcut=QKeySequence.Copy,
                               statusTip="Copy the current selection's contents to the clipboard",
                               triggered=self.textEdit.copy)

        self.pasteAct = QAction(QIcon(root + '/images/paste.png'), "&Paste",
                                self, shortcut=QKeySequence.Paste,
                                statusTip="Paste the clipboard's contents into the current selection",
                                triggered=self.textEdit.paste)

        self.aboutAct = QAction("&About", self,
                                statusTip="Show the application's About box",
                                triggered=self.about)

        self.aboutQtAct = QAction("About &Qt", self,
                                  statusTip="Show the Qt library's About box",
                                  triggered=QApplication.instance().aboutQt)

        self.cutAct.setEnabled(False)
        self.copyAct.setEnabled(False)
        self.textEdit.copyAvailable.connect(self.cutAct.setEnabled)
        self.textEdit.copyAvailable.connect(self.copyAct.setEnabled)

    def createMenus(self):
        self.fileMenu = self.menuBar().addMenu("&File")
        self.fileMenu.addAction(self.newAct)
        self.fileMenu.addAction(self.openAct)
        self.fileMenu.addAction(self.saveAct)
        self.fileMenu.addAction(self.saveAsAct)
        self.fileMenu.addAction(self.syncAct)
        self.fileMenu.addAction(self.readDBAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAct)

        self.editMenu = self.menuBar().addMenu("&Edit")
        self.editMenu.addAction(self.cutAct)
        self.editMenu.addAction(self.copyAct)
        self.editMenu.addAction(self.pasteAct)

        self.menuBar().addSeparator()

        self.helpMenu = self.menuBar().addMenu("&Help")
        self.helpMenu.addAction(self.aboutAct)
        self.helpMenu.addAction(self.aboutQtAct)

    def createToolBars(self):
        self.fileToolBar = self.addToolBar("File")
        self.fileToolBar.addAction(self.newAct)
        self.fileToolBar.addAction(self.openAct)
        self.fileToolBar.addAction(self.saveAct)

        self.editToolBar = self.addToolBar("Edit")
        self.editToolBar.addAction(self.cutAct)
        self.editToolBar.addAction(self.copyAct)
        self.editToolBar.addAction(self.pasteAct)

    def createStatusBar(self):
        self.statusBar().showMessage("Ready")

    def readSettings(self):
        settings = QSettings("Trolltech", "Application Example")
        pos = settings.value("pos", QPoint(200, 200))
        size = settings.value("size", QSize(400, 400))
        self.resize(size)
        self.move(pos)

    def writeSettings(self):
        settings = QSettings("Trolltech", "Application Example")
        settings.setValue("pos", self.pos())
        settings.setValue("size", self.size())

    def maybeSave(self):
        if self.textEdit.document().isModified():
            ret = QMessageBox.warning(self, "Application",
                                      "The document has been modified.\nDo you want to save "
                                      "your changes?",
                                      QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)

            if ret == QMessageBox.Save:
                return self.save()

            if ret == QMessageBox.Cancel:
                return False

        return True

    def loadFile(self, fileName):
        file = QFile(fileName)
        if not file.open(QFile.ReadOnly | QFile.Text):
            QMessageBox.warning(self, "Application",
                                "Cannot read file %s:\n%s." % (fileName, file.errorString()))
            return

        inf = QTextStream(file)
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.textEdit.setPlainText(inf.readAll())
        QApplication.restoreOverrideCursor()

        self.setCurrentFile(fileName)
        self.statusBar().showMessage("File loaded", 2000)

    def saveFile(self, fileName):
        file = QFile(fileName)
        if not file.open(QFile.WriteOnly | QFile.Text):
            QMessageBox.warning(self, "Application",
                                "Cannot write file %s:\n%s." % (fileName, file.errorString()))
            return False

        outf = QTextStream(file)
        QApplication.setOverrideCursor(Qt.WaitCursor)
        outf << self.textEdit.toPlainText()
        QApplication.restoreOverrideCursor()

        self.setCurrentFile(fileName);
        self.statusBar().showMessage("File saved", 2000)
        return True

    def setCurrentFile(self, fileName):
        self.curFile = fileName
        self.textEdit.document().setModified(False)
        self.setWindowModified(False)

        if self.curFile:
            shownName = self.strippedName(self.curFile)
        else:
            shownName = 'OneNote for linux'

        self.setWindowTitle(shownName)

    def strippedName(self, fullFileName):
        return QFileInfo(fullFileName).fileName()

    def write_at_exit(self):
        self.dbm_obj.write([self.hierarchy_dict, self.notebook_dict, self.section_dict, self.page_dict])
Beispiel #31
0
class DataManagementTab(QWidget):
    def __init__(self, obj_mng: ObjectManager, tpl_mng: TemplateManager,
                 sgn_mng: SignageManager, mtm_mng: MultimediaManager,
                 chn_mng: ChannelManager):
        super().__init__()

        self._obj_mng = obj_mng
        self._tpl_mng = tpl_mng
        self._sgn_mng = sgn_mng
        self._mtm_mng = mtm_mng
        self._chn_mng = chn_mng

        self._data_list = QTreeWidget()

        self._res = ResourceManager()
        self._stacked_widget = QStackedWidget()
        self._widget_idx = dict()
        self.init_ui()

    def data_to_tree_item(self):
        data_type_items = []
        # For all data type
        for data_type_id in self._obj_mng.object_types.keys():
            data_type = self._obj_mng.get_object_type(data_type_id)
            data_type_text = utils.gen_ui_text(data_type.name, data_type.id)
            data_type_item = QTreeWidgetItem([data_type_text])
            # Add data
            for data_id in self._obj_mng.get_object_values(data_type).keys():
                data_item = QTreeWidgetItem([data_id])
                data_type_item.addChild(data_item)
            data_addition_item = QTreeWidgetItem(["+"])
            data_type_item.addChild(data_addition_item)
            data_type_items.append(data_type_item)
        return data_type_items

    def init_ui(self):
        # Left side of screen
        self._data_list.setHeaderLabel(self._res['dataTypeListLabel'])
        self._data_list.addTopLevelItems(self.data_to_tree_item())
        self._data_list.expandAll()
        self._data_list.itemSelectionChanged.connect(self.list_item_clicked)

        def data_type_change_handler(change_type: utils.ChangeType,
                                     data_text: str = '') -> None:
            # Get selected signage item
            get_selected = self._data_list.selectedItems()
            if get_selected:
                item = get_selected[0]
                if change_type == utils.ChangeType.DELETE:
                    # Remove QTreeWidgetItem
                    self._data_list.removeItemWidget(item)

        data_type_widget = DataTypeWidget(self._obj_mng,
                                          data_type_change_handler)
        self._widget_idx['type'] = self._stacked_widget.addWidget(
            data_type_widget)

        def data_change_handler(change_type: utils.ChangeType,
                                data_text: str = '') -> None:
            # Get selected signage item
            get_selected = self._data_list.selectedItems()
            if get_selected:
                item = get_selected[0]
                if change_type == utils.ChangeType.SAVE:
                    # Update QTreeWidgetItem
                    item.setText(0, data_text)
                elif change_type == utils.ChangeType.DELETE:
                    # Remove QTreeWidgetItem
                    parent = item.parent()
                    parent.removeChild(parent.child(parent.childCount() - 1))
                    parent.removeChild(item)
                    parent.addChild(QTreeWidgetItem(['+']))

        data_widget = DataWidget(self._obj_mng, self._mtm_mng,
                                 data_change_handler)
        self._widget_idx['data'] = self._stacked_widget.addWidget(data_widget)

        # Gather altogether
        hbox_outmost = QHBoxLayout()
        hbox_outmost.addWidget(self._data_list, 1)
        hbox_outmost.addWidget(self._stacked_widget, 4)
        self.setLayout(hbox_outmost)

    def list_item_clicked(self):
        get_selected = self.sender().selectedItems()
        if get_selected:
            item = get_selected[0]
            item_text = item.text(0)
            if item.parent() is None:
                # It is at topmost level
                # Selected one is data type
                idx = self._widget_idx['type']
                data_type_id = utils.ui_text_to_id(item_text)
                data_type = self._obj_mng.get_object_type(data_type_id)
                self._stacked_widget.widget(idx).load_data_on_ui(data_type)
                self._stacked_widget.setCurrentIndex(idx)
            else:
                if item_text == '+':
                    item.setSelected(False)
                    text, ok = QInputDialog.getText(
                        self, self._res['idDialogTitle'],
                        self._res['idDialogDescription'])
                    if ok:
                        try:
                            utils.validate_id(text)
                        except AttributeError:
                            QMessageBox.warning(
                                self, self._res['idInvalidTitle'],
                                self._res['idInvalidDescription'],
                                QMessageBox.Ok, QMessageBox.Ok)
                            return  # Invalid ID. Do not create signage
                        data_type_id = utils.ui_text_to_id(
                            item.parent().text(0))
                        data_type = self._obj_mng.get_object_type(data_type_id)
                        self._obj_mng.add_object_value(
                            ObjectValue(text, data_type, self._obj_mng,
                                        self._mtm_mng))
                        item.setText(0, text)
                        item.parent().addChild(QTreeWidgetItem(['+']))
                else:
                    # Selected one is data
                    idx = self._widget_idx['data']
                    data_type_id = utils.ui_text_to_id(item.parent().text(0))
                    data_type = self._obj_mng.get_object_type(data_type_id)
                    data = self._obj_mng.get_object_value(data_type, item_text)
                    self._stacked_widget.widget(idx).load_data_on_ui(data)
                    self._stacked_widget.setCurrentIndex(idx)
Beispiel #32
0
class Shortcuts(preferences.Page):
    def __init__(self, dialog):
        super(Shortcuts, self).__init__(dialog)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        self.scheme = SchemeSelector(self)
        layout.addWidget(self.scheme)
        self.searchEntry = LineEdit()
        self.searchEntry.setPlaceholderText(_("Search..."))
        layout.addWidget(self.searchEntry)
        self.tree = QTreeWidget(self)
        self.tree.setHeaderLabels([_("Command"), _("Shortcut")])
        self.tree.setRootIsDecorated(False)
        self.tree.setColumnCount(2)
        self.tree.setAllColumnsShowFocus(True)
        self.tree.setAnimated(True)
        layout.addWidget(self.tree)

        self.edit = QPushButton(
            icons.get("preferences-desktop-keyboard-shortcuts"), '')
        layout.addWidget(self.edit)

        # signals
        self.searchEntry.textChanged.connect(self.updateFilter)
        self.scheme.currentChanged.connect(self.slotSchemeChanged)
        self.scheme.changed.connect(self.changed)
        self.tree.currentItemChanged.connect(self.slotCurrentItemChanged)
        self.tree.itemDoubleClicked.connect(self.editCurrentItem)
        self.edit.clicked.connect(self.editCurrentItem)

        # make a dict of all actions with the actions as key and the names as
        # value, with the collection prepended (for loading/saving)
        win = dialog.parent()
        allactions = {}
        for collection in actioncollectionmanager.manager(
                win).actionCollections():
            for name, action in collection.actions().items():
                allactions[action] = (collection, name)

        # keep a list of actions not in the menu structure
        left = list(allactions.keys())

        def add_actions(menuitem, actions):
            """Add actions to a QTreeWidgetItem."""
            for a in actions:
                if a.menu():
                    item = build_menu_item(a)
                    if item.childCount():
                        menuitem.addChild(item)
                elif a in left:
                    left.remove(a)
                    menuitem.addChild(ShortcutItem(a, *allactions[a]))
            menuitem.setFlags(Qt.ItemIsEnabled)  # disable selection

        def build_menu_item(action):
            """Return a QTreeWidgetItem with children for all the actions in the submenu."""
            menuitem = QTreeWidgetItem()
            text = qutil.removeAccelerator(action.text())
            menuitem.setText(0, _("Menu {name}").format(name=text))
            add_actions(menuitem, action.menu().actions())
            return menuitem

        # present the actions nicely ordered as in the menus
        for a in win.menuBar().actions():
            menuitem = build_menu_item(a)
            if menuitem.childCount():
                self.tree.addTopLevelItem(menuitem)

        # sort leftover actions
        left.sort(key=lambda i: i.text())

        # show actions that are left, grouped by collection
        titlegroups = {}
        for a in left[:]:  # copy
            collection, name = allactions[a]
            if collection.title():
                titlegroups.setdefault(collection.title(), []).append(a)
                left.remove(a)
        for title in sorted(titlegroups):
            item = QTreeWidgetItem(["{0}:".format(title)])
            for a in titlegroups[title]:
                item.addChild(ShortcutItem(a, *allactions[a]))
            self.tree.addTopLevelItem(item)
            item.setFlags(Qt.ItemIsEnabled)  # disable selection

        # show other actions that were not in the menus
        item = QTreeWidgetItem([_("Other commands:")])
        for a in left:
            if a.text() and not a.menu():
                item.addChild(ShortcutItem(a, *allactions[a]))
        if item.childCount():
            self.tree.addTopLevelItem(item)
            item.setFlags(Qt.ItemIsEnabled)  # disable selection

        self.tree.expandAll()

        item = self.tree.topLevelItem(0).child(0)
        if _lastaction:
            # find the previously selected item
            for i in self.items():
                if i.name == _lastaction:
                    item = i
                    break
        self.tree.setCurrentItem(item)
        self.tree.resizeColumnToContents(0)

    def items(self):
        """Yield all the items in the actions tree."""
        def children(item):
            for i in range(item.childCount()):
                c = item.child(i)
                if c.childCount():
                    for c1 in children(c):
                        yield c1
                else:
                    yield c

        for c in children(self.tree.invisibleRootItem()):
            yield c

    def item(self, collection, name):
        for item in self.items():
            if item.collection.name == collection and item.name == name:
                return item

    def saveSettings(self):
        self.scheme.saveSettings("shortcut_scheme", "shortcut_schemes",
                                 "shortcuts")
        for item in self.items():
            for scheme in self.scheme.schemes():
                item.save(scheme)
            item.clearSettings()
            item.switchScheme(self.scheme.currentScheme())

    def loadSettings(self):
        self.scheme.loadSettings("shortcut_scheme", "shortcut_schemes")
        # clear the settings in all the items
        for item in self.items():
            item.clearSettings()
            item.switchScheme(self.scheme.currentScheme())

    def slotSchemeChanged(self):
        """Called when the Scheme combobox is changed by the user."""
        for item in self.items():
            item.switchScheme(self.scheme.currentScheme())

    def slotCurrentItemChanged(self, item):
        if isinstance(item, ShortcutItem):
            self.edit.setText(
                _("&Edit Shortcut for \"{name}\"").format(name=item.text(0)))
            self.edit.setEnabled(True)
            global _lastaction
            _lastaction = item.name
        else:
            self.edit.setText(_("(no shortcut)"))
            self.edit.setEnabled(False)

    def import_(self, filename):
        from . import import_export
        import_export.importShortcut(filename, self, self.scheme)

    def export(self, name, filename):
        from . import import_export
        try:
            import_export.exportShortcut(self, self.scheme.currentScheme(),
                                         name, filename)
        except (IOError, OSError) as e:
            QMessageBox.critical(
                self, _("Error"),
                _("Can't write to destination:\n\n{url}\n\n{error}").format(
                    url=filename, error=e.strerror))

    def findShortcutConflict(self, shortcut):
        """Find the possible shortcut conflict and return the conflict name."""
        if shortcut:
            item = self.tree.currentItem()
            if not isinstance(item, ShortcutItem):
                return None
            scheme = self.scheme.currentScheme()
            for i in self.items():
                a = i.action(scheme)
                if i != item and a.shortcuts():
                    for s1 in a.shortcuts():
                        if s1.matches(shortcut) or shortcut.matches(s1):
                            return qutil.removeAccelerator(a.text())
        return None

    def editCurrentItem(self):
        item = self.tree.currentItem()
        if not isinstance(item, ShortcutItem):
            return

        dlg = ShortcutEditDialog(self, self.findShortcutConflict)
        scheme = self.scheme.currentScheme()
        action = item.action(scheme)
        default = item.defaultShortcuts() or None
        if dlg.editAction(action, default):
            shortcuts = action.shortcuts()
            # check for conflicts
            conflicting = []
            for i in self.items():
                if i is not item:
                    for s1, s2 in itertools.product(i.shortcuts(scheme),
                                                    shortcuts):
                        if s1.matches(s2) or s2.matches(s1):
                            conflicting.append(i)
            if conflicting:
                for i in conflicting:
                    l = i.shortcuts(scheme)
                    for s1 in list(l):  # copy
                        for s2 in shortcuts:
                            if s1.matches(s2) or s2.matches(s1):
                                l.remove(s1)
                    i.setShortcuts(l, scheme)

            # store the shortcut
            item.setShortcuts(shortcuts, scheme)
            self.changed.emit()

    def updateFilter(self):
        """Called when the search text changes."""
        search = self.searchEntry.text()
        scheme = self.scheme.currentScheme()

        def hidechildren(item):
            hideparent = True
            for n in range(item.childCount()):
                c = item.child(n)
                if c.childCount():
                    # submenu item
                    if hidechildren(c):
                        c.setHidden(True)
                    else:
                        c.setHidden(False)
                        c.setExpanded(True)
                        hideparent = False
                elif isinstance(c, ShortcutItem):
                    # shortcut item, should be the case
                    if c.matches(scheme, search):
                        c.setHidden(False)
                        hideparent = False
                    else:
                        c.setHidden(True)
            return hideparent

        hidechildren(self.tree.invisibleRootItem())
Beispiel #33
0
    def __init__(self, parent: QWidget, filename: str,
                 torrent_info: TorrentInfo,
                 control_thread: 'ControlManagerThread'):
        super().__init__(parent)

        self.app = QApplication.instance()

        self._torrent_filepath = Path(filename)

        self._torrent_info = torrent_info
        download_info = torrent_info.download_info
        self._control_thread = control_thread
        self._control = control_thread.control

        vbox = QVBoxLayout(self)

        self._download_dir = self.get_directory(
            self._control.last_download_dir)

        vbox.addWidget(QLabel('Download directory:'))
        vbox.addWidget(self._get_directory_browse_widget())

        vbox.addWidget(QLabel('Announce URLs:'))

        url_tree = QTreeWidget()
        url_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        url_tree.header().close()
        vbox.addWidget(url_tree)
        for i, tier in enumerate(torrent_info.announce_list):
            tier_item = QTreeWidgetItem(url_tree)
            tier_item.setText(0, 'Tier {}'.format(i + 1))
            for url in tier:
                url_item = QTreeWidgetItem(tier_item)
                url_item.setText(0, url)
        url_tree.expandAll()
        vbox.addWidget(url_tree, 1)

        file_tree = QTreeWidget()
        file_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        file_tree.setHeaderLabels(('Name', 'Size'))
        file_tree.header().setSectionResizeMode(0,
                                                QHeaderView.ResizeToContents)
        self._file_items = []
        self._traverse_file_tree(download_info.suggested_name,
                                 download_info.file_tree, file_tree)
        file_tree.sortItems(0, Qt.AscendingOrder)
        file_tree.expandAll()
        file_tree.itemClicked.connect(self._update_checkboxes)
        vbox.addWidget(file_tree, 3)

        self._selection_label = QLabel(
            TorrentAddingDialog.SELECTION_LABEL_FORMAT.format(
                len(download_info.files),
                humanize_size(download_info.total_size)))
        vbox.addWidget(self._selection_label)

        self._ipfsadd_checkbox = QCheckBox(
            'Import files to IPFS when download is complete')
        self._ipfsadd_checkbox.setCheckState(Qt.Unchecked)
        # vbox.addWidget(self._ipfsadd_checkbox)

        self._button_box = QDialogButtonBox(self)
        self._button_box.setOrientation(Qt.Horizontal)
        self._button_box.setStandardButtons(QDialogButtonBox.Cancel
                                            | QDialogButtonBox.Ok)
        self._button_box.button(QDialogButtonBox.Ok).clicked.connect(
            self.submit_torrent)
        self._button_box.button(QDialogButtonBox.Cancel).clicked.connect(
            self.close)
        vbox.addWidget(self._button_box)

        self.setWindowTitle('Add Torrent')

        self.setMinimumSize(
            QSize(self.app.desktopGeometry.width() / 3,
                  (2 * self.app.desktopGeometry.height()) / 3))
Beispiel #34
0
class TestsTab:
    model: GuiModel

    def __init__(self, model):
        self.__test_list = QTreeWidget()
        self.__test_list.setHeaderLabel("Name")
        self.__test_list.itemSelectionChanged.connect(self.__test_selected)

        self.__test_details = QTreeWidget()
        self.__test_details.setColumnCount(2)
        self.__test_details.setHeaderLabels(["Student", "Points"])
        self.__test_details.itemActivated.connect(
            lambda item, column: file_double_clicked(self.model, item))
        self.__test_details.itemSelectionChanged.connect(
            self.__test_file_selected)

        self.__test_file_details = FileDetailsWidget(model)

        details_splitter = QSplitter(Qt.Horizontal)
        details_splitter.addWidget(self.__test_details)
        details_splitter.addWidget(self.__test_file_details.widget)

        self.widget = QSplitter(Qt.Vertical)
        self.widget.addWidget(self.__test_list)
        self.widget.addWidget(details_splitter)
        self.widget.setStretchFactor(0, 3)
        self.widget.setStretchFactor(1, 1)

        self.model = model
        self.__load_tests()

        self.model.subject_changed.connect(self.__subject_changed)

    def __subject_changed(self):
        self.__load_tests()

    def __load_tests(self):
        self.__test_list.clear()
        self.__test_details.clear()

        if self.model.subject is not None:
            for test in self.model.subject.tests:
                test_item = TestItem([test.name], test)
                self.__test_list.addTopLevelItem(test_item)

    def __test_selected(self):
        self.__test_details.clear()

        home_work_items = self.__test_list.selectedItems()
        if home_work_items:
            test: Test = home_work_items[0].test

            for test_points in test.get_submissions():
                student_item = StudentItem([
                    f"{test_points.student.surname} {test_points.student.name}",
                    points_or_none(test_points.points)
                ], test_points.student)

                self.__test_details.addTopLevelItem(student_item)
                add_file_items(test_points.files, student_item)

            self.__test_details.expandAll()

    def __test_file_selected(self):
        self.__test_file_details.master_selection_changed(
            self.__test_details.selectedItems())
Beispiel #35
0
class InfoServicePageCollector(QWidget):
    def __init__(self, *args, **kwargs):
        super(InfoServicePageCollector, self).__init__(*args, **kwargs)
        layout = QHBoxLayout(margin=0)
        # 左侧管理菜单
        self.left_tree = QTreeWidget(clicked=self.left_tree_clicked,
                                     objectName='leftTree')
        self.left_tree.header().hide()
        layout.addWidget(self.left_tree, alignment=Qt.AlignLeft)
        # 右侧显示窗口
        self.right_frame = LoadedPage()
        layout.addWidget(self.right_frame)
        self.setLayout(layout)
        self._addLeftTreeContentes()
        self.setStyleSheet("""
        #leftTree::item{
            height:22px;
        }
        """)

    # 添加管理菜单
    def _addLeftTreeContentes(self):
        contents = [
            {
                'name':
                u'咨询服务',
                'subs': [
                    {
                        'id': 1,
                        'name': u'短信通'
                    },
                    {
                        'id': 2,
                        'name': u'市场分析'
                    },
                    {
                        'id': 3,
                        'name': u'专题研究'
                    },
                    {
                        'id': 4,
                        'name': u'调研报告'
                    },
                    {
                        'id': 5,
                        'name': u'市场路演'
                    },
                ]
            },
            {
                'name':
                u'顾问服务',
                'subs': [
                    {
                        'id': 6,
                        'name': u'人才培养'
                    },
                    {
                        'id': 7,
                        'name': u'部门组建'
                    },
                    {
                        'id': 8,
                        'name': u'制度考核'
                    },
                ]
            },
            {
                'name':
                u'策略服务',
                'subs': [
                    {
                        'id': 9,
                        'name': u'交易策略'
                    },
                    {
                        'id': 10,
                        'name': u'投资方案'
                    },
                    {
                        'id': 11,
                        'name': u'套保方案'
                    },
                ]
            },
            {
                'name':
                u'培训服务',
                'subs': [
                    {
                        'id': 12,
                        'name': u'品种介绍'
                    },
                    {
                        'id': 13,
                        'name': u'基本分析'
                    },
                    {
                        'id': 14,
                        'name': u'技术分析'
                    },
                    {
                        'id': 15,
                        'name': u'制度规则'
                    },
                    {
                        'id': 16,
                        'name': u'交易管理'
                    },
                    {
                        'id': 17,
                        'name': u'经验分享'
                    },
                ]
            },
        ]
        # 填充树
        for group_item in contents:
            group = QTreeWidgetItem(self.left_tree)
            group.setText(0, group_item['name'])
            # 添加子节点
            for variety_item in group_item['subs']:
                child = QTreeWidgetItem()
                child.setText(0, variety_item['name'])
                child.sid = variety_item['id']
                group.addChild(child)
        self.left_tree.expandAll()  # 展开所有

    # 点击左侧菜单
    def left_tree_clicked(self):
        item = self.left_tree.currentItem()
        if item.childCount():  # has children open the root
            if item.isExpanded():
                item.setExpanded(False)
            else:
                item.setExpanded(True)
            return
        service_id = item.sid
        text = item.text(0)
        # print(service_id)
        if service_id == 1:  # 短信通
            page = MessageServiceMaintain()
            page.getCurrentSMS()
        elif service_id == 2:  # 市场分析
            page = MarketAnalysisMaintain()
            page.getFileContents()
        elif service_id == 3:  # 专题研究
            page = TopicSearchMaintain()
            page.getFileContents()
        elif service_id == 4:  # 调研报告
            page = SearchReportMaintain()
            page.getFileContents()
        elif service_id == 6:  # 人才培养
            page = PersonnelTrainMaintain()
        elif service_id == 7:  # 部门组建
            page = DeptBuildMaintain()
        elif service_id == 8:  # 制度考核
            page = InstExamineMaintain()
        elif service_id == 9:  # 交易策略
            page = TradePolicyMaintain()
        elif service_id == 10:  # 投资方案
            page = InvestPlanMaintain()
            page.getFileContents()
        elif service_id == 11:  # 套保方案
            page = HedgePlanMaintain()
            page.getFileContents()
        elif service_id == 12:  # 培训服务-品种介绍
            page = VarietyIntroMaintain()
        else:
            page = QLabel(
                '【' + text + '】还不能进行数据管理...',
                styleSheet=
                'color:rgb(50,180,100); font-size:15px;font-weight:bold',
                alignment=Qt.AlignCenter)
        self.right_frame.clear()
        self.right_frame.addWidget(page)
Beispiel #36
0
class Preferences(QDialog):

    configuration = {}
    weight = 0
    # Signals
    savePreferences = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent, Qt.Dialog)
        self.setWindowTitle(translations.TR_PREFERENCES_TITLE)
        self.setMinimumSize(900, 650)
        box = QVBoxLayout(self)
        box.setContentsMargins(3, 3, 3, 3)
        self.setAutoFillBackground(True)
        # Header
        self._header_label = QLabel("")
        header_font = self._header_label.font()
        header_font.setBold(True)
        header_font.setPointSize(header_font.pointSize() + 4)
        self._header_label.setFont(header_font)

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

        self.tree = QTreeWidget()
        self.tree.header().setHidden(True)
        self.tree.setSelectionMode(QTreeWidget.SingleSelection)
        self.tree.setAnimated(True)
        self.tree.header().setSectionResizeMode(
            0, QHeaderView.ResizeToContents)
        self.tree.setFixedWidth(200)
        hbox.addWidget(self.tree)

        self.stacked = QStackedLayout()
        header_layout = QVBoxLayout()
        header_layout.setContentsMargins(0, 0, 0, 0)
        header_layout.addWidget(self._header_label)
        header_layout.addLayout(self.stacked)
        hbox.addLayout(header_layout)
        box.addLayout(hbox)

        # Footer buttons
        button_box = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        box.addWidget(button_box)

        # Connections
        button_box.rejected.connect(self.close)
        button_box.accepted.connect(self._save_preferences)
        self.tree.selectionModel().currentRowChanged.connect(
            self._change_current)

        self.load_ui()

    @pyqtSlot()
    def _save_preferences(self):
        self.savePreferences.emit()
        self.close()

    def load_ui(self):
        sections = sorted(
            Preferences.configuration.keys(),
            key=lambda item: Preferences.configuration[item]['weight'])
        for section in sections:
            text = Preferences.configuration[section]['text']
            Widget = Preferences.configuration[section]['widget']
            widget = Widget(self)
            area = QScrollArea()
            area.setWidgetResizable(True)
            area.setWidget(widget)
            self.stacked.addWidget(area)
            index = self.stacked.indexOf(area)
            item = QTreeWidgetItem([text])
            item.setData(0, Qt.UserRole, index)
            self.tree.addTopLevelItem(item)

            # Sort Item Children
            subcontent = Preferences.configuration[section].get(
                'subsections', {})
            subsections = sorted(
                subcontent.keys(), key=lambda item: subcontent[item]['weight'])
            for sub in subsections:
                text = subcontent[sub]['text']
                Widget = subcontent[sub]['widget']
                widget = Widget(self)
                area = QScrollArea()
                area.setWidgetResizable(True)
                area.setWidget(widget)
                self.stacked.addWidget(area)
                index = self.stacked.indexOf(area)
                subitem = QTreeWidgetItem([text])
                subitem.setData(0, Qt.UserRole, index)
                item.addChild(subitem)

        self.tree.expandAll()
        self.tree.setCurrentIndex(self.tree.model().index(0, 0))

    def _change_current(self):
        item = self.tree.currentItem()
        index = item.data(0, Qt.UserRole)
        self.stacked.setCurrentIndex(index)
        self._header_label.setText(item.text(0))

    @classmethod
    def register_configuration(cls, section, widget, text,
                               weight=None, subsection=None):
        if weight is None:
            Preferences.weight += 1
            weight = Preferences.weight
        if subsection is None:
            Preferences.configuration[section] = {
                'widget': widget,
                'weight': weight,
                'text': text
            }
        else:
            config = Preferences.configuration.get(section, {})
            if not config:
                config[section] = {
                    'widget': None,
                    'weight': 100
                }
            subconfig = config.get('subsections', {})
            subconfig[subsection] = {
                'widget': widget,
                'weight': weight,
                'text': text
            }
            config['subsections'] = subconfig
            Preferences.configuration[section] = config