コード例 #1
0
ファイル: groupview.py プロジェクト: gshklover/qtbind
class GroupView(QWidget, View):
    def __init__(self, context=None, **kwargs):
        super().__init__(**kwargs)

        self._list = QListView()
        self._list.setItemDelegate(PersonItemDelegate())
        self._details = PersonView()

        self.bind("people", self._list, "model", flags=BIND_READ)
        self.bind("current", self._details, "context", flags=BIND_READ)

        layout = QGridLayout()
        self.setLayout(layout)
        layout.addWidget(self._list, 0, 0)
        layout.addWidget(self._details, 0, 1, 1, 1, QtCore.Qt.AlignTop)

        self.context = context

        self._list.selectionModel().selectionChanged.connect(self._on_selection_changed)

    def _on_selection_changed(self, new_selection, old_selection):
        sel = new_selection.indexes()
        if len(sel) != 1:
            return
        self.context.set_current(sel[0].row())
コード例 #2
0
class TeamChooserWidget(QWidget):
    def __init__(self, parent, on_next, league=None):
        super().__init__(parent)
        self.layout = QVBoxLayout()
        self.list_view = QListView()
        self.league = league
        self.model = TeamListModel(league)
        self.list_view.setModel(self.model)
        self.list_view.setSelectionMode(QAbstractItemView.MultiSelection)
        self.list_view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.list_view.customContextMenuRequested.connect(self.list_context_menu)
        self.layout.addWidget(self.list_view)
        self.team_add = AddItemWidget(self, "New Team Name: ", self.add_team, unavailable_options=self.model.all_team_names)
        self.layout.addWidget(self.team_add)

        self.button_h_layout = QHBoxLayout()
        self.button_cancel = QPushButton("Cancel")
        self.button_cancel.clicked.connect(self.on_cancel)
        self.button_next = QPushButton("Next")
        self.button_next.clicked.connect(on_next)
        self.button_h_layout.addWidget(self.button_cancel)
        self.button_h_layout.addWidget(self.button_next)
        self.layout.addLayout(self.button_h_layout)
        self.setLayout(self.layout)
        self.new_teams = []

    def add_team(self, name):
        self.new_teams.append(name)
        team = Team.create(name=name)
        self.model.add_team(team)

    def list_context_menu(self, pos):
        self.listMenu = QMenu()
        current_index = self.list_view.currentIndex()
        select = self.listMenu.addAction("Select")
        select.triggered.connect(
            lambda: self.list_view.selectionModel().select(current_index, QtCore.QItemSelectionModel.Select)
        )

        deselect = self.listMenu.addAction("Deselect")
        deselect.triggered.connect(
            lambda: self.list_view.selectionModel().select(current_index, QtCore.QItemSelectionModel.Deselect)
        )
        delete = self.listMenu.addAction("Delete")
        delete.setDisabled(current_index.data() not in self.new_teams)
        delete.triggered.connect(lambda: self.model.delete_team(current_index.row()))

        parentPosition = self.list_view.mapToGlobal(QtCore.QPoint(0, 0))
        self.listMenu.move(parentPosition + pos)
        self.listMenu.show()

    def on_cancel(self):
        self.model.delete_added_teams()
        self.window().close()

    def get_selected_teams(self):
        teams = []
        for i in self.list_view.selectedIndexes():
            teams.append(self.model.get_team(i.row()))
        return teams
コード例 #3
0
class Browser():
    def __init__(self, app):
        self.listViewModel = QStandardItemModel()

        self.app = app

        self.listView = QListView(app)
        self.listView.move(15, 145)
        self.listView.setFixedSize(app.width - 30, app.height - 190)
        self.listView.setModel(self.listViewModel)
        self.listView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.listView.doubleClicked.connect(self.processItem)
        self.listView.keyPressEvent = self.keyPressEvent
        self.listView.selectionModel().selectionChanged.connect(
            self.selectionChanged)

    def populate(self, entries):
        self.listViewModel.clear()

        for entry in entries:
            item = QStandardItem(
                QIcon('icons/' + (
                    'file.png' if entry['type'] == 'file' else 'folder.png')),
                entry['name'])

            item.setData(entry)
            self.listViewModel.appendRow(item)

    def processItem(self):
        if self.item.data()['type'] == 'dir':
            self.app.navigateDown(self.selectedItem())
        else:
            self.app.extract()

    def keyPressEvent(self, event):
        super(QListView, self.listView).keyPressEvent(event)

        if event.key() == Qt.Key_Return:
            self.processItem()

    def deselect(self):
        self.item = None
        self.app.disableFileActions()

    def selectedItem(self):
        return self.item.text() if self.item else None

    def selectionChanged(self, selected, deselected):
        if len(selected.indexes()):
            modelIndex = selected.indexes()[0]

            self.item = modelIndex.model().item(modelIndex.row())
            self.app.enableFileActions()
        else:
            self.deselect()
コード例 #4
0
 def synchronize_selection(self, from_list: QListView, to_list: QListView):
     source_selection_model: QItemSelectionModel = from_list.selectionModel()
     destination_selection_model: QItemSelectionModel = to_list.selectionModel()
     rows = source_selection_model.selectedRows()
     if len(rows) > 0:
         idx = [r.row() for r in rows]
         min_idx, max_idx = min(idx), max(idx)
         top_index = QModelIndex(to_list.model().index(min_idx, 0))
         bottom_index = QModelIndex(to_list.model().index(max_idx, 0))
         destination_selection_model.select(QItemSelection(top_index, bottom_index),
                                            QItemSelectionModel.ClearAndSelect)
コード例 #5
0
ファイル: __main__.py プロジェクト: VikingScientist/Geomaker
class DatabaseWidget(QSplitter):

    def __init__(self):
        super().__init__()
        self.setOrientation(Qt.Vertical)
        self.create_ui()

    def create_ui(self):
        top = QWidget()
        box = QVBoxLayout()
        top.setLayout(box)

        box.addWidget(label('<strong>Stored regions</strong>'))

        self.listview = QListView()
        self.listview.setModel(DatabaseModel(db))
        self.listview.selectionModel().selectionChanged.connect(self.selection_changed)
        self.listview.doubleClicked.connect(self.list_double_clicked)
        self.listview.setEditTriggers(QListView.EditKeyPressed | QListView.SelectedClicked)
        box.addWidget(self.listview)

        self.addWidget(top)

        self.poly = PolyWidget()
        self.addWidget(self.poly)

    def unselect(self):
        selection_model = self.listview.selectionModel()
        selection_model.select(QModelIndex(), QItemSelectionModel.SelectCurrent)

    def select(self, row):
        selection_model = self.listview.selectionModel()
        index = self.listview.model().index(row, 0, QModelIndex())
        selection_model.select(index, QItemSelectionModel.SelectCurrent)

    def selection_changed(self, selected, deselected):
        try:
            index = selected.indexes()[0]
        except IndexError:
            main_widget.set_selected()
            self.poly.show()
            return
        poly = db[index.row()]
        main_widget.set_selected(poly.lfid)
        self.poly.show(poly)

    def list_double_clicked(self, item):
        main_widget.focus(db[item.row()].lfid)
コード例 #6
0
ファイル: wmain.py プロジェクト: cegesoma/rspub-gui
    def __init_ui__(self):
        self.setWindowTitle(_("Manage configurations"))
        vbox = QVBoxLayout(self)

        list_view = QListView()
        list_view.setSelectionMode(QAbstractItemView.MultiSelection)
        list_view.setAlternatingRowColors(True)
        self.list_model = QStandardItemModel(list_view)
        self.populate_model()
        list_view.setModel(self.list_model)
        self.selection_model = list_view.selectionModel()
        self.selection_model.selectionChanged.connect(
            self.on_selection_changed)
        hbox = QHBoxLayout()
        hbox.addWidget(list_view)
        hbox.addStretch(1)
        vbox.addLayout(hbox)

        btn_box = QHBoxLayout()
        self.btn_delete = QPushButton(_("Delete"))
        self.btn_delete.setEnabled(False)
        self.btn_delete.clicked.connect(self.on_btn_delete_clicked)
        btn_box.addWidget(self.btn_delete)

        btn_close = QPushButton(_("Close"))
        btn_close.setDefault(True)
        btn_close.clicked.connect(self.close)
        btn_box.addWidget(btn_close)

        btn_box.addStretch(1)
        vbox.addLayout(btn_box)

        self.setLayout(vbox)
コード例 #7
0
class OWPySparkScript(SparkEnvironment, widget.OWWidget):
    priority = 3
    name = "PySpark Script"
    description = "Write a PySpark script and run it on input"
    icon = "../assets/Spark.svg"

    class Inputs:
        df = widget.Input('df', pyspark.sql.DataFrame, default=True)
        df1 = widget.Input('df1', pyspark.sql.DataFrame)
        df2 = widget.Input('df2', pyspark.sql.DataFrame)
        df3 = widget.Input('df3', pyspark.sql.DataFrame)

        transformer = widget.Input('transformer', pyspark.ml.Transformer)
        estimator = widget.Input('transformer', pyspark.ml.Estimator)
        model = widget.Input('model', pyspark.ml.Model)

        data = widget.Input('data', object)

    class Outputs:
        df = widget.Output('df', pyspark.sql.DataFrame, default=True)
        df1 = widget.Output('df1', pyspark.sql.DataFrame)
        df2 = widget.Output('df2', pyspark.sql.DataFrame)
        df3 = widget.Output('df3', pyspark.sql.DataFrame)

        transformer = widget.Output('transformer', pyspark.ml.Transformer)
        estimator = widget.Output('transformer', pyspark.ml.Estimator)
        model = widget.Output('model', pyspark.ml.Model)

        data = widget.Output('data', object)

    # inputs = [("in_object", object, "setObject")]
    # outputs = [("out_object", object, widget.Dynamic)]

    df = None
    df1 = None
    df2 = None
    df3 = None
    transformer = None
    estimator = None
    model = None
    data = None

    libraryListSource = Setting(
        [Script("Hello world", "print('Hello world')\n")])
    currentScriptIndex = Setting(0)
    splitterState = Setting(None)
    auto_execute = Setting(False)
    _script = Setting("")

    @Inputs.data
    def set_data(self, obj):
        self.data = obj
        self.console.shell.push({'data': self.data})

    @Inputs.df
    def set_df(self, df):
        self.df = df
        self.console.shell.push({'df': self.df})

    @Inputs.df1
    def set_df1(self, df):
        self.df1 = df
        self.console.shell.push({'df1': self.df1})

    @Inputs.df2
    def set_df2(self, df):
        self.df2 = df
        self.console.shell.push({'df2': self.df2})

    @Inputs.df3
    def set_df3(self, df):
        self.df3 = df
        self.console.shell.push({'df3': self.df3})

    @Inputs.transformer
    def set_transformer(self, transformer):
        self.transformer = transformer
        self.console.shell.push({'transformer': self.transformer})

    @Inputs.estimator
    def set_estimator(self, estimator):
        self.estimator = estimator
        self.console.shell.push({'estimator': self.estimator})

    @Inputs.model
    def set_model(self, model):
        self.model = model
        self.console.shell.push({'model': self.model})

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

        self.spark_logo = "      ____              __     / __/__  ___ _____/ /__    _\ \/ _ \/ _ `/ __/  '_/   /__ / .__/\_,_/_/ /_/\_\   version {version}      /_/".format(
            version=self.sc.version)

        for s in self.libraryListSource:
            s.flags = 0

        self._cachedDocuments = {}

        self.infoBox = gui.widgetBox(self.controlArea, 'Info')
        gui.label(
                self.infoBox, self,
                "<p>Execute python script.</p><p>Input variables:<ul><li> " + \
                "<li>".join(t for t in dir(self.Inputs) if isinstance(getattr(self.Inputs, t), widget.Input)) + \
                "</ul></p><p>Output variables:<ul><li>" + \
                "<li>".join(t for t in dir(self.Outputs) if isinstance(getattr(self.Outputs, t), widget.Output)) + \
                "</ul></p>"
        )

        self.libraryList = itemmodels.PyListModel(
            [],
            self,
            flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable)
        self.libraryList.wrap(self.libraryListSource)

        self.controlBox = gui.widgetBox(self.controlArea, 'Library')
        self.controlBox.layout().setSpacing(1)

        self.libraryView = QListView(
            editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred))
        self.libraryView.setItemDelegate(ScriptItemDelegate(self))
        self.libraryView.setModel(self.libraryList)

        self.libraryView.selectionModel().selectionChanged.connect(
            self.onSelectedScriptChanged)
        self.controlBox.layout().addWidget(self.libraryView)

        w = itemmodels.ModelActionsWidget()

        self.addNewScriptAction = action = QAction("+", self)
        action.setToolTip("Add a new script to the library")
        action.triggered.connect(self.onAddScript)
        w.addAction(action)

        action = QAction(unicodedata.lookup("MINUS SIGN"), self)
        action.setToolTip("Remove script from library")
        action.triggered.connect(self.onRemoveScript)
        w.addAction(action)

        action = QAction("Update", self)
        action.setToolTip("Save changes in the editor to library")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.triggered.connect(self.commitChangesToLibrary)
        w.addAction(action)

        action = QAction("More", self, toolTip="More actions")

        new_from_file = QAction("Import a script from a file", self)
        save_to_file = QAction("Save selected script to a file", self)
        save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs))

        new_from_file.triggered.connect(self.onAddScriptFromFile)
        save_to_file.triggered.connect(self.saveScript)

        menu = QMenu(w)
        menu.addAction(new_from_file)
        menu.addAction(save_to_file)
        action.setMenu(menu)
        button = w.addAction(action)
        button.setPopupMode(QToolButton.InstantPopup)

        w.layout().setSpacing(1)

        self.controlBox.layout().addWidget(w)

        gui.auto_commit(self.controlArea, self, "auto_execute", "Execute")

        self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea)
        self.mainArea.layout().addWidget(self.splitCanvas)

        self.defaultFont = defaultFont = "Monaco" if sys.platform == "darwin" else "Courier"

        self.textBox = gui.widgetBox(self, 'Python script')
        self.splitCanvas.addWidget(self.textBox)
        self.text = PythonScriptEditor(self)
        self.textBox.layout().addWidget(self.text)

        self.textBox.setAlignment(Qt.AlignVCenter)
        self.text.setTabStopWidth(4)

        self.text.modificationChanged[bool].connect(self.onModificationChanged)

        self.saveAction = action = QAction("&Save", self.text)
        action.setToolTip("Save script to file")
        action.setShortcut(QKeySequence(QKeySequence.Save))
        action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        action.triggered.connect(self.saveScript)

        self.consoleBox = gui.widgetBox(self, 'Console')
        self.splitCanvas.addWidget(self.consoleBox)

        # self.console = PySparkConsole(self.__dict__, self, sc = self.sc)
        self.console = EmbedIPython(sc=self.sc,
                                    hc=self.hc,
                                    sqlContext=self.sqlContext,
                                    data=self.data,
                                    df=self.df,
                                    df1=self.df1,
                                    df2=self.df2,
                                    df3=self.df3,
                                    transformer=self.transformer,
                                    estimator=self.estimator,
                                    model=self.model)
        # self.console.shell.run_cell('%pylab qt')
        self.console.shell.run_cell(
            'print("{sparklogo}")'.format(sparklogo=self.spark_logo))

        self.consoleBox.layout().addWidget(self.console)
        self.consoleBox.setAlignment(Qt.AlignBottom)

        select_row(self.libraryView, self.currentScriptIndex)

        self.splitCanvas.setSizes([2, 1])
        # if self.splitterState is not None:
        #     self.splitCanvas.restoreState(QByteArray(self.splitterState))
        #
        # self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved)
        self.controlArea.layout().addStretch(1)
        self.resize(800, 600)

    def handleNewSignals(self):
        self.unconditional_commit()

    def selectedScriptIndex(self):
        rows = self.libraryView.selectionModel().selectedRows()
        if rows:
            return [i.row() for i in rows][0]
        else:
            return None

    def setSelectedScript(self, index):
        select_row(self.libraryView, index)

    def onAddScript(self, *args):
        self.libraryList.append(Script("New script", "", 0))
        self.setSelectedScript(len(self.libraryList) - 1)

    def onAddScriptFromFile(self, *args):
        filename = QFileDialog.getOpenFileName(
            self, 'Open Python Script', os.path.expanduser("~/"),
            'Python files (*.py)\nAll files(*.*)')

        filename = str(filename[0])
        if filename:
            name = os.path.basename(filename)
            contents = open(
                filename, "rb",
                encoding="utf-8").read()  #.decode("utf-8", errors = "ignore")
            self.libraryList.append(Script(name, contents, 0, filename))
            self.setSelectedScript(len(self.libraryList) - 1)

    def onRemoveScript(self, *args):
        index = self.selectedScriptIndex()
        if index is not None:
            del self.libraryList[index]
            select_row(self.libraryView, max(index - 1, 0))

    def onSaveScriptToFile(self, *args):
        index = self.selectedScriptIndex()
        if index is not None:
            self.saveScript()

    def onSelectedScriptChanged(self, selected, deselected):
        index = [i.row() for i in selected.indexes()]
        if index:
            current = index[0]
            if current >= len(self.libraryList):
                self.addNewScriptAction.trigger()
                return

            self.text.setDocument(self.documentForScript(current))
            self.currentScriptIndex = current

    def documentForScript(self, script=0):
        if type(script) != Script:
            script = self.libraryList[script]

        if script not in self._cachedDocuments:
            doc = QtGui.QTextDocument(self)
            doc.setDocumentLayout(QtGui.QPlainTextDocumentLayout(doc))
            doc.setPlainText(script.script)
            doc.setDefaultFont(QFont(self.defaultFont))
            doc.highlighter = PythonSyntaxHighlighter(doc)
            doc.modificationChanged[bool].connect(self.onModificationChanged)
            doc.setModified(False)
            self._cachedDocuments[script] = doc
        return self._cachedDocuments[script]

    def commitChangesToLibrary(self, *args):
        index = self.selectedScriptIndex()
        if index is not None:
            self.libraryList[index].script = self.text.toPlainText()
            self.text.document().setModified(False)
            self.libraryList.emitDataChanged(index)

    def onModificationChanged(self, modified):
        index = self.selectedScriptIndex()
        if index is not None:
            self.libraryList[index].flags = Script.Modified if modified else 0
            self.libraryList.emitDataChanged(index)

    def onSpliterMoved(self, pos, ind):
        self.splitterState = str(self.splitCanvas.saveState())

    def updateSelecetdScriptState(self):
        index = self.selectedScriptIndex()
        if index is not None:
            script = self.libraryList[index]
            self.libraryList[index] = Script(script.name,
                                             self.text.toPlainText(), 0)

    def saveScript(self):
        index = self.selectedScriptIndex()
        if index is not None:
            script = self.libraryList[index]
            filename = script.filename
        else:
            filename = os.path.expanduser("~/")

        filename = QFileDialog.getSaveFileName(
            self, 'Save Python Script', filename,
            'Python files (*.py)\nAll files(*.*)')

        if filename:
            fn = ""
            head, tail = filename  #os.path.splitext(filename)
            if not tail:
                fn = head + ".py"
            else:
                fn = head

            f = open(fn, 'w', encoding='utf-8')
            f.write(self.text.toPlainText())
            f.close()

    def commit(self):
        self._script = str(self.text.toPlainText())
        inputs = [
            'data', 'df', 'df1', 'df2', 'df3', 'transformer', 'estimator',
            'model'
        ]
        self.console.shell.user_ns.update(
            {input: getattr(self, input)
             for input in inputs})
        self.console.execute(self._script)
        for input in inputs:
            getattr(self.Outputs,
                    input).send(self.console.shell.user_ns[input])
コード例 #8
0
ファイル: patch.py プロジェクト: PixelStereo/ola-pyqt-gui
class PatchPanel(QGroupBox):
    """Group of widget to patch an universe"""
    def __init__(self, parent):
        super(PatchPanel, self).__init__()

        self.ola = parent.ola

        self.parent = parent

        self.device_selected = None

        self.universe = None

        grid = QGridLayout()
        self.inputs_model = PortList(self, 'input_mode')
        self.outputs_model = PortList(self, 'output_mode')
        self.devices = QListView()
        self.devices_model = DeviceList(self)
        self.devices.setModel(self.devices_model)
        self.inputs = QListView()
        self.inputs.setModel(self.inputs_model)
        self.inputs.setMinimumHeight(400)
        self.inputs.setMinimumHeight(120)
        self.outputs = QListView()
        self.outputs.setModel(self.outputs_model)
        self.outputs.setMinimumHeight(400)
        self.outputs.setMinimumHeight(120)

        # Universe Selected Change
        self.devices.selectionModel().selectionChanged.connect(self.device_selection_changed)

        devices_label = QLabel('Devices')
        grid.addWidget(devices_label, 0, 0, 1, 1)
        grid.addWidget(self.devices, 1, 0, 21, 1)
        inputs_label = QLabel('Inputs')
        grid.addWidget(inputs_label, 0, 1, 1, 1)
        grid.addWidget(self.inputs, 1, 1, 10, 1)
        outputs_label = QLabel('Outputs')
        grid.addWidget(outputs_label, 11, 1, 1, 1)
        grid.addWidget(self.outputs, 12, 1, 10, 1)
        grid.setSpacing(5)
        self.setLayout(grid)

    def display_ports(self, universe=None):
        """
        Request a list of Devices
        if universe == None, a list of None-Already-Patched ports is send

        """
        if universe is None:
            result = self.ola.client.GetCandidatePorts(self.GetCandidatePortsCallback, None)
            return result
        result = self.ola.client.FetchDevices(self.GetDevicesCallback, 0)
        return result

    def GetCandidatePortsCallback(self, status, devices):
        """
        Called for a new universe
        """
        if status.Succeeded():
            # clear the list of devices
            self.devices_model.devices = []
            if debug:
                print('found', len(devices), 'candidate devices')
            for device in devices:
                self.devices_model.devices.append(device)
        self.parent.ola.devicesList.emit()
        self.refresh_ports()

    def GetDevicesCallback(self, status, devices):
        """
        Fill-in universe menus with candidate devices/ports
        We need to make menus checkable to be able to patch ports
        """
        if status.Succeeded():
            # clear the list of devices
            self.devices_model.devices = []
            for device in devices:
                if device.input_ports == []:
                    # there is no input ports
                    if device.output_ports == []:
                        # no in + no out = no device
                        pass
                    else:
                        self.devices_model.devices.append(device)
                else:
                    self.devices_model.devices.append(device)
            if debug:
                print('found', len(self.devices_model.devices), 'devices')
        self.parent.ola.devicesList.emit()
        self.refresh_ports()
        # if there was a selection before, restore it
        #if self.device_selected:
            #self.devices.setSelection(self.device_selected)

    def refresh_ports(self):
        device = self.device_selected
        if device:
            # reset the models of inputs and outputs
            self.inputs_model.ports = []
            self.outputs_model.ports = []
            # Append input ports of this device to the inputs list model
            for port in device.input_ports:
                self.inputs_model.ports.append(port)
            # Append output ports of this device to the outputs list model
            for port in device.output_ports:
                self.outputs_model.ports.append(port)
            # please refresh Qlistview
            self.parent.ola.inPortsList.emit()
            self.parent.ola.outPortsList.emit()

    def device_selection_changed(self, device):
        # tell me which is the row selected
        row = device.indexes()[0].row()
        # tell me which device is associated with this row
        device = device.indexes()[0].model().object(row)
        self.device_selected = device
        # refresh ports list
        self.refresh_ports()
        if debug:
            print('selected device :', device.name)
コード例 #9
0
class UploadDialog(QDialog):
    """文件上传对话框"""
    new_infos = pyqtSignal(object)

    def __init__(self):
        super().__init__()
        self.cwd = os.getcwd()
        self.selected = []
        self.max_len = 400
        self.initUI()
        self.set_size()
        self.setStyleSheet(dialog_qss_style)

    def set_values(self, folder_name):
        self.setWindowTitle("上传文件至 ➩ " + str(folder_name))

    def initUI(self):
        self.setWindowTitle("上传文件")
        self.setWindowIcon(QIcon("./icon/upload.ico"))
        self.logo = QLabel()
        self.logo.setPixmap(QPixmap("./icon/logo3.gif"))
        self.logo.setStyleSheet("background-color:rgb(0,153,255);")
        self.logo.setAlignment(Qt.AlignCenter)

        # btn 1
        self.btn_chooseDir = QPushButton("选择文件夹", self)
        self.btn_chooseDir.setObjectName("btn_chooseDir")
        self.btn_chooseDir.setObjectName("btn_chooseDir")
        self.btn_chooseDir.setIcon(QIcon("./icon/folder.gif"))

        # btn 2
        self.btn_chooseMutiFile = QPushButton("选择多文件", self)
        self.btn_chooseDir.setObjectName("btn_chooseMutiFile")
        self.btn_chooseMutiFile.setObjectName("btn_chooseMutiFile")
        self.btn_chooseMutiFile.setIcon(QIcon("./icon/file.ico"))

        # btn 3
        self.btn_deleteSelect = QPushButton("删除", self)
        self.btn_deleteSelect.setObjectName("btn_deleteSelect")
        self.btn_deleteSelect.setIcon(QIcon("./icon/delete.ico"))

        # 列表
        self.list_view = QListView(self)
        self.list_view.setViewMode(QListView.ListMode)
        self.slm = QStandardItem()
        self.model = QStandardItemModel()
        self.list_view.setModel(self.model)
        self.model.removeRows(0, self.model.rowCount())  # 清除旧的选择
        self.list_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.list_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.list_view.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)

        grid = QGridLayout()
        grid.setSpacing(10)
        grid.addWidget(self.logo, 1, 0, 1, 3)
        grid.addWidget(self.btn_chooseDir, 2, 0)
        grid.addWidget(self.btn_chooseMutiFile, 2, 2)
        grid.addWidget(self.list_view, 3, 0, 2, 3)
        grid.addWidget(self.btn_deleteSelect, 5, 0)
        grid.addWidget(self.buttonBox, 5, 1, 1, 2)
        self.setLayout(grid)

        self.setMinimumWidth(350)

        # 设置信号
        self.btn_chooseDir.clicked.connect(self.slot_btn_chooseDir)
        self.btn_chooseMutiFile.clicked.connect(self.slot_btn_chooseMutiFile)
        self.btn_deleteSelect.clicked.connect(self.slot_btn_deleteSelect)

        self.buttonBox.accepted.connect(self.slot_btn_ok)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.clear_old)
        self.buttonBox.rejected.connect(self.reject)

    def set_size(self):
        rows = self.model.rowCount()
        for i in range(rows):
            m_len = int(len(self.model.item(i, 0).text()) * 4)
            if m_len > self.max_len:
                self.max_len = m_len
        rows = 10 if rows >= 10 else rows  # 限制最大高度
        self.resize(self.max_len, 250 + rows * 28)

    def clear_old(self):
        self.selected = []
        self.model.removeRows(0, self.model.rowCount())
        self.set_size()

    def slot_btn_ok(self):
        if self.selected:
            self.new_infos.emit(self.selected)
            self.clear_old()

    def slot_btn_deleteSelect(self):
        _indexes = self.list_view.selectionModel().selection().indexes()
        if not _indexes:
            return
        indexes = []
        for i in _indexes:  # 获取所选行号
            indexes.append(i.row())
        indexes = set(indexes)
        for i in sorted(indexes, reverse=True):
            self.selected.remove(self.model.item(i, 0).text())
            self.model.removeRow(i)
        self.set_size()

    def slot_btn_chooseDir(self):
        dir_choose = QFileDialog.getExistingDirectory(self, "选择文件夹",
                                                      self.cwd)  # 起始路径

        if dir_choose == "":
            return
        if dir_choose not in self.selected:
            self.selected.append(dir_choose)
            self.model.appendRow(
                QStandardItem(QIcon("./icon/folder.gif"), dir_choose))
            self.set_size()

    def slot_btn_chooseMutiFile(self):
        files, _ = QFileDialog.getOpenFileNames(self, "选择多文件", self.cwd,
                                                "All Files (*)")
        if len(files) == 0:
            return

        for _file in files:
            if _file not in self.selected:
                self.selected.append(_file)
                self.model.appendRow(
                    QStandardItem(QIcon("./icon/file.ico"), _file))
        self.set_size()
コード例 #10
0
class MDIHistory(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(MDIHistory, self).__init__(parent)
        self.setMinimumSize(QSize(200, 150))
        self.setWindowTitle("PyQt5 editor test example")

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

        self.list = QListView()
        self.list.setEditTriggers(QListView.NoEditTriggers)
        self.list.activated.connect(self.activated)
        self.list.setAlternatingRowColors(True)
        self.list.selectionChanged = self.selectionChanged
        self.model = QStandardItemModel(self.list)

        self.MDILine = MDILine()
        self.MDILine.soft_keyboard = False
        self.MDILine.line_up = self.line_up
        self.MDILine.line_down = self.line_down

        STATUS.connect('mdi-history-changed', self.reload)

        # add widgets
        lay.addWidget(self.list)
        lay.addWidget(self.MDILine)

        self.fp = os.path.expanduser(INFO.MDI_HISTORY_PATH)
        try:
            open(self.fp, 'r')
        except:
            open(self.fp, 'a+')
            LOG.debug('MDI History file created: {}'.format(self.fp))
        self.reload()
        self.select_row('last')

    def _hal_init(self):
        STATUS.connect('state-off', lambda w: self.setEnabled(False))
        STATUS.connect('state-estop', lambda w: self.setEnabled(False))
        STATUS.connect(
            'interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on(
            ) and (STATUS.is_all_homed() or INFO.NO_HOME_REQUIRED)))
        STATUS.connect('interp-run',
                       lambda w: self.setEnabled(not STATUS.is_auto_mode()))
        STATUS.connect('all-homed',
                       lambda w: self.setEnabled(STATUS.machine_is_on()))

    def reload(self, w=None):
        self.model.clear()
        try:
            with open(self.fp, 'r') as inputfile:
                for line in inputfile:
                    line = line.rstrip('\n')
                    item = QStandardItem(line)
                    self.model.appendRow(item)
            self.list.setModel(self.model)
            self.list.scrollToBottom()
            if self.MDILine.hasFocus():
                self.select_row('last')
        except:
            LOG.debug('File path is not valid: {}'.format(fp))

    def selectionChanged(self, old, new):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        selectionModel = self.list.selectionModel()
        if selectionModel.hasSelection():
            self.row = selectionModel.currentIndex().row()

    def getSelected(self):
        selected_indexes = self.list.selectedIndexes()
        selected_rows = [item.row() for item in selected_indexes]
        # iterates each selected row in descending order
        for selected_row in sorted(selected_rows, reverse=True):
            text = self.model.item(selected_row).text()
            return text

    def activated(self):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        self.MDILine.submit()
        self.select_row('down')

    def run_command(self):
        self.MDILine.submit()
        self.select_row('last')

    def select_row(self, style):
        style = style.lower()
        selectionModel = self.list.selectionModel()
        parent = QModelIndex()
        self.rows = self.model.rowCount(parent) - 1
        if style == 'last':
            self.row = self.rows
            print 'last =', self.row
        elif style == 'up':
            if self.row > 0:
                self.row -= 1
            else:
                self.row = 0
        elif style == 'down':
            if self.row < self.rows:
                self.row += 1
            else:
                self.row = self.rows
        else:
            return
        top = self.model.index(self.row, 0, parent)
        bottom = self.model.index(self.row, 0, parent)
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    def line_up(self):
        self.select_row('up')

    def line_down(self):
        self.select_row('down')

    #########################################################################
    # This is how designer can interact with our widget properties.
    # designer will show the pyqtProperty properties in the editor
    # it will use the get set and reset calls to do those actions
    #########################################################################

    def set_soft_keyboard(self, data):
        self.MDILine.soft_keyboard = data

    def get_soft_keyboard(self):
        return self.MDILine.soft_keyboard

    def reset_soft_keyboard(self):
        self.MDILine.soft_keyboard = False

    # designer will show these properties in this order:
    soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard,
                                        set_soft_keyboard, reset_soft_keyboard)
コード例 #11
0
class ErrorVisualizeWidget(QWidget):
    def __init__(self, parent, mainwindow):
        super().__init__(parent)
        

        self.__widget_mainwindow = mainwindow
        self.__widget_matplotlib = ErrorVisualizeMatplotlibWidget(self)
        self.__current_layer = 0

        self.__widget_label_wrong_dimension = QLabel("", parent=self)

        self.__widget_label_layer = QLabel("<b>Layer</b>: ", parent=self)
        self.__widget_list_layer = QListView(self)
        self.__widget_list_layer.setModel(QStandardItemModel())
        self.__widget_list_layer.clicked.connect(self.set_layer)
        self.__widget_list_layer.selectionModel().selectionChanged.connect(self.set_layer)

        if not SDB_HAS_MATPLOTLIB:
            self.__widget_label_layer.setEnabled(False)
            self.__widget_list_layer.setEnabled(False)

        hbox_top = QHBoxLayout()
        hbox_top.addWidget(self.__widget_matplotlib)

        vbox_top = QVBoxLayout()
        vbox_top.addWidget(self.__widget_label_layer)
        vbox_top.addWidget(self.__widget_list_layer)
        hbox_top.addLayout(vbox_top)

        hbox_bottom = QHBoxLayout()
        hbox_bottom.addWidget(self.__widget_label_wrong_dimension)
        hbox_bottom.addStretch(1)

        vbox = QVBoxLayout()
        vbox.addLayout(hbox_top)
        vbox.addLayout(hbox_bottom)
        self.setLayout(vbox)

    def make_update(self, comparison_result):
        Logger.info("Updating ErrorVisualizeWidget")

        if not SDB_HAS_MATPLOTLIB:
            return

        self.__error_positions = comparison_result.get_error_positions()

        if self.__error_positions.ndim in (2, 3):
            self.__current_layer = 0
            self.__widget_matplotlib.draw_layer(self.__error_positions, self.__current_layer)

            self.__widget_list_layer.model().clear()
            if self.__error_positions.ndim == 3:
                self.__widget_label_layer.setEnabled(True)
                self.__widget_list_layer.setEnabled(True)

                for k in range(self.__error_positions.shape[2]):
                    item = QStandardItem("  %i" % k)

                    if any(self.__error_positions[:, :, k]):
                        item.setIcon(Icon("failure-small.png"))
                    else:
                        item.setIcon(Icon("success.png"))

                    item.setEditable(False)
                    self.__widget_list_layer.model().insertRow(k, item)
            else:
                self.__widget_label_layer.setEnabled(False)
                self.__widget_list_layer.setEnabled(False)

            self.__widget_label_wrong_dimension.setText("")
        else:
            self.__widget_matplotlib.draw_nothing()

            self.__widget_label_layer.setEnabled(False)
            self.__widget_list_layer.model().clear()
            self.__widget_list_layer.setEnabled(False)

            self.__widget_label_wrong_dimension.setText(
                "Visualization is only supported for 2 and 3-dimensional fields.")

    def set_layer(self, layer):
        if isinstance(layer, QItemSelection):
            layer = layer.indexes()[0]

        layer_idx = layer.row()

        self.__current_layer = layer_idx
        self.__widget_matplotlib.draw_layer(self.__error_positions, self.__current_layer)
コード例 #12
0
class PatchPanel(QGroupBox):
    """Group of widget to patch an universe"""
    def __init__(self, parent):
        super(PatchPanel, self).__init__()

        self.ola = parent.ola

        self.parent = parent

        self.device_selected = None

        self.universe = None

        grid = QGridLayout()
        self.inputs_model = PortList(self, 'input_mode')
        self.outputs_model = PortList(self, 'output_mode')
        self.devices = QListView()
        self.devices_model = DeviceList(self)
        self.devices.setModel(self.devices_model)
        self.inputs = QListView()
        self.inputs.setModel(self.inputs_model)
        self.inputs.setMinimumHeight(400)
        self.inputs.setMinimumHeight(120)
        self.outputs = QListView()
        self.outputs.setModel(self.outputs_model)
        self.outputs.setMinimumHeight(400)
        self.outputs.setMinimumHeight(120)

        # Universe Selected Change
        self.devices.selectionModel().selectionChanged.connect(
            self.device_selection_changed)

        devices_label = QLabel('Devices')
        grid.addWidget(devices_label, 0, 0, 1, 1)
        grid.addWidget(self.devices, 1, 0, 21, 1)
        inputs_label = QLabel('Inputs')
        grid.addWidget(inputs_label, 0, 1, 1, 1)
        grid.addWidget(self.inputs, 1, 1, 10, 1)
        outputs_label = QLabel('Outputs')
        grid.addWidget(outputs_label, 11, 1, 1, 1)
        grid.addWidget(self.outputs, 12, 1, 10, 1)
        grid.setSpacing(5)
        self.setLayout(grid)

    def display_ports(self, universe=None):
        """
        Request a list of Devices
        if universe == None, a list of None-Already-Patched ports is send

        """
        if universe is None:
            result = self.ola.client.GetCandidatePorts(
                self.GetCandidatePortsCallback, None)
            return result
        result = self.ola.client.FetchDevices(self.GetDevicesCallback, 0)
        return result

    def GetCandidatePortsCallback(self, status, devices):
        """
        Called for a new universe
        """
        if status.Succeeded():
            # clear the list of devices
            self.devices_model.devices = []
            if debug:
                print('found', len(devices), 'candidate devices')
            for device in devices:
                self.devices_model.devices.append(device)
        self.parent.ola.devicesList.emit()
        self.refresh_ports()

    def GetDevicesCallback(self, status, devices):
        """
        Fill-in universe menus with candidate devices/ports
        We need to make menus checkable to be able to patch ports
        """
        if status.Succeeded():
            # clear the list of devices
            self.devices_model.devices = []
            for device in devices:
                if device.input_ports == []:
                    # there is no input ports
                    if device.output_ports == []:
                        # no in + no out = no device
                        pass
                    else:
                        self.devices_model.devices.append(device)
                else:
                    self.devices_model.devices.append(device)
            if debug:
                print('found', len(self.devices_model.devices), 'devices')
        self.parent.ola.devicesList.emit()
        self.refresh_ports()
        # if there was a selection before, restore it
        #if self.device_selected:
        #self.devices.setSelection(self.device_selected)

    def refresh_ports(self):
        device = self.device_selected
        if device:
            # reset the models of inputs and outputs
            self.inputs_model.ports = []
            self.outputs_model.ports = []
            # Append input ports of this device to the inputs list model
            for port in device.input_ports:
                self.inputs_model.ports.append(port)
            # Append output ports of this device to the outputs list model
            for port in device.output_ports:
                self.outputs_model.ports.append(port)
            # please refresh Qlistview
            self.parent.ola.inPortsList.emit()
            self.parent.ola.outPortsList.emit()

    def device_selection_changed(self, device):
        # tell me which is the row selected
        row = device.indexes()[0].row()
        # tell me which device is associated with this row
        device = device.indexes()[0].model().object(row)
        self.device_selected = device
        # refresh ports list
        self.refresh_ports()
        if debug:
            print('selected device :', device.name)
コード例 #13
0
ファイル: mdi_history.py プロジェクト: LinuxCNC/linuxcnc
class MDIHistory(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(MDIHistory, self).__init__(parent)
        self.setMinimumSize(QSize(200, 150))    
        self.setWindowTitle("PyQt5 editor test example") 

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

        self.list = QListView()
        self.list.setEditTriggers(QListView.NoEditTriggers)
        self.list.activated.connect(self.activated)
        self.list.setAlternatingRowColors(True)
        self.list.selectionChanged = self.selectionChanged
        self.model = QStandardItemModel(self.list)

        self.MDILine = MDILine()
        self.MDILine.soft_keyboard = False
        self.MDILine.line_up = self.line_up
        self.MDILine.line_down = self.line_down

        STATUS.connect('reload-mdi-history', self.reload)

        # add widgets
        lay.addWidget(self.list)
        lay.addWidget(self.MDILine)

        self.fp = os.path.expanduser(INFO.MDI_HISTORY_PATH)
        try:
            open(self.fp, 'r')
        except:
            open(self.fp, 'a+')
            LOG.debug('MDI History file created: {}'.format(self.fp))
        self.reload()
        self.select_row('last')

    def _hal_init(self):
        STATUS.connect('state-off', lambda w: self.setEnabled(False))
        STATUS.connect('state-estop', lambda w: self.setEnabled(False))
        STATUS.connect('interp-idle', lambda w: self.setEnabled(STATUS.machine_is_on()
                                                                and (STATUS.is_all_homed()
                                                                or INFO.NO_HOME_REQUIRED)))
        STATUS.connect('interp-run', lambda w: self.setEnabled(not STATUS.is_auto_mode()))
        STATUS.connect('all-homed', lambda w: self.setEnabled(STATUS.machine_is_on()))

    def reload(self, w=None ):
        self.model.clear()
        try:
            with open(self.fp,'r') as inputfile:
                for line in inputfile:
                    line = line.rstrip('\n')
                    item = QStandardItem(line)
                    self.model.appendRow(item)
            self.list.setModel(self.model)
            self.list.scrollToBottom()
            if self.MDILine.hasFocus():
                self.select_row('last')
        except:
            LOG.debug('File path is not valid: {}'.format(fp))

    def selectionChanged(self,old, new):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        selectionModel = self.list.selectionModel()
        if selectionModel.hasSelection():
            self.row = selectionModel.currentIndex().row()

    def getSelected(self):
        selected_indexes = self.list.selectedIndexes()
        selected_rows = [item.row() for item in selected_indexes]
        # iterates each selected row in descending order
        for selected_row in sorted(selected_rows, reverse=True):
            text = self.model.item(selected_row).text()
            return text

    def activated(self):
        cmd = self.getSelected()
        self.MDILine.setText(cmd)
        self.MDILine.submit()
        self.select_row('down')

    def select_row(self, style):
        selectionModel = self.list.selectionModel()
        parent = QModelIndex()
        self.rows = self.model.rowCount(parent) - 1
        if style == 'last':
            self.row = self.rows
        elif style == 'up':
            if self.row > 0:
                self.row -= 1
            else:
                self.row = self.rows
        elif style == 'down':
            if self.row < self.rows:
                self.row += 1
            else:
                self.row = 0
        else:
            return
        top = self.model.index(self.row, 0, parent)
        bottom = self.model.index(self.row, 0, parent)
        selectionModel.setCurrentIndex(top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    def line_up(self):
        self.select_row('up')

    def line_down(self):
        self.select_row('down')

    #########################################################################
    # This is how designer can interact with our widget properties.
    # designer will show the pyqtProperty properties in the editor
    # it will use the get set and reset calls to do those actions
    #########################################################################

    def set_soft_keyboard(self, data):
        self.MDILine.soft_keyboard = data
    def get_soft_keyboard(self):
        return self.MDILine.soft_keyboard
    def reset_soft_keyboard(self):
        self.MDILine.soft_keyboard = False

    # designer will show these properties in this order:
    soft_keyboard_option = pyqtProperty(bool, get_soft_keyboard, set_soft_keyboard, reset_soft_keyboard)
コード例 #14
0
class LabelSelectionWidget(QWidget):
    """
    A widget for selection of label values.

    The widget displays the contents of the model with two widgets:

    * The top level model items are displayed in a combo box.
    * The children of the current selected top level item are
      displayed in a subordinate list view.

    .. note:: This is not a QAbstractItemView subclass.
    """
    #: Current group/root index has changed.
    groupChanged = Signal(int)
    #: Selection for the current group/root has changed.
    groupSelectionChanged = Signal()

    def __init__(self, parent=None, **kwargs):
        super().__init__(parent, **kwargs)
        self.__model = None
        self.__selectionMode = QListView.ExtendedSelection

        self.__currentIndex = -1
        self.__selections = {}

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

        def group_box(title):
            box = QGroupBox(title)
            box.setFlat(True)
            lay = QVBoxLayout()
            lay.setContentsMargins(0, 0, 0, 0)
            box.setLayout(lay)
            return box

        self.labels_combo = QComboBox()
        self.values_view = QListView(selectionMode=self.__selectionMode)

        self.labels_combo.currentIndexChanged.connect(
            self.__onCurrentIndexChanged)

        l_box = group_box(self.tr("Label"))
        v_box = group_box(self.tr("Values"))

        l_box.layout().addWidget(self.labels_combo)
        v_box.layout().addWidget(self.values_view)

        layout.addWidget(l_box)
        layout.addWidget(v_box)

        self.setLayout(layout)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    def clear(self):
        """ Clear the widget/model (same as ``setModel(None)``).
        """
        if self.__model is not None:
            self.values_view.selectionModel().clearSelection()
            self.values_view.selectionModel().selectionChanged.disconnect(
                self.__onSelectionChanged)

            self.values_view.setModel(None)
            self.labels_combo.setModel(QStandardItemModel(self.labels_combo))
            self.__currentIndex = -1
            self.__selections = {}
            self.__model = None

    def setModel(self, model):
        """
        Set the source model for display.

        The model should be a tree model with depth 2.

        Parameters
        ----------
        model : QtCore.QAbstractItemModel
        """
        if model is self.__model:
            return

        self.clear()

        if model is None:
            return

        self.__model = model
        self.values_view.setModel(model)
        self.values_view.setRootIndex(model.index(0, 0))
        self.values_view.selectionModel().selectionChanged.connect(
            self.__onSelectionChanged)
        # will emit the currentIndexChanged (if the model is not empty)
        self.labels_combo.setModel(model)

    def model(self):
        """
        Return the current model.

        Returns
        -------
        model : QtCore.QAbstractItemModel
        """
        return self.__model

    def setCurrentGroupIndex(self, index):
        """
        Set the current selected group/root index row.

        Parameters
        ----------
        index : int
            Group index.
        """
        self.labels_combo.setCurrentIndex(index)

    def currentGroupIndex(self):
        """
        Return the current selected group/root index row.

        Returns
        -------
        row : index
            Current group row index (-1 if there is no current index)
        """
        return self.labels_combo.currentIndex()

    def setSelection(self, selection):
        """
        Set the model item selection.

        Parameters
        ----------
        selection : QtCore.QItemSelection
            Item selection.
        """
        if self.values_view.selectionModel() is not None:
            indices = selection.indexes()
            pind = defaultdict(list)

            for index in indices:
                parent = index.parent()
                if parent.isValid():
                    if parent == self.__model.index(parent.row(),
                                                    parent.column()):
                        pind[parent.row()].append(QPersistentModelIndex(index))
                    else:
                        warnings.warn("Die Die Die")
                else:
                    # top level index
                    pass

            self.__selections = pind
            self.__restoreSelection()

    def selection(self):
        """
        Return the item selection.

        Returns
        -------
        selection : QtCore.QItemSelection
        """
        selection = QItemSelection()
        if self.__model is None:
            return selection

        for pind in chain(*self.__selections.values()):
            ind = self.__model.index(pind.row(), pind.column(), pind.parent())
            if ind.isValid():
                selection.select(ind, ind)
        return selection

    def currentGroupSelection(self):
        """
        Return the item selection for the current group only.
        """
        if self.values_view.selectionModel() is not None:
            return self.values_view.selectionModel().selection()
        else:
            return QItemSelection()

    def __onCurrentIndexChanged(self, index):
        self.__storeSelection(self.__currentIndex,
                              self.values_view.selectedIndexes())

        self.__currentIndex = index
        if self.__model is not None:
            root = self.__model.index(index, 0)
            self.values_view.setRootIndex(root)

            self.__restoreSelection()
        self.groupChanged.emit(index)

    def __onSelectionChanged(self, old, new):
        self.__storeSelection(self.__currentIndex,
                              self.values_view.selectedIndexes())

        self.groupSelectionChanged.emit()

    def __storeSelection(self, groupind, indices):
        # Store current values selection for the current group
        groupind = self.__currentIndex
        indices = [
            QPersistentModelIndex(ind)
            for ind in self.values_view.selectedIndexes()
        ]
        self.__selections[groupind] = indices

    def __restoreSelection(self):
        # Restore previous selection for root (if available)
        assert self.__model is not None
        groupind = self.__currentIndex
        root = self.__model.index(groupind, 0)
        sel = self.__selections.get(groupind, [])
        indices = [
            self.__model.index(pind.row(), pind.column(), root) for pind in sel
            if pind.isValid() and pind.parent() == root
        ]

        selection = QItemSelection()
        for ind in indices:
            selection.select(ind, ind)
        self.values_view.selectionModel().select(
            selection, QItemSelectionModel.ClearAndSelect)

    def sizeHint(self):
        """Reimplemented from QWidget.sizeHint"""
        return QSize(100, 200)
コード例 #15
0
class DictView(QWidget):
    BTN_ADDWORD_TEXT = 'Add'
    BTN_RMWORD_TEXT  = 'Remove'
    

    def __init__(self, parent: QObject = None, model: WordListModel = None, **kwargs):
        super().__init__(parent, **kwargs)

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

        self.b_addword = QPushButton(self.BTN_ADDWORD_TEXT)
        self.b_rmword  = QPushButton(self.BTN_RMWORD_TEXT)
        self.cmb_wordclass = QComboBox()
        
        for wc in WordClass:
            self.cmb_wordclass.addItem(wc.name)

        self.hsplitter = QSplitter(Qt.Horizontal)

        self.wordlistview = QListView()
        self.wordeditview = WordEditView()

        self.wordlsmdl = model

        self.wordlistview.activated.connect(self.wordeditview.handle_wordlistitem_activated)

        self.hsplitter.addWidget(self.wordlistview)
        self.hsplitter.addWidget(self.wordeditview)
        self.hsplitter.setSizes([PyDictAppView.DESKTOP_DEFAULT_WIDTH * 0.4, PyDictAppView.DESKTOP_DEFAULT_WIDTH * 0.6])

        self.lhb_control.addWidget(self.cmb_wordclass)
        self.lhb_control.addWidget(self.b_addword)
        self.lhb_control.addWidget(self.b_rmword)
        self.lhb_control.addStretch()

        self.layout.addLayout(self.lhb_control)
        self.layout.addWidget(self.hsplitter)
        self.setLayout(self.layout)

        self.b_addword.clicked.connect(self.handle_b_addword_clicked)
        self.b_rmword.clicked.connect(self.handle_b_rmword_clicked)


    @property
    def wordlsmdl(self) -> WordListModel:
        return self.wordlistview.model()

    @wordlsmdl.setter
    def wordlsmdl(self, value: WordListModel) -> None:
        assert (value is None) or isinstance(value, WordListModel), 'The wordlsmdl property of {} class shall have {} type.'\
               .format(self.__class__.__name__, WordListModel.__name__)
        self.wordlistview.setModel(value)
        self.wordeditview.wordlsmdl = value


    def handle_b_addword_clicked(self) -> None:
        wc = self.parse_wordclass()
        word_dialog = WordDialog(wc, self.wordlsmdl, self)
        word_dialog.show()
        word_dialog.exec()


    def handle_b_rmword_clicked(self) -> None:
        self.wordeditview.activate_wordview(None)
        sel_indexes = self.wordlistview.selectionModel().selectedIndexes()
        if sel_indexes is not None:
            for index in sel_indexes:
                guid = self.wordlsmdl.get_guid(index)
                event_wordremreq = EventWordRemoveRequest(guid)
                event_wordremreq.fire()


    def parse_wordclass(self) -> WordClass:
        wordclass_text = self.cmb_wordclass.currentText()
        if WordClass.__members__.get(wordclass_text) is None:
            return WordClass.NOUN
        else:
            return WordClass[wordclass_text]
コード例 #16
0
class SelectColumnDialog(QDialog):
    """
    Dialog for selecting a single column from the current dataframe
    """

    def __init__(self, columns=None, selected=None, parent=None):
        super(SelectColumnDialog, self).__init__(parent)
        self.setWindowTitle("Select Column")
        self.columns = columns
        self.selected = selected  # Name of selected variable, or None.

        # Available
        self.varlist_model = QStandardItemModel(self)

        # Proxy model for filtering/sorting
        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.varlist_model)
        self.proxy.setFilterKeyColumn(0)  # Filters based on the only column
        self.proxy.setFilterCaseSensitivity(
            Qt.CaseInsensitive
        )  # Case insensitive search

        # Setup Layout
        layout = QVBoxLayout(self)

        # Left Side Group Box ("Available")
        varlist_box = QGroupBox("Available Variables")
        varlist_box_layout = QVBoxLayout()
        # Multiselect listing available columns
        self.varlist = QListView(self)
        self.varlist.setModel(self.proxy)
        self.varlist.setSelectionMode(QAbstractItemView.SingleSelection)
        self.varlist.selectionModel().selectionChanged.connect(self.selected_change)
        self.varlist.setEditTriggers(QAbstractItemView.NoEditTriggers)
        varlist_box_layout.addWidget(self.varlist)

        # Add a search box
        self.varlist_search = QLineEdit(parent=self)
        self.varlist_search.setPlaceholderText("Search...")
        self.varlist_search.textChanged.connect(self.proxy.setFilterFixedString)
        varlist_box_layout.addWidget(self.varlist_search)

        # Set layout and add to the main layout
        varlist_box.setLayout(varlist_box_layout)
        layout.addWidget(varlist_box)

        # Ok/Cancel
        QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel

        self.buttonBox = QDialogButtonBox(QBtn)
        self.buttonBox.accepted.connect(self.submit)
        self.buttonBox.rejected.connect(self.reject)
        layout.addWidget(self.buttonBox)

        # Reset to update
        self.reset_list()

    def selected_change(self):
        """
        Update the current selection.  Disable "Ok" if nothing is selected.
        """
        selection_indexes = self.varlist.selectedIndexes()
        if len(selection_indexes) == 0:
            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        else:
            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)
            selected_index = selection_indexes[0]
            self.selected = self.proxy.itemData(selected_index)[0]

    def reset_list(self):
        """Clear the search field and show the full list"""
        self.varlist_search.setText("")
        self.varlist_model.clear()
        for idx, v in enumerate(self.columns):
            self.varlist_model.appendRow(QStandardItem(v))
            if v == self.selected:
                selection_index = self.varlist_model.index(idx, 0)
                mode = (
                    QtCore.QItemSelectionModel.Select | QtCore.QItemSelectionModel.Rows
                )
                self.varlist.selectionModel().select(selection_index, mode)

    def submit(self):
        # TODO: Add any warnings here
        self.selected = self.selected
        self.accept()

    @staticmethod
    def get_column(columns=None, selected=None, parent=None):
        if columns is None:
            return "No columns", None, None
        # Launch dialog to select a column
        dlg = SelectColumnDialog(columns, selected, parent)
        result = dlg.exec_()
        if result:
            # Update the selected value if the dialog accepted
            selected = dlg.selected
        return selected
コード例 #17
0
    def add_action(self, action):
        self.actions.append(action)


def list_view_current_changed():
    index = list_view.selectionModel().currentIndex()
    action = list_view.model().data(index, QtCore.Qt.UserRole)
    action.print_data()

    action = index.internalPointer()
    print(str(action))


if __name__ == "__main__":
    app = QApplication(sys.argv)

    list_view = QListView()

    actions_model = ActionsModel()
    actions_model.add_action(RandomList("l1"))
    actions_model.add_action(RandomList("l2"))
    actions_model.add_action(RandomList("l3"))

    list_view.setModel(actions_model)

    list_view.selectionModel().currentChanged.connect(list_view_current_changed)

    list_view.show()
    app.exec_()
コード例 #18
0
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'Qtvcp File System View'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.media_path = (os.path.join(os.path.expanduser('~'),
                                        'linuxcnc/nc_files'))
        user = os.path.split(os.path.expanduser('~'))[-1]
        self.user_path = (os.path.join('/media', user))
        self.currentPath = None
        self.currentFolder = None
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        pasteBox = QHBoxLayout()
        self.textLine = QLineEdit()
        self.textLine.setToolTip('Current Director/selected File')
        self.pasteButton = QToolButton()
        self.pasteButton.setEnabled(False)
        self.pasteButton.setText('Paste')
        self.pasteButton.setToolTip(
            'Copy file from copy path to current directory/file')
        self.pasteButton.clicked.connect(self.paste)
        self.pasteButton.hide()
        pasteBox.addWidget(self.textLine)
        pasteBox.addWidget(self.pasteButton)

        self.copyBox = QFrame()
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        self.copyLine = QLineEdit()
        self.copyLine.setToolTip('File path to copy from, when pasting')
        self.copyButton = QToolButton()
        self.copyButton.setText('Copy')
        self.copyButton.setToolTip('Record current file as copy path')
        self.copyButton.clicked.connect(self.recordCopyPath)
        hbox.addWidget(self.copyButton)
        hbox.addWidget(self.copyLine)
        self.copyBox.setLayout(hbox)
        self.copyBox.hide()

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.rootPathChanged.connect(self.folderChanged)

        self.list = QListView()
        self.list.setModel(self.model)
        self.updateDirectoryView(self.media_path)
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.listClicked)
        self.list.activated.connect(self._getPathActivated)
        self.list.setAlternatingRowColors(True)

        self.cb = QComboBox()
        self.cb.currentIndexChanged.connect(self.filterChanged)
        self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS)
        self.cb.setMinimumHeight(30)
        self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,
                                          QSizePolicy.Fixed))

        self.button2 = QToolButton()
        self.button2.setText('Media')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setMinimumSize(60, 30)
        self.button2.setToolTip('Jump to Media directory')
        self.button2.clicked.connect(self.onJumpClicked)

        SettingMenu = QMenu(self)
        self.settingMenu = SettingMenu
        for i in ('Media', 'User'):
            axisButton = QAction(QIcon.fromTheme('user-home'), i, self)
            # weird lambda i=i to work around 'function closure'
            axisButton.triggered.connect(
                lambda state, i=i: self.jumpTriggered(i))
            SettingMenu.addAction(axisButton)
        self.button2.setMenu(SettingMenu)

        self.button3 = QToolButton()
        self.button3.setText('Add Jump')
        self.button3.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button3.setMinimumSize(60, 30)
        self.button3.setToolTip('Add current directory to jump button list')
        self.button3.clicked.connect(self.onActionClicked)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button2)
        hbox.addWidget(self.button3)
        hbox.insertStretch(2, stretch=0)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addLayout(pasteBox)
        windowLayout.addWidget(self.copyBox)
        windowLayout.addWidget(self.list)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_loaded_directory',
                                            self.media_path, str,
                                            'BOOK_KEEPING')
            self.updateDirectoryView(last_path)
            LOG.debug("lAST FILE PATH: {}".format(last_path))
        else:
            LOG.debug("lAST FILE PATH: {}".format(self.media_path))
            self.updateDirectoryView(self.media_path)

    #########################
    # callbacks
    #########################

    # add shown text and hidden filter data from the INI
    def fillCombobox(self, data):
        for i in data:
            self.cb.addItem(i[0], i[1])

    def folderChanged(self, data):
        self.currentFolder = data
        self.textLine.setText(data)

    def updateDirectoryView(self, path):
        self.list.setRootIndex(self.model.setRootPath(path))

    # retrieve selected filter (it's held as QT.userData)
    def filterChanged(self, index):
        userdata = self.cb.itemData(index)
        self.model.setNameFilters(userdata)

    def listClicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            self.textLine.setText(self.currentPath)
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)

    def onUserClicked(self):
        self.showUserDir()

    def onMediaClicked(self):
        self.showMediaDir()

    def onJumpClicked(self):
        data = self.button2.text()
        if data == 'Media':
            self.showMediaDir()
        elif data == 'User':
            self.showUserDir()
        else:
            self.updateDirectoryView(self.button2.text())

    def jumpTriggered(self, data):
        if data == 'Media':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to Media directory')
            self.showMediaDir()
        elif data == 'User':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to User directory')
            self.showUserDir()
        else:
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to directory: {}'.format(data))
            self.updateDirectoryView(self.button2.text())

    def onActionClicked(self):
        i = self.currentFolder
        button = QAction(QIcon.fromTheme('user-home'), i, self)
        # weird lambda i=i to work around 'function closure'
        button.triggered.connect(lambda state, i=i: self.jumpTriggered(i))
        self.settingMenu.addAction(button)

    # get current selection and update the path
    # then if the path is good load it into linuxcnc
    # record it in the preference file if available
    def _getPathActivated(self):
        row = self.list.selectionModel().currentIndex()
        self.listClicked(row)

        fname = self.currentPath
        if fname is None:
            return
        if fname:
            self.load(fname)

    def recordCopyPath(self):
        data, isFile = self.getCurrentSelected()
        if isFile:
            self.copyLine.setText(os.path.normpath(data))
            self.pasteButton.setEnabled(True)
        else:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)
            STATUS.emit('error', OPERATOR_ERROR,
                        'Can only copy a file, not a folder')

    def paste(self):
        res = self.copyFile(self.copyLine.text(), self.textLine.text())
        if res:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)

    ########################
    # helper functions
    ########################

    def showCopyControls(self, state):
        if state:
            self.copyBox.show()
            self.pasteButton.show()
        else:
            self.copyBox.hide()
            self.pasteButton.hide()

    def showMediaDir(self):
        self.updateDirectoryView(self.user_path)

    def showUserDir(self):
        self.updateDirectoryView(self.media_path)

    def copyFile(self, s, d):
        try:
            shutil.copy(s, d)
            return True
        except Exception as e:
            LOG.error("Copy file error: {}".format(e))
            STATUS.emit('error', OPERATOR_ERROR,
                        "Copy file error: {}".format(e))
            return False

    # moves the selection up
    # used with MPG scrolling
    def up(self):
        self.select_row('up')

    # moves the selection down
    # used with MPG scrolling
    def down(self):
        self.select_row('down')

    def select_row(self, style='down'):
        style = style.lower()
        selectionModel = self.list.selectionModel()
        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(self.list.rootIndex())

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows:
                row += 1
            else:
                row = self.rows
        else:
            return
        top = self.model.index(row, 0, self.list.rootIndex())
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    # returns the current highlighted (selected) path as well as
    # whether it's a file or not.
    def getCurrentSelected(self):
        selectionModel = self.list.selectionModel()
        index = selectionModel.currentIndex()
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            return (dir_path, True)
        else:
            return (dir_path, False)

    # This can be class patched to do something else
    def load(self, fname=None):
        if fname is None:
            self._getPathActivated()
            return
        self.recordBookKeeping()
        ACTION.OPEN_PROGRAM(fname)
        STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')

    # This can be class patched to do something else
    def recordBookKeeping(self):
        fname = self.currentPath
        if fname is None:
            return
        if self.PREFS_:
            self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(),
                                str, 'BOOK_KEEPING')
            self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')
コード例 #19
0
class HardwareSelector(QDialog):
    def __init__(self, host, port, parent=None):
        QDialog.__init__(self, parent)
        self.host = host
        self.port = port

        self._layout = QVBoxLayout(self)
        self.setWindowTitle("Hardware on " + self.host + ":" + str(self.port))
        self.setMinimumSize(800, 600)

        self.hardware = None
        self.selectedHW = None
        self._model = None

        self._lbl_status = QLabel()
        self._layout.addWidget(self._lbl_status)

        self._layoutH = QHBoxLayout()
        self._layout.addLayout(self._layoutH)

        self._hwlist = QListView()
        self._layoutH.addWidget(self._hwlist)

        self._lbl_hw = QLabel()
        self._lbl_hw.setMinimumWidth(400)
        self._lbl_hw.setMargin(10)
        self._lbl_hw.setFont(QFontDatabase.systemFont(QFontDatabase.FixedFont))
        #self._layoutH.addWidget(self._hwlabel)
        self._hwscroll = QScrollArea()
        self._hwscroll.setWidget(self._lbl_hw)
        self._layoutH.addWidget(self._hwscroll)

        self._layoutB = QHBoxLayout()
        self._layout.addLayout(self._layoutB)

        self._btn_select = QPushButton("Select")
        self._layoutB.addWidget(self._btn_select)
        self._btn_rescan = QPushButton("Rescan")
        self._layoutB.addWidget(self._btn_rescan)
        self._btn_cancel = QPushButton("Cancel")
        self._layoutB.addWidget(self._btn_cancel)

        self._btn_select.clicked.connect(self._select)
        self._btn_cancel.clicked.connect(lambda:
                                         (self._quitScan(), self.close()))
        self._btn_rescan.clicked.connect(self._prepareScan)

        self._disable()
        self._start()

    def _start(self, ret=None):
        if not ret:
            self._prepareScan()
            ret = self._getHardware()
        if ret:
            self.hardware = ret[0]
            if len(self.hardware) == 0:
                self._lbl_status.setText(
                    "No Hardware detected. Is Caffepath set?")
            elif ret[1] == 0:
                self._lbl_status.setText("Currently selected CPU: " +
                                         ret[0][0]["name"])
            else:
                self._lbl_status.setText("Currently selected GPU " +
                                         str(ret[1]) + ": " +
                                         ret[0][ret[1]]["name"])
            self._model = self.HardwareListModel(self.hardware)
            self._hwlist.setModel(self._model)
            self._hwlist.selectionModel().currentChanged.connect(
                self._onSelection)
            self._enable()

    def _enable(self):
        self._hwlist.setEnabled(True)
        self._btn_rescan.setEnabled(True)

    def _disable(self):
        self._hwlist.setEnabled(False)
        self._btn_select.setEnabled(False)
        self._btn_rescan.setEnabled(False)
        self._lbl_hw.setText("")
        if self._hwlist.selectionModel():
            self._hwlist.selectionModel().currentChanged.disconnect()
            self._hwlist.setModel(None)

    def _select(self):
        self.selectedHW = self._hwlist.currentIndex().row()
        self.close()

    def _onSelection(self):
        row = self._hwlist.currentIndex().row()
        if row != -1:
            self._lbl_hw.setText(self._getText(row))
            self._lbl_hw.adjustSize()
            self._btn_select.setEnabled(True)
        else:
            self._lbl_hw.setText("")

    def _getText(self, row):
        log = self.hardware[row]["log"]
        text = ""
        for l in log:
            text += l + "\n"
        return text

    def _prepareScan(self):
        self._disable()
        ct = buildTransaction(self.host, self.port)
        if ct:
            self.ct = ct
            msg = {"key": Protocol.SCANHARDWARE}
            self.ct.send(msg)
            self.ct.bufferReady.connect(self._processScan)
            self.ct.socketClosed.connect(self._socketClosed)
            self._lbl_status.setText("Start scanning...")
        else:
            self._lbl_status.setText("Failed to start Scan.")

    def _processScan(self):
        msg = self.ct.asyncRead()
        if msg["status"]:
            if "finished" in msg.keys():
                if msg["finished"]:
                    self._quitScan()
                    self._lbl_status.setText("Scan finished.")
                    self._start([msg["hardware"], msg["current"]])
                else:
                    if "id" in msg.keys():
                        self._lbl_status.setText("Found GPU " +
                                                 str(msg["id"]) + ": " +
                                                 msg["name"])
                    else:
                        self._lbl_status.setText("Found CPU: " + msg["name"])
        else:
            self._lbl_status.setText("Scan failed: " + msg["error"])

    def _socketClosed(self):
        self._quitScan()
        self._enable()
        self._lbl_status.setText("Connection lost!")

    def _quitScan(self):
        if hasattr(self, "ct"):
            self.ct.bufferReady.disconnect()
            self.ct.socketClosed.disconnect()
            self.ct.close()
            del self.ct

    def _getHardware(self):
        msg = {"key": Protocol.GETHARDWARE}
        ret = sendMsgToHost(self.host, self.port, msg)
        if ret and "hardware" in ret:
            return [ret["hardware"], ret["current"]]

    class HardwareListModel(QAbstractListModel):
        def __init__(self, data):
            QAbstractListModel.__init__(self)
            self.data = data

        def rowCount(self, parent=None, *args, **kwargs):
            return len(self.data)

        def data(self, index, role=None):
            row = index.row()
            if role == Qt.DisplayRole:
                if row == 0:
                    return "CPU: " + self.data[row]["name"]
                return "GPU " + str(
                    self.data[row]["id"]) + ": " + self.data[row]["name"]
コード例 #20
0
ファイル: client_gui2.py プロジェクト: vsurguch/client
class AppWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setGeometry(100, 100, 550, 400)
        self.setUpMenu()
        self.setUpLayout()
        self.checkBoxConnect.stateChanged.connect(self.connect_disconnect)
        self.addButton.clicked.connect(self.add_contact)
        self.deleteButton.clicked.connect(self.delete_contact)
        self.sendButton.clicked.connect(self.send_message)
        self.contactsList.clicked.connect(self.select_contact)
        # self.messageField.drop.connect(self.add_file_to_message)

        # model -controller - view
        self.contact_list_model = StandardItemModelContacts(self)
        self.messages_list_model = StandardItemModelMessages(self)
        self.model = ClientModel(self.contact_list_model,
                                 self.messages_list_model)
        self.contactsList.setModel(self.contact_list_model)
        self.messagesList.setModel(self.messages_list_model)
        self.controller = ClientController(self.model)

        # signal-slot
        self.controller.auth_recieved.connect(self.authentification_recieved)
        self.controller.gotPersonal.connect(self.new_personal_message)

        # not connected
        self.connected = False
        # nobody selected
        self.currently_selected = ''

    def setUpMenu(self):
        fileMenu = self.menuBar().addMenu('File')
        quitAct = QAction('Quit', self)
        quitAct.triggered.connect(self.doQuit)
        fileMenu.addAction(quitAct)
        sendMenu = self.menuBar().addMenu('Send')
        sendFile = QAction('Send File', self)
        sendFile.triggered.connect(self.doSendFile)
        sendMenu.addAction(sendFile)

    def setUpLayout(self):
        hBoxLayout = QHBoxLayout()
        mainFrame = QFrame()
        mainFrame.setLayout(hBoxLayout)

        self.contact = QLineEdit()
        self.contact.setFont(QFont('Calibri', 14))
        self.contact.setPlaceholderText('Add Contact Here')
        self.contact.setMinimumHeight(30)
        self.contact.setMaximumHeight(30)

        self.addButton = QPushButton('+')
        self.addButton.setMinimumHeight(30)
        self.addButton.setMaximumHeight(30)
        self.addButton.setMinimumWidth(30)
        self.addButton.setMaximumWidth(30)

        self.deleteButton = QPushButton('-')
        self.deleteButton.setMinimumHeight(30)
        self.deleteButton.setMaximumHeight(30)
        self.deleteButton.setMinimumWidth(30)
        self.deleteButton.setMaximumWidth(30)

        self.contactsList = QListView()
        self.contactsList.setFrameShape(QFrame.Box)

        spacer = QFrame()
        spacer.setMaximumWidth(5)

        self.nameLabel = QLabel('Username')
        self.nameLabel.setMinimumHeight(30)
        self.nameLabel.setMaximumHeight(30)
        self.nameLabel.setFont(QFont('Calibri', 14))
        self.checkBoxConnect = QCheckBox()
        self.checkBoxConnect.setText('Connect')
        self.checkBoxConnect.setChecked(False)
        self.checkBoxConnect.setMaximumHeight(30)
        self.checkBoxConnect.setMinimumHeight(30)
        self.checkBoxConnect.setMaximumWidth(70)
        self.checkBoxConnect.setMinimumWidth(70)

        self.messagesList = QListView()
        self.messagesList.setIconSize(QSize(30, 30))
        self.messagesList.setFrameShape(QFrame.Box)
        self.messageField = MessageField()
        self.messageField.setMinimumHeight(50)
        self.messageField.setMaximumHeight(50)
        self.sendButton = QPushButton()
        self.sendButton.setText('>>')
        self.sendButton.setMinimumHeight(50)
        self.sendButton.setMaximumHeight(50)
        self.sendButton.setMinimumWidth(50)
        self.sendButton.setMaximumWidth(50)

        contBox = QGridLayout()
        contBox.addWidget(self.contact, 0, 0)
        contBox.addWidget(self.addButton, 0, 1)
        contBox.addWidget(self.deleteButton, 0, 2)
        contBox.addWidget(self.contactsList, 1, 0, 2, 3)
        contBox.addWidget(spacer, 0, 3, 3, 1)
        contBox.addWidget(self.nameLabel, 0, 4)
        contBox.addWidget(self.checkBoxConnect, 0, 5, 1, 2)
        contBox.addWidget(self.messagesList, 1, 4, 1, 3)
        contBox.addWidget(self.messageField, 2, 4, 1, 2)
        contBox.addWidget(self.sendButton, 2, 6)
        contBox.setColumnStretch(0, 3)
        contBox.setColumnStretch(4, 6)
        groupBoxCont = QFrame()
        groupBoxCont.setLayout(contBox)

        self.setCentralWidget(groupBoxCont)

    def doQuit(self):
        self.close()

    def doSendFile(self):
        filename = QFileDialog.getOpenFileName(self, 'Open file', '/home')[0]
        self.messageField.file = filename
        self.messageField.appendPlainText(filename)

    def connect_disconnect(self):
        self.checkBoxConnect.setEnabled(False)
        if self.checkBoxConnect.isChecked():
            self.authentification()
        else:
            self.user_disconnect()
            self.checkBoxConnect.setEnabled(True)

    # Log in  dialog
    def authentification(self):
        #read config file
        d = conf.read_conf()
        #show Authorization dialog
        auth_dialog = AuthDialog(self.model,
                                 d['username'],
                                 d['hostname'],
                                 d['port'],
                                 parent=self)
        auth_dialog.accepted.connect(self.auth_dialog_accepted)
        auth_dialog.rejected.connect(self.auth_dialog_rejected)
        auth_dialog.show()

    def auth_dialog_accepted(self):
        self.checkBoxConnect.setEnabled(True)
        self.controller.run_client()

    def auth_dialog_rejected(self):
        self.checkBoxConnect.setChecked(False)
        self.checkBoxConnect.setEnabled(True)

    @pyqtSlot(bool)
    def authentification_recieved(self, ok):
        if ok:
            self.connected = True
            self.checkBoxConnect.setText('Connected')
            self.nameLabel.setText('{}:'.format(self.model.username))
            self.model.contactlist.clear()
            self.model.personal_messages = []
            self.model.server_messages = []
            self.model.sent_messages = []
            self.model.open_db()
            self.controller.ask_contact_list()
        else:
            self.checkBoxConnect.setChecked(False)

    def user_disconnect(self):
        if self.connected:
            conf.save_conf(username=self.model.username,
                           hostname=self.model.host,
                           port=str(self.model.port))
            self.model.clear_data()
            self.controller.user_disconnect()
            self.contact.setText('')
            self.nameLabel.setText('')
            self.checkBoxConnect.setText('Connect')
            self.connected = False
            self.currently_selected = ''

    @pyqtSlot(str)
    def get_contact_list(self):
        pass

    def add_contact(self):
        name = self.contact.text()
        if name != '':
            self.controller.add_contact(name)
            self.contact.setText('')

    def delete_contact(self):
        name = self.contact.text()
        if name != '':
            self.controller.delete_contact(name)
            self.contact.setText('')

    @pyqtSlot(QMimeData)
    def add_file_to_message(self, mime):
        self.messageField.setPlainText(mime.text())

    def send_message(self):
        sel_list = self.contactsList.selectionModel().selectedIndexes()
        if len(sel_list) > 0:
            contact = self.model.contactlist.contacts[sel_list[0].row()]
            if self.messageField.file != '':
                self.controller.send_file(contact.name, self.messageField.file)
                self.messageField.file = ''
            else:
                self.controller.personal_message(
                    contact.name, self.messageField.toPlainText())
            self.messageField.clear()
            self.model.update_messages_for_contact(contact.name)
        else:
            pass

    @pyqtSlot(QModelIndex)
    def select_contact(self, modelindex):
        item = self.contact_list_model.data(modelindex, role=Qt.DisplayRole)
        contact_name = self.model.contactlist.contacts_name[modelindex.row()]
        self.contact.setText(contact_name)
        self.show_messages_for_contact(contact_name)
        self.contactsList.setCurrentIndex(modelindex)
        self.currently_selected = contact_name

    @pyqtSlot(str)
    def new_personal_message(self, sender):
        self.model.new_message_increase(sender, True)
        # sel_list = self.listViewContacts.selectionModel().selectedIndexes()
        if sender == self.currently_selected:
            self.show_messages_for_contact(self.currently_selected)

    @pyqtSlot(str)
    def show_messages_for_contact(self, contact_name):
        self.model.update_messages_for_contact(contact_name)
        self.model.new_message_increase(contact_name, False)
        self.messagesList.scrollToBottom()
コード例 #21
0
class EditList(QWidget):
    """An editable List-Widget to display and manipulate the content of a list.

    Parameters
    ----------
    data : List of str | None
        Input a list with contents to display
    parent : QWidget | None
        Parent Widget (QWidget or inherited) or None if there is no parent

    Notes
    -----
    If you change the list outside of this class, call content_changed to update this widget
    """

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

        self.model = EditListModel(data)
        self.view = QListView()
        self.view.setModel(self.model)

        self.layout = QVBoxLayout()

        self.init_ui()

    def init_ui(self):
        self.layout.addWidget(self.view)

        if self.ui_buttons:
            bt_layout = QHBoxLayout()

            addrow_bt = QPushButton('Add Row')
            addrow_bt.clicked.connect(self.add_row)
            bt_layout.addWidget(addrow_bt)

            rmrow_bt = QPushButton('Remove Row')
            rmrow_bt.clicked.connect(self.remove_row)
            bt_layout.addWidget(rmrow_bt)

            edit_bt = QPushButton('Edit')
            edit_bt.clicked.connect(self.edit_item)
            bt_layout.addWidget(edit_bt)

            self.layout.addLayout(bt_layout)

        self.setLayout(self.layout)

    def content_changed(self):
        """Informs ModelView about external change made in data
        """
        self.model.layoutChanged.emit()

    def replace_data(self, new_data):
        """Replaces model._data with new_data
        """
        self.model._data = new_data
        self.content_changed()

    def add_row(self):
        row = self.view.selectionModel().currentIndex().row()
        self.model.insertRow(row)

    def remove_row(self):
        row_idxs = self.view.selectionModel().selectedRows()
        for row_idx in row_idxs:
            self.model.removeRow(row_idx.row())

    def edit_item(self):
        self.view.edit(self.view.selectionModel().currentIndex())
コード例 #22
0
class EDFilterListWidget(QWidget):
    """FilterListWidget Combines a QLineEdit and a QListView"""
    add = pyqtSignal()
    remove = pyqtSignal()

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

        v_layout = QVBoxLayout(self)
        h_layout = QHBoxLayout()

        filter_frame = QFrame(self)
        filter_h_layout = QHBoxLayout(filter_frame)
        filter_h_layout.setContentsMargins(0, 0, 0, 0)
        size_policy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        filter_frame.setSizePolicy(size_policy)

        filter_lbl = QLabel("Filter")
        self.line_edit = QLineEdit(self)

        filter_h_layout.addWidget(filter_lbl)
        filter_h_layout.addWidget(self.line_edit)

        h_layout.addWidget(filter_frame)
        self.line_edit.textEdited.connect(self.filter)

        self.list = QListView(self)
        self.model = QStandardItemModel(self.list)
        self.list.setModel(self.model)
        size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.list.setSizePolicy(size_policy)

        v_layout.addLayout(h_layout)
        v_layout.addWidget(self.list)

        self.controls = EDAddRemoveButtons(parent=self)
        self.controls.add_btn.clicked.connect(self.add_item)
        self.controls.rm_btn.clicked.connect(self.remove_item)
        v_layout.addWidget(self.controls)

    def filter(self, filter_text):
        """Hides rows that do not have the pattern"""
        for row in range(self.model.rowCount()):
            if filter_text in str(self.model.item(row).text()).lower():
                self.list.setRowHidden(row, False)
            else:
                self.list.setRowHidden(row, True)

    @pyqtSlot()
    def add_item(self):
        """Add item"""
        self.add.emit()

    @pyqtSlot()
    def remove_item(self):
        """Remove Item"""
        self.remove.emit()

    def clear(self):
        """Clear the model"""
        self.model.clear()

    # pylint: disable=invalid-name
    def takeItem(self, row: int):
        """Take Item from the list"""
        item = self.model.takeItem(row)
        self.model.takeRow(row)
        return item

    # pylint: disable=invalid-name
    def addItem(self, item: Union[QListWidgetItem, QStandardItem, str]):
        """Add Item to the list"""
        if isinstance(item, str):
            item = QStandardItem(item)
        self.model.appendRow(item)

    def count(self):
        """Convenience method"""
        return self.model.rowCount()

    def item(self, row):
        """Convenience method to reveal model method"""
        return self.model.item(row)

    # pylint: disable=invalid-name
    def selectedIndexes(self):
        """Convenience Function to revel selectionModel option"""
        return self.list.selectionModel().selectedIndexes()

    # pylint: disable=invalid-name
    def selectedItems(self):
        """Convenience to replicate functionality in QListWidget"""
        inds = self.selectedIndexes()
        items = [self.item(i.row()) for i in inds]
        return items
コード例 #23
0
ファイル: main.py プロジェクト: petersohn/photo-organizer
 def _get_selected_items(self, view: W.QListView) -> List[int]:
     return [
         index.row() for index in view.selectionModel().selectedIndexes()
     ]
コード例 #24
0
class _StyleList(QWidget):
    def __init__(
        self,
        api: Api,
        model: AssStylesModel,
        selection_model: QItemSelectionModel,
        parent: QWidget,
    ) -> None:
        super().__init__(parent)
        self._api = api
        self._model = model
        selection_model.selectionChanged.connect(self._on_selection_change)

        self._styles_list_view = QListView(self)
        self._styles_list_view.setModel(model)
        self._styles_list_view.setSelectionModel(selection_model)

        self._add_button = QPushButton("Add", self)
        self._add_button.clicked.connect(self._on_add_button_click)
        self._remove_button = QPushButton("Remove", self)
        self._remove_button.setEnabled(False)
        self._remove_button.clicked.connect(self._on_remove_button_click)
        self._duplicate_button = QPushButton("Duplicate", self)
        self._duplicate_button.setEnabled(False)
        self._duplicate_button.clicked.connect(self._on_duplicate_button_click)
        self._move_up_button = QPushButton("Move up", self)
        self._move_up_button.setEnabled(False)
        self._move_up_button.clicked.connect(self._on_move_up_button_click)
        self._move_down_button = QPushButton("Move down", self)
        self._move_down_button.setEnabled(False)
        self._move_down_button.clicked.connect(self._on_move_down_button_click)
        self._rename_button = QPushButton("Rename", self)
        self._rename_button.setEnabled(False)
        self._rename_button.clicked.connect(self._on_rename_button_click)

        strip = QWidget(self)
        strip_layout = QGridLayout(strip)
        strip_layout.setContentsMargins(0, 0, 0, 0)
        strip_layout.addWidget(self._add_button, 0, 0)
        strip_layout.addWidget(self._remove_button, 0, 1)
        strip_layout.addWidget(self._duplicate_button, 0, 2)
        strip_layout.addWidget(self._move_up_button, 1, 0)
        strip_layout.addWidget(self._move_down_button, 1, 1)
        strip_layout.addWidget(self._rename_button, 1, 2)

        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._styles_list_view)
        layout.addWidget(strip)

    @property
    def _selected_style(self) -> Optional[AssStyle]:
        selected_row = self._selected_row
        if selected_row is None:
            return None
        return self._api.subs.styles[selected_row]

    @property
    def _selected_row(self) -> Optional[int]:
        indexes = self._styles_list_view.selectedIndexes()
        if not indexes:
            return None
        return cast(int, indexes[0].row())

    def _on_selection_change(
        self,
        selected: QItemSelection,
        _deselected: QItemSelection,
    ) -> None:
        anything_selected = len(selected.indexes()) > 0
        self._remove_button.setEnabled(anything_selected)
        self._rename_button.setEnabled(anything_selected)
        self._duplicate_button.setEnabled(anything_selected)
        self._move_up_button.setEnabled(anything_selected
                                        and selected.indexes()[0].row() > 0)
        self._move_down_button.setEnabled(
            anything_selected
            and selected.indexes()[0].row() < len(self._api.subs.styles) - 1)

    @async_slot()
    async def _on_add_button_click(self) -> None:
        style_name = await self._prompt_for_unique_style_name()
        if not style_name:
            return

        style = AssStyle(name=style_name)
        self._api.subs.styles.append(style)
        idx = style.index

        self._styles_list_view.selectionModel().select(
            self._model.index(idx, 0),
            QItemSelectionModel.SelectionFlag(
                QItemSelectionModel.SelectionFlag.Clear
                | QItemSelectionModel.SelectionFlag.Select),
        )

    async def _prompt_for_unique_style_name(self,
                                            style_name: str = ""
                                            ) -> Optional[str]:
        prompt_text = "Name of the new style:"
        while True:
            dialog = QInputDialog(self)
            dialog.setLabelText(prompt_text)
            dialog.setTextValue(style_name)
            dialog.setInputMode(QInputDialog.TextInput)
            if not await async_dialog_exec(dialog):
                return None
            style_name = dialog.textValue()

            exists = False
            for style in self._api.subs.styles:
                if style.name == style_name:
                    exists = True

            if not exists:
                return style_name

            prompt_text = '"{}" already exists. Choose different name:'.format(
                style_name)

    @async_slot()
    async def _on_remove_button_click(self) -> None:
        style = self._selected_style
        assert style is not None
        idx = style.index

        if not await show_prompt(
                f'Are you sure you want to remove style "{style.name}"?',
                self):
            return

        self._styles_list_view.selectionModel().clear()
        with self._api.undo.capture():
            del self._api.subs.styles[idx]

    def _on_duplicate_button_click(self, event: QMouseEvent) -> None:
        style = self._selected_style
        assert style is not None
        idx = style.index

        style_copy = copy(style)
        style_copy.name += " (copy)"
        with self._api.undo.capture():
            self._api.subs.styles.insert(idx + 1, style_copy)
        self._styles_list_view.selectionModel().select(
            self._model.index(idx + 1, 0),
            QItemSelectionModel.SelectionFlag(
                QItemSelectionModel.SelectionFlag.Clear
                | QItemSelectionModel.SelectionFlag.Select),
        )

    def _on_move_up_button_click(self, event: QMouseEvent) -> None:
        style = self._selected_style
        assert style is not None
        idx = style.index

        with self._api.undo.capture():
            self._api.subs.styles[idx:idx + 1] = []
            self._api.subs.styles[idx - 1:idx - 1] = [style]
        self._styles_list_view.selectionModel().select(
            self._model.index(idx - 1, 0),
            QItemSelectionModel.SelectionFlag(
                QItemSelectionModel.SelectionFlag.Clear
                | QItemSelectionModel.SelectionFlag.Select),
        )

    def _on_move_down_button_click(self, event: QMouseEvent) -> None:
        style = self._selected_style
        assert style is not None
        idx = style.index

        with self._api.undo.capture():
            self._api.subs.styles[idx:idx + 1] = []
            self._api.subs.styles[idx + 1:idx + 1] = [style]
        self._styles_list_view.selectionModel().select(
            self._model.index(idx + 1, 0),
            QItemSelectionModel.SelectionFlag(
                QItemSelectionModel.SelectionFlag.Clear
                | QItemSelectionModel.SelectionFlag.Select),
        )

    @async_slot()
    async def _on_rename_button_click(self) -> None:
        style = self._selected_style
        assert style is not None
        idx = style.index

        old_name = style.name
        new_name = await self._prompt_for_unique_style_name(old_name)
        if not new_name:
            return

        with self._api.undo.capture():
            style.name = new_name
            for line in self._api.subs.events:
                if line.style_name == old_name:
                    line.style_name = new_name

        self._styles_list_view.selectionModel().select(
            self._model.index(idx, 0),
            QItemSelectionModel.SelectionFlag.Select)
コード例 #25
0
class Explorer(QWidget):
    def __init__(self, rootdir=QDir.rootPath()):
        QWidget.__init__(self)
        self.treeview = QTreeView()
        self.listview = QListView()
        self.path = rootdir
        self.filename = ''
        self.filepath = rootdir
        self.canvas = None
        self.col_selector = None

        self.header = ''
        self.xcol = [1]
        self.ycol = [1]
        self.ncols = 0

        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(self.path)
        self.dirModel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)

        self.fileModel = QFileSystemModel()
        self.fileModel.setRootPath(self.filepath)
        self.fileModel.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.fileModel.setNameFilters(['*.txt'])
        self.fileModel.setNameFilterDisables(0)

        self.treeview.setModel(self.dirModel)
        self.listview.setModel(self.fileModel)
        for i in [1, 2, 3]: self.treeview.setColumnHidden(i, True)
        self.treeview.setHeaderHidden(True)

        self.treeview.setRootIndex(self.dirModel.index(self.path))
        self.listview.setRootIndex(self.fileModel.index(self.path))

        self.treeview.clicked.connect(self.on_clicked)
        self.listview.selectionModel().currentChanged.connect(self.file_selected)
        self.listview.selectionModel().currentChanged.connect(lambda: self.canvas.update_plot(self))
        self.listview.selectionModel().currentChanged.connect(lambda: self.col_selector.update_range(self.ncols))

    def on_clicked(self, index):
        self.path = self.dirModel.fileInfo(index).absoluteFilePath()
        self.listview.setRootIndex(self.fileModel.setRootPath(self.path))

    def file_selected(self, index):
        self.filename = self.fileModel.fileName(index)
        self.filepath = self.fileModel.filePath(index)
        self.load_file()

    def load_file(self):
        try:
            if self.filepath.endswith('.txt'):
                with open(self.filepath, 'r') as file:
                        self.header, self.xcol, self.ycol = '', [], []
                        for ln in file:
                            if ln.startswith('#'):
                                self.header += ln[2:]
                            else:
                                cols = ln.split('\t')
                                self.xcol.append(float(cols[0]))
                                self.ycol.append(float(cols[self.col_selector.sp.value()]))
                        self.ncols = len(cols)
                        self.col_selector.update_range(self.ncols)
        except:
            self.header, self.xcol, self.ycol = '', [0], [0]

    def update_rootdir(self, rootdir):
        self.path = rootdir
        self.treeview.setRootIndex(self.dirModel.index(self.path))
        self.listview.setRootIndex(self.fileModel.index(self.path))
コード例 #26
0
ファイル: main.py プロジェクト: vikas-vm/mediaProQT
class MainWindow(QWidget):

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

        self.playlistView = QListView()
        self.switch_status = 2
        self.video_widget = QVideoWidget()
        self.playlist = QMediaPlaylist()
        self.model = PlaylistModel(self.playlist)
        self.titleBar = TitleBar(self)
        self.currentTimeLabel = QLabel()
        self.timeSlider = QSlider()
        self.totalTimeLabel = QLabel()
        self.mediaPlayer = QMediaPlayer()
        self.open_btn = QPushButton('Open File')
        self.play_btn = QPushButton()
        self.prev_btn = QPushButton()
        self.stop_btn = QPushButton()
        self.next_btn = QPushButton()
        self.switch_media_widgets_btn = QPushButton()
        self.pseudo_label = QLabel()

        self.vol_label = QLabel()
        self.volume_slider = Slider(Qt.Horizontal)
        self.gui()
        self.set_children_focus_policy(Qt.NoFocus)

    def gui(self):
        self.currentTimeLabel.setMinimumSize(QSize(80, 0))
        self.currentTimeLabel.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)

        self.timeSlider.setOrientation(Qt.Horizontal)
        self.totalTimeLabel.setMinimumSize(QSize(80, 0))
        self.totalTimeLabel.setAlignment(Qt.AlignLeading | Qt.AlignLeft | Qt.AlignVCenter)

        self.playlistView.setAcceptDrops(True)
        self.playlistView.setProperty("showDropIndicator", True)
        self.playlistView.setDragDropMode(QAbstractItemView.DropOnly)
        self.playlistView.setAlternatingRowColors(True)
        self.playlistView.setUniformItemSizes(True)

        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setWindowTitle('Media Player')
        self.titleBar.label.setText('Media Player')
        self.setWindowIcon(QIcon('icon_png/media_player.png'))

        self.setGeometry(600, 200, 850, 600)
        self.timeSlider.setRange(0, 0)
        self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.prev_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipBackward))
        self.next_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipForward))
        self.stop_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
        self.switch_media_widgets_btn.setIcon(self.style().standardIcon(QStyle.SP_FileDialogDetailedView))
        self.vol_label.setText("")
        self.vol_label.setPixmap(QPixmap("icon_png/speaker-volume.png"))
        self.currentTimeLabel.setText("00:00")
        self.totalTimeLabel.setText("00:00")
        self.volume_slider.setValue(self.mediaPlayer.volume())
        self.mediaPlayer.setVideoOutput(self.video_widget)
        self.mediaPlayer.setPlaylist(self.playlist)
        self.playlistView.setModel(self.model)
        self.video_widget.hide()

        sizegrip = QSizeGrip(self)

        self.setAcceptDrops(True)

        inner_h_box = QHBoxLayout()
        inner_h_box.addWidget(self.prev_btn)
        inner_h_box.addWidget(self.stop_btn)
        inner_h_box.addWidget(self.next_btn)

        vol_h_box = QHBoxLayout()
        vol_h_box.addWidget(self.vol_label, 0)
        vol_h_box.addWidget(self.volume_slider, 1)

        h_box = QHBoxLayout()
        h_box.addWidget(self.open_btn)
        h_box.addWidget(self.play_btn, 0)
        h_box.addLayout(inner_h_box, 0)
        h_box.addWidget(self.switch_media_widgets_btn, 0)
        h_box.addWidget(self.pseudo_label, 1)
        h_box.addLayout(vol_h_box, 0)
        h_box.addWidget(sizegrip, 0, Qt.AlignBottom | Qt.AlignRight)

        video_slider_h_box = QHBoxLayout()
        video_slider_h_box.addWidget(self.currentTimeLabel)
        video_slider_h_box.addWidget(self.timeSlider)
        video_slider_h_box.addWidget(self.totalTimeLabel)

        v_box = QVBoxLayout()
        v_box.addWidget(self.titleBar, 0)
        v_box.addWidget(self.video_widget, 1)
        v_box.addWidget(self.playlistView, 1)
        v_box.addLayout(video_slider_h_box, 0)
        v_box.addLayout(h_box, 0)

        inner_h_box.setContentsMargins(20, 0, 10, 0)
        vol_h_box.setContentsMargins(0, 0, 20, 0)
        h_box.setContentsMargins(20, 0, 0, 0)
        v_box.setContentsMargins(0, 0, 0, 0)
        video_slider_h_box.setSpacing(10)
        h_box.setSpacing(0)
        v_box.setSpacing(0)

        self.setLayout(v_box)
        self.enabler()

        # connections
        self.open_btn.clicked.connect(self.open_file)
        self.play_btn.clicked.connect(self.play_media)
        self.stop_btn.clicked.connect(self.stop_media)

        self.prev_btn.pressed.connect(self.play_prev)
        self.next_btn.pressed.connect(self.play_next)
        self.switch_media_widgets_btn.pressed.connect(self.switch_media)

        self.playlist.currentIndexChanged.connect(self.playlist_position_changed)
        selection_model = self.playlistView.selectionModel()
        selection_model.selectionChanged.connect(self.playlist_selection_changed)

        self.mediaPlayer.durationChanged.connect(self.update_duration)
        self.mediaPlayer.positionChanged.connect(self.update_position)
        self.timeSlider.valueChanged.connect(self.mediaPlayer.setPosition)

        self.mediaPlayer.stateChanged.connect(self.media_state)

        self.mediaPlayer.volumeChanged.connect(self.volume_changed)
        self.volume_slider.valueChanged.connect(self.set_volume)

    def set_children_focus_policy(self, policy):
        def recursive_set_child_focus_policy(parent_q_widget):
            for childQWidget in parent_q_widget.findChildren(QWidget):
                childQWidget.setFocusPolicy(policy)
                recursive_set_child_focus_policy(childQWidget)

        recursive_set_child_focus_policy(self)

    def enabler(self, state=False):
        if state is False:
            self.play_btn.setEnabled(False)
            self.prev_btn.setEnabled(False)
            self.stop_btn.setEnabled(False)
            self.next_btn.setEnabled(False)
        else:
            self.play_btn.setEnabled(True)
            self.stop_btn.setEnabled(True)
            self.prev_btn.setEnabled(True)
            self.next_btn.setEnabled(True)

    def switch_media(self):
        if self.switch_status == 0:
            self.video_widget.hide()
            self.playlistView.show()
            self.switch_status = 1
            self.switch_media_widgets_btn.setEnabled(True)
        elif self.switch_status == 1:
            self.video_widget.show()
            self.playlistView.hide()
            self.switch_status = 0
            self.switch_media_widgets_btn.setEnabled(True)
        else:
            self.video_widget.hide()
            self.playlistView.show()
            self.switch_media_widgets_btn.setEnabled(False)

    def play_media(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()
        self.ui_handler()

    def ui_handler(self):
        if not self.playlist.isEmpty():
            self.enabler(True)
        file_path = QFileInfo(self.mediaPlayer.currentMedia().canonicalUrl().toString()).fileName()
        ext = os.path.splitext(file_path)[-1].lower()
        audio_ext = ['.flac', '.mp3']
        video_ext = ['.mp4', '.m4a', '.mov', '.flv', 'avi', '3gp', '.mkv', '.wmv']

        if ext in audio_ext:
            self.switch_status = 2
            self.switch_media()
            if self.isFullScreen():
                self.fullscreen()
        elif ext in video_ext:
            self.switch_status = 1
            self.switch_media()
        self.setWindowTitle(file_path + ' - Media Player')
        self.titleBar.label.setText(file_path + ' - Media Player')

    def stop_media(self):
        if self.mediaPlayer.state() != QMediaPlayer.StoppedState:
            self.mediaPlayer.stop()
            self.setWindowTitle('Media Player')
            self.titleBar.label.setText('Media Player')

    def fullscreen(self):
        if self.switch_status == 2 or self.isFullScreen():
            self.titleBar.show()
            self.timeSlider.show()
            self.currentTimeLabel.show()
            self.totalTimeLabel.show()
            self.volume_slider.show()
            self.open_btn.show()
            self.play_btn.show()
            self.prev_btn.show()
            self.stop_btn.show()
            self.next_btn.show()
            self.switch_media_widgets_btn.show()
            self.pseudo_label.show()
            self.vol_label.show()
            self.showNormal()
        else:
            self.titleBar.hide()
            self.timeSlider.hide()
            self.currentTimeLabel.hide()
            self.totalTimeLabel.hide()
            self.volume_slider.hide()
            self.open_btn.hide()
            self.play_btn.hide()
            self.prev_btn.hide()
            self.stop_btn.hide()
            self.next_btn.hide()
            self.switch_media_widgets_btn.hide()
            self.pseudo_label.hide()
            self.vol_label.hide()
            self.showFullScreen()

    def mouseDoubleClickEvent(self, event: QMouseEvent):
        event.accept()
        if event.button() == Qt.LeftButton:
            self.fullscreen()

    def media_state(self):

        os_sleep = WindowsInhibitor()
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
            if os.name == 'nt':
                os_sleep = WindowsInhibitor()
                os_sleep.inhibit()
        else:
            self.play_btn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
            if os_sleep:
                os_sleep.uninhibit()

    def play_next(self):
        self.playlist.next()

    def media_seek(self, seek):
        if not self.playlist.isEmpty():
            player = self.mediaPlayer
            if (player.duration() - seek) > player.position():
                player.setPosition(player.position() + seek)

    def play_prev(self):
        self.playlist.previous()

    def dragEnterEvent(self, e):
        if e.mimeData().hasUrls():
            e.acceptProposedAction()

    def dropEvent(self, e):
        for url in e.mimeData().urls():
            ext = os.path.splitext(url.fileName())[-1].lower()
            allowed_ext = ['.flac', '.mp3', '.mp4', '.m4a', '.mov', '.flv', 'avi', '3gp', '.mkv', '.wmv']
            if ext in allowed_ext:
                self.playlist.addMedia(
                    QMediaContent(url)
                )

        self.model.layoutChanged.emit()

        if self.mediaPlayer.state() != QMediaPlayer.PlayingState:
            i = self.playlist.mediaCount() - len(e.mimeData().urls())
            self.playlist.setCurrentIndex(i)
            if not self.playlist.isEmpty():
                self.play_media()

    def open_file(self):
        filter_files = "Media (*.mp3 *.mp4 *.mkv);; Videos files (*.mp4 *.mkv);; Music Files(*.mp3)"
        paths, _ = QFileDialog.getOpenFileNames(self, "Open file", "", filter_files)

        if paths:
            self.mediaPlayer.pause()
            for path in paths:
                self.playlist.addMedia(
                    QMediaContent(
                        QUrl.fromLocalFile(path)
                    )
                )
            i = self.playlist.mediaCount() - len(paths)
            self.playlist.setCurrentIndex(i)
            self.play_media()

        self.model.layoutChanged.emit()

    def update_duration(self, duration):
        self.mediaPlayer.duration()

        self.timeSlider.setMaximum(duration)

        if duration >= 0:
            self.totalTimeLabel.setText(hhmmss(duration))

    def update_position(self, position):
        if position >= 0:
            self.currentTimeLabel.setText(hhmmss(position))

        self.timeSlider.blockSignals(True)
        self.timeSlider.setValue(position)
        self.timeSlider.blockSignals(False)

    def playlist_selection_changed(self, ix):
        i = ix.indexes()[0].row()
        self.playlist.setCurrentIndex(i)
        self.ui_handler()

    def playlist_position_changed(self, i):
        if i > -1:
            ix = self.model.index(i)
            self.playlistView.setCurrentIndex(ix)

    def set_volume(self, value):
        self.mediaPlayer.setVolume(value)

    def volume_changed(self, value):
        self.volume_slider.setValue(value)

    def keyPressEvent(self, event):
        key = event.key()
        modifiers = int(event.modifiers())
        if (modifiers and modifiers & MOD_MASK == modifiers and
                key > 0 and key != Qt.Key_Shift and key != Qt.Key_Alt and
                key != Qt.Key_Control and key != Qt.Key_Meta):
            key_name = QKeySequence(modifiers + key).toString()
            if key_name == 'Ctrl+Right':
                self.media_seek(30000)
            elif key_name == 'Ctrl+Left':
                self.media_seek(-30000)
            elif key_name == 'Ctrl+Up':
                self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 5)
            elif key_name == 'Ctrl+Down':
                self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 5)
            elif key_name == 'Ctrl+O':
                self.open_file()

        else:
            if event.key() == Qt.Key_Space:
                self.play_media()
            elif event.key() == Qt.Key_MediaPlay:
                self.play_media()
            elif event.key() == Qt.Key_MediaNext:
                self.play_next()
            elif event.key() == Qt.Key_MediaPrevious:
                self.play_prev()
            elif event.key() == Qt.Key_Escape:
                self.close()
            elif event.key() == Qt.Key_F:
                self.fullscreen()
            elif event.key() == Qt.Key_Right:
                self.media_seek(5000)
            elif event.key() == Qt.Key_Left:
                self.media_seek(-5000)
コード例 #27
0
ファイル: file_manager.py プロジェクト: def187/linuxcnc
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'PyQt5 file system view - pythonspot.com'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.default_path = (os.path.join(os.path.expanduser('~'), 'linuxcnc/nc_files/examples'))
        self.user_path = (os.path.join('/media'))
        self.currentPath = None
        self.EXT = INFO.PROGRAM_FILTERS_EXTENSIONS
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.setNameFilters(self.EXT)

        self.list = QListView()
        self.list.setModel(self.model)
        self.updateDirectoryView(self.default_path)
        self.list.setWindowTitle("Dir View")
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.clicked)
        self.list.activated.connect(self._getPathActivated)
        #self.list.currentChanged = self.currentChanged
        self.list.setAlternatingRowColors(True)

        self.cb = QComboBox()
        self.cb.currentTextChanged.connect(self.filterChanged)
        self.cb.addItems(self.EXT)
        #self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.button = QPushButton()
        self.button.setText('Media')
        self.button.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button.setToolTip('Jump to Media directory')
        self.button.clicked.connect(self.onMediaClicked)

        self.button2 = QPushButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setToolTip('Jump to linuxcnc directory')
        self.button2.clicked.connect(self.onUserClicked)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button)
        hbox.addWidget(self.button2)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.list)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    # this could return the current/previous selected as it's selected.
    # need to uncomment monkey patch of self.list.currentChanged above
    # so far this is not needed
    def currentChanged(self,c,p):
        dir_path = self.model.filePath(c)
        print('-> ',dir_path)

    def updateDirectoryView(self, path):
        self.list.setRootIndex(self.model.setRootPath(path))

    def filterChanged(self, text):
        self.model.setNameFilters([text])

    def clicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)

    def onMediaClicked(self):
        self.updateDirectoryView(self.user_path)

    def onUserClicked(self):
        self.updateDirectoryView(self.default_path)

    def select_row(self, style):
        style = style.lower()
        selectionModel = self.list.selectionModel()
        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(self.list.rootIndex())

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows:
                row += 1
            else:
                row = self.rows
        else:
            return
        top = self.model.index(row, 0, self.list.rootIndex())
        selectionModel.setCurrentIndex(top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    # returns the current highlighted (selected) path as well as
    # whether it's a file or not.
    def getCurrentSelected(self):
        selectionModel = self.list.selectionModel()
        index = selectionModel.currentIndex()
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            return (dir_path, True)
        else:
            return (dir_path, False)

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_loaded_directory', self.default_path, str, 'BOOK_KEEPING')
            self.updateDirectoryView(last_path)
            LOG.debug("lAST FILE PATH: {}".format(last_path))
        else:
            LOG.debug("lAST FILE PATH: {}".format(self.default_path))
            self.updateDirectoryView(self.default_path)

    # get current selection and update the path
    # then if the path is good load it into linuxcnc
    # record it in the preference file if available
    def _getPathActivated(self):
        row = self.list.selectionModel().currentIndex()
        self.clicked(row)

        fname = self.currentPath
        if fname is None: 
            return
        if fname:
            self.load(fname)

    # this can be class patched to do something else
    def load(self, fname=None):
        if fname is None:
            self._getPathActivated()
            return
        self.recordBookKeeping()
        ACTION.OPEN_PROGRAM(fname)
        STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')

    # this can be class patched to do something else
    def recordBookKeeping(self):
        fname = self.currentPath
        if fname is None: 
            return
        if self.PREFS_:
            self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(), str, 'BOOK_KEEPING')
            self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')

    # moves the selection up
    # used with MPG scrolling
    def up(self):
        self.select_row('up')

    # moves the selection down
    # used with MPG scrolling
    def down(self):
        self.select_row('down')
コード例 #28
0
ファイル: file_manager.py プロジェクト: zym1rm/linuxcnc
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'Qtvcp File System View'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self._last = 0

        if INFO.PROGRAM_PREFIX is not None:
            self.user_path = os.path.expanduser(INFO.PROGRAM_PREFIX)
        else:
            self.user_path = (os.path.join(os.path.expanduser('~'),
                                           'linuxcnc/nc_files'))
        user = os.path.split(os.path.expanduser('~'))[-1]
        self.media_path = (os.path.join('/media', user))
        temp = [('User', self.user_path), ('Media', self.media_path)]
        self._jumpList = OrderedDict(temp)
        self.currentPath = None
        self.currentFolder = None
        self.PREFS_ = None
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        pasteBox = QHBoxLayout()
        self.textLine = QLineEdit()
        self.textLine.setToolTip('Current Director/selected File')
        self.pasteButton = QToolButton()
        self.pasteButton.setEnabled(False)
        self.pasteButton.setText('Paste')
        self.pasteButton.setToolTip(
            'Copy file from copy path to current directory/file')
        self.pasteButton.clicked.connect(self.paste)
        self.pasteButton.hide()
        pasteBox.addWidget(self.textLine)
        pasteBox.addWidget(self.pasteButton)

        self.copyBox = QFrame()
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        self.copyLine = QLineEdit()
        self.copyLine.setToolTip('File path to copy from, when pasting')
        self.copyButton = QToolButton()
        self.copyButton.setText('Copy')
        self.copyButton.setToolTip('Record current file as copy path')
        self.copyButton.clicked.connect(self.recordCopyPath)
        hbox.addWidget(self.copyButton)
        hbox.addWidget(self.copyLine)
        self.copyBox.setLayout(hbox)
        self.copyBox.hide()

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.rootPathChanged.connect(self.folderChanged)

        self.list = QListView()
        self.list.setModel(self.model)
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.listClicked)
        self.list.activated.connect(self._getPathActivated)
        self.list.setAlternatingRowColors(True)
        self.list.hide()

        self.table = QTableView()
        self.table.setModel(self.model)
        self.table.resize(640, 480)
        self.table.clicked[QModelIndex].connect(self.listClicked)
        self.table.activated.connect(self._getPathActivated)
        self.table.setAlternatingRowColors(True)

        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        header.swapSections(1, 3)
        header.setSortIndicator(1, Qt.AscendingOrder)

        self.table.setSortingEnabled(True)
        self.table.setColumnHidden(2, True)  # type
        self.table.verticalHeader().setVisible(False)  # row count header

        self.cb = QComboBox()
        self.cb.currentIndexChanged.connect(self.filterChanged)
        self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS)
        self.cb.setMinimumHeight(30)
        self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,
                                          QSizePolicy.Fixed))

        self.button2 = QToolButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setMinimumSize(60, 30)
        self.button2.setToolTip(
            'Jump to User directory.\nLong press for Options.')
        self.button2.clicked.connect(self.onJumpClicked)

        self.button3 = QToolButton()
        self.button3.setText('Add Jump')
        self.button3.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button3.setMinimumSize(60, 30)
        self.button3.setToolTip('Add current directory to jump button list')
        self.button3.clicked.connect(self.onActionClicked)

        self.settingMenu = QMenu(self)
        self.button2.setMenu(self.settingMenu)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button2)
        hbox.addWidget(self.button3)
        hbox.insertStretch(2, stretch=0)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addLayout(pasteBox)
        windowLayout.addWidget(self.copyBox)
        windowLayout.addWidget(self.list)
        windowLayout.addWidget(self.table)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_loaded_directory',
                                            self.user_path, str,
                                            'BOOK_KEEPING')
            LOG.debug("lAST FILE PATH: {}".format(last_path))
            if not last_path == '':
                self.updateDirectoryView(last_path)
            else:
                self.updateDirectoryView(self.user_path)

            # get all the saved jumplist paths
            temp = self.PREFS_.getall('FILEMANAGER_JUMPLIST')
            self._jumpList.update(temp)

        else:
            LOG.debug("lAST FILE PATH: {}".format(self.user_path))
            self.updateDirectoryView(self.user_path)

        # install jump paths into toolbutton menu
        for i in self._jumpList:
            self.addAction(i)

        # set recorded columns sort settings
        self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName()))
        sect = self.SETTINGS_.value('sortIndicatorSection', type=int)
        order = self.SETTINGS_.value('sortIndicatorOrder', type=int)
        self.SETTINGS_.endGroup()
        if not None in (sect, order):
            self.table.horizontalHeader().setSortIndicator(sect, order)

    # when qtvcp closes this gets called
    # record jump list paths
    def _hal_cleanup(self):
        if self.PREFS_:
            for i, key in enumerate(self._jumpList):
                if i in (0, 1):
                    continue
                self.PREFS_.putpref(key, self._jumpList.get(key), str,
                                    'FILEMANAGER_JUMPLIST')

        # record sorted columns
        h = self.table.horizontalHeader()
        self.SETTINGS_.beginGroup("FileManager-{}".format(self.objectName()))
        self.SETTINGS_.setValue('sortIndicatorSection',
                                h.sortIndicatorSection())
        self.SETTINGS_.setValue('sortIndicatorOrder', h.sortIndicatorOrder())
        self.SETTINGS_.endGroup()

    #########################
    # callbacks
    #########################

    # add shown text and hidden filter data from the INI
    def fillCombobox(self, data):
        for i in data:
            self.cb.addItem(i[0], i[1])

    def folderChanged(self, data):
        data = os.path.normpath(data)
        self.currentFolder = data
        self.textLine.setText(data)

    def updateDirectoryView(self, path, quiet=False):
        if os.path.exists(path):
            self.list.setRootIndex(self.model.setRootPath(path))
            self.table.setRootIndex(self.model.setRootPath(path))
        else:
            LOG.debug(
                "Set directory view error - no such path {}".format(path))
            if not quiet:
                STATUS.emit(
                    'error', LOW_ERROR,
                    "File Manager error - No such path: {}".format(path))

    # retrieve selected filter (it's held as QT.userData)
    def filterChanged(self, index):
        userdata = self.cb.itemData(index)
        self.model.setNameFilters(userdata)

    def listClicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = os.path.normpath(self.model.filePath(index))
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            self.textLine.setText(self.currentPath)
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)
        self.table.setRootIndex(root_index)

    def onUserClicked(self):
        self.showUserDir()

    def onMediaClicked(self):
        self.showMediaDir()

    # jump directly to a saved path shown on the button
    def onJumpClicked(self):
        data = self.button2.text()
        if data.upper() == 'MEDIA':
            self.showMediaDir()
        elif data.upper() == 'USER':
            self.showUserDir()
        else:
            temp = self._jumpList.get(data)
            if temp is not None:
                self.updateDirectoryView(temp)
            else:
                STATUS.emit('error', linuxcnc.OPERATOR_ERROR,
                            'file jumopath: {} not valid'.format(data))
                log.debug('file jumopath: {} not valid'.format(data))

    # jump directly to a saved path from the menu
    def jumpTriggered(self, data):
        if data.upper() == 'MEDIA':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip(
                'Jump to Media directory.\nLong press for Options.')
            self.showMediaDir()
        elif data.upper() == 'USER':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip(
                'Jump to User directory.\nLong press for Options.')
            self.showUserDir()
        else:
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to directory:\n{}'.format(
                self._jumpList.get(data)))
            self.updateDirectoryView(self._jumpList.get(data))

    # add a jump list path
    def onActionClicked(self):
        i = self.currentFolder
        try:
            self._jumpList[i] = i
        except Exception as e:
            print(e)
        button = QAction(QIcon.fromTheme('user-home'), i, self)
        # weird lambda i=i to work around 'function closure'
        button.triggered.connect(lambda state, i=i: self.jumpTriggered(i))
        self.settingMenu.addAction(button)

    # get current selection and update the path
    # then if the path is good load it into linuxcnc
    # record it in the preference file if available
    def _getPathActivated(self):
        if self.list.isVisible():
            row = self.list.selectionModel().currentIndex()
        else:
            row = self.table.selectionModel().currentIndex()
            self.listClicked(row)

        fname = self.currentPath
        if fname is None:
            return
        if fname:
            self.load(fname)

    def recordCopyPath(self):
        data, isFile = self.getCurrentSelected()
        if isFile:
            self.copyLine.setText(os.path.normpath(data))
            self.pasteButton.setEnabled(True)
        else:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)
            STATUS.emit('error', OPERATOR_ERROR,
                        'Can only copy a file, not a folder')

    def paste(self):
        res = self.copyFile(self.copyLine.text(), self.textLine.text())
        if res:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)

    ########################
    # helper functions
    ########################

    def addAction(self, i):
        axisButton = QAction(QIcon.fromTheme('user-home'), i, self)
        # weird lambda i=i to work around 'function closure'
        axisButton.triggered.connect(lambda state, i=i: self.jumpTriggered(i))
        self.settingMenu.addAction(axisButton)

    def showList(self, state=True):
        if state:
            self.table.hide()
            self.list.show()
        else:
            self.table.show()
            self.list.hide()

    def showTable(self, state=True):
        self.showList(not state)

    def showCopyControls(self, state):
        if state:
            self.copyBox.show()
            self.pasteButton.show()
        else:
            self.copyBox.hide()
            self.pasteButton.hide()

    def showMediaDir(self, quiet=False):
        self.updateDirectoryView(self.media_path, quiet)

    def showUserDir(self, quiet=False):
        self.updateDirectoryView(self.user_path, quiet)

    def copyFile(self, s, d):
        try:
            shutil.copy(s, d)
            return True
        except Exception as e:
            LOG.error("Copy file error: {}".format(e))
            STATUS.emit('error', OPERATOR_ERROR,
                        "Copy file error: {}".format(e))
            return False

    @pyqtSlot(float)
    @pyqtSlot(int)
    def scroll(self, data):
        if data > self._last:
            self.up()
        elif data < self._last:
            self.down()
        self._last = data

    # moves the selection up
    # used with MPG scrolling
    def up(self):
        self.select_row('up')

    # moves the selection down
    # used with MPG scrolling
    def down(self):
        self.select_row('down')

    def select_row(self, style='down'):
        style = style.lower()
        if self.list.isVisible():
            i = self.list.rootIndex()
            selectionModel = self.list.selectionModel()
        else:
            i = self.table.rootIndex()
            selectionModel = self.table.selectionModel()

        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(i)

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows - 1:
                row += 1
            else:
                row = self.rows - 1
        else:
            return
        top = self.model.index(row, 0, i)
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    # returns the current highlighted (selected) path as well as
    # whether it's a file or not.
    def getCurrentSelected(self):
        if self.list.isVisible():
            selectionModel = self.list.selectionModel()
        else:
            selectionModel = self.table.selectionModel()
        index = selectionModel.currentIndex()
        dir_path = os.path.normpath(self.model.filePath(index))
        if self.model.fileInfo(index).isFile():
            return (dir_path, True)
        else:
            return (dir_path, False)

    # This can be class patched to do something else
    def load(self, fname=None):
        try:
            if fname is None:
                self._getPathActivated()
                return
            self.recordBookKeeping()
            ACTION.OPEN_PROGRAM(fname)
            STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')
        except Exception as e:
            LOG.error("Load file error: {}".format(e))
            STATUS.emit('error', NML_ERROR, "Load file error: {}".format(e))

    # This can be class patched to do something else
    def recordBookKeeping(self):
        fname = self.currentPath
        if fname is None:
            return
        if self.PREFS_:
            self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(),
                                str, 'BOOK_KEEPING')
            self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')
コード例 #29
0
ファイル: tivopy.py プロジェクト: emanuel-mazilu/TIVOpy
class VideoPlayer(QWidget):

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

        self.setAttribute(Qt.WA_NoSystemBackground, True)
        self.setAcceptDrops(True)
        
        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.StreamPlayback)
        self.mediaPlayer.setVolume(80)
        
        self.videoWidget = QVideoWidget(self)
        self.videoWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.videoWidget.setMinimumSize(QSize(640, 360))
        
        self.lbl = QLineEdit('00:00:00')
        self.lbl.setReadOnly(True)
        self.lbl.setFixedWidth(70)
        self.lbl.setUpdatesEnabled(True)
        self.lbl.setStyleSheet(stylesheet(self))

        self.elbl = QLineEdit('00:00:00')
        self.elbl.setReadOnly(True)
        self.elbl.setFixedWidth(70)
        self.elbl.setUpdatesEnabled(True)
        self.elbl.setStyleSheet(stylesheet(self))

        self.playButton = QPushButton()
        self.playButton.setEnabled(False)
        self.playButton.setFixedWidth(32)
        self.playButton.setStyleSheet("background-color: black")
        self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.playButton.clicked.connect(self.play)

        self.positionSlider = QSlider(Qt.Horizontal, self)
        self.positionSlider.setStyleSheet(stylesheet(self))
        self.positionSlider.setRange(0, 100)
        self.positionSlider.sliderMoved.connect(self.setPosition)
        self.positionSlider.sliderMoved.connect(self.handleLabel)
        self.positionSlider.setSingleStep(2)
        self.positionSlider.setPageStep(20)
        self.positionSlider.setAttribute(Qt.WA_TranslucentBackground, True)

        self.clip = QApplication.clipboard()
        self.process = QProcess(self)
        self.process.readyRead.connect(self.dataReady)
        self.process.finished.connect(self.playFromURL)

        self.myurl = ""

        # channel list
        self.channelList = QListView(self)
        self.channelList.setMinimumSize(QSize(150, 0))
        self.channelList.setMaximumSize(QSize(150, 4000))
        self.channelList.setFrameShape(QFrame.Box)
        self.channelList.setObjectName("channelList")
        self.channelList.setStyleSheet("background-color: black; color: #585858;")
        self.channelList.setFocus()
        # for adding items to list must create a model
        self.model = QStandardItemModel()
        self.channelList.setModel(self.model)

        self.controlLayout = QHBoxLayout()
        self.controlLayout.setContentsMargins(5, 0, 5, 0)
        self.controlLayout.addWidget(self.playButton)
        self.controlLayout.addWidget(self.lbl)
        self.controlLayout.addWidget(self.positionSlider)
        self.controlLayout.addWidget(self.elbl)

        self.mainLayout = QHBoxLayout()

        # contains video and cotrol widgets to the left side
        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.addWidget(self.videoWidget)
        self.layout.addLayout(self.controlLayout)
        
        # adds channels list to the right
        self.mainLayout.addLayout(self.layout)
        self.mainLayout.addWidget(self.channelList)

        self.setLayout(self.mainLayout)

        self.myinfo = "©2020\nTIVOpy v1.0"

        self.widescreen = True

        #### shortcuts ####
        self.shortcut = QShortcut(QKeySequence("q"), self)
        self.shortcut.activated.connect(self.handleQuit)
        self.shortcut = QShortcut(QKeySequence("u"), self)
        self.shortcut.activated.connect(self.playFromURL)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Space), self)
        self.shortcut.activated.connect(self.play)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_F), self)
        self.shortcut.activated.connect(self.handleFullscreen)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self)
        self.shortcut.activated.connect(self.exitFullscreen)
        self.shortcut.activated.connect(self.handleFullscreen)
        self.shortcut = QShortcut(QKeySequence("i"), self)
        self.shortcut.activated.connect(self.handleInfo)
        self.shortcut = QShortcut(QKeySequence("s"), self)
        self.shortcut.activated.connect(self.toggleSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Right), self)
        self.shortcut.activated.connect(self.forwardSlider)
        self.shortcut = QShortcut(QKeySequence(Qt.Key_Left), self)
        self.shortcut.activated.connect(self.backSlider)

        self.mediaPlayer.setVideoOutput(self.videoWidget)
        self.mediaPlayer.stateChanged.connect(self.mediaStateChanged)
        self.mediaPlayer.positionChanged.connect(self.positionChanged)
        self.mediaPlayer.positionChanged.connect(self.handleLabel)
        self.mediaPlayer.durationChanged.connect(self.durationChanged)
        self.mediaPlayer.error.connect(self.handleError)

        self.populateChannelList()
        self.selectChannel()
        self.initialPlay()

    def playFromURL(self):
        self.mediaPlayer.pause()
        self.myurl = self.clip.text()
        self.mediaPlayer.setMedia(QMediaContent(QUrl(self.myurl)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()
        self.hideSlider()
        print(self.myurl)

    def dataReady(self):
        self.myurl = str(self.process.readAll(), encoding='utf8').rstrip()  ###
        self.myurl = self.myurl.partition("\n")[0]
        print(self.myurl)
        self.clip.setText(self.myurl)
        self.playFromURL()

    def play(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()

    def mediaStateChanged(self, state):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.playButton.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPause))
        else:
            self.playButton.setIcon(
                self.style().standardIcon(QStyle.SP_MediaPlay))

    def positionChanged(self, position):
        self.positionSlider.setValue(position)

    def durationChanged(self, duration):
        self.positionSlider.setRange(0, duration)
        mtime = QTime(0, 0, 0, 0)
        mtime = mtime.addMSecs(self.mediaPlayer.duration())
        self.elbl.setText(mtime.toString())

    def setPosition(self, position):
        self.mediaPlayer.setPosition(position)

    def handleError(self):
        self.playButton.setEnabled(False)
        print("Error: ", self.mediaPlayer.errorString())

    def handleQuit(self):
        self.mediaPlayer.stop()
        print("Goodbye ...")
        app.quit()

    def contextMenuRequested(self, point):
        menu = QMenu()
        actionURL = menu.addAction(QIcon.fromTheme("browser"), "URL from Clipboard (u)")
        menu.addSeparator()
        actionToggle = menu.addAction(QIcon.fromTheme("next"), "Show / Hide Channels (s)")
        actionFull = menu.addAction(QIcon.fromTheme("view-fullscreen"), "Fullscreen (f)")
        menu.addSeparator()
        actionInfo = menu.addAction(QIcon.fromTheme("help-about"), "About (i)")
        menu.addSeparator()
        actionQuit = menu.addAction(QIcon.fromTheme("application-exit"), "Exit (q)")

        actionQuit.triggered.connect(self.handleQuit)
        actionFull.triggered.connect(self.handleFullscreen)
        actionInfo.triggered.connect(self.handleInfo)
        actionToggle.triggered.connect(self.toggleSlider)
        actionURL.triggered.connect(self.playFromURL)
        menu.exec_(self.mapToGlobal(point))

    def wheelEvent(self, event):
        mscale = event.angleDelta().y() / 13
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + mscale)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def mouseDoubleClickEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.handleFullscreen()

    def handleFullscreen(self):
        if self.windowState() and Qt.WindowFullScreen:
            self.showNormal()
        else:
            self.showFullScreen()

    def exitFullscreen(self):
        self.showNormal()

    def handleInfo(self):
        QMessageBox.about(self, "About", self.myinfo)

    def toggleSlider(self):
        if self.positionSlider.isVisible():
            self.hideSlider()
        else:
            self.showSlider()

    def hideSlider(self):
        self.channelList.hide()
        self.playButton.hide()
        self.lbl.hide()
        self.positionSlider.hide()
        self.elbl.hide()

    def showSlider(self):
        self.channelList.show()
        self.playButton.show()
        self.lbl.show()
        self.positionSlider.show()
        self.elbl.show()
        self.channelList.setFocus()

    def forwardSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() + 1000 * 60)

    def backSlider(self):
        self.mediaPlayer.setPosition(self.mediaPlayer.position() - 1000 * 60)

    def volumeUp(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() + 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def volumeDown(self):
        self.mediaPlayer.setVolume(self.mediaPlayer.volume() - 10)
        print("Volume: " + str(self.mediaPlayer.volume()))

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        elif event.mimeData().hasText():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        print("drop")
        if event.mimeData().hasUrls():
            url = event.mimeData().urls()[0].toString()
            print("url = ", url)
            self.mediaPlayer.stop()
            self.mediaPlayer.setMedia(QMediaContent(QUrl(url)))
            self.playButton.setEnabled(True)
            self.mediaPlayer.play()
        elif event.mimeData().hasText():
            mydrop = event.mimeData().text()
            print("generic url = ", mydrop)
            self.mediaPlayer.setMedia(QMediaContent(QUrl(mydrop)))
            self.playButton.setEnabled(True)
            self.mediaPlayer.play()
            self.hideSlider()

    def loadFilm(self, f):
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(f)))
        self.playButton.setEnabled(True)
        self.mediaPlayer.play()

    def populateChannelList(self):
        # file must be in same directory as the script
        FILEPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "canaletv.txt")
        # lines from file with "channel name" -- "link"
        channelArray = []
        # split file by line and adding it to the array
        with open(FILEPATH) as f:
            for line in f:
                channelArray.append(line.rstrip())
        # dictionary with key = channel name and value = link
        self.channelDict = dict(ch.split(" -- ") for ch in channelArray)
        for channel in self.channelDict.keys():
            item = QStandardItem(channel)
            self.model.appendRow(item)

    def selectedItemBehavior(self, index):
    # gets the link for the selected channel and plays it
        itms = self.channelList.selectedIndexes()
        for it in itms:
            channel = it.data()
            link = self.channelDict[channel]
            self.mediaPlayer.setMedia(QMediaContent(QUrl(link)))
            self.play()

    def selectChannel(self):
    # selecting channel from sidebar calls selectedItemBehavior
        self.selModel = self.channelList.selectionModel()
        self.selModel.selectionChanged.connect(self.selectedItemBehavior)

    def initialPlay(self):
    # play somenting when app opens
        self.mediaPlayer.setMedia(QMediaContent(QUrl("https://vid.hls.protv.ro/proxhdn/proxhd_3_34/index.m3u8?1")))
        self.play()

    def handleLabel(self):
        self.lbl.clear()
        mtime = QTime(0, 0, 0, 0)
        self.time = mtime.addMSecs(self.mediaPlayer.position())
        self.lbl.setText(self.time.toString())
コード例 #30
0
class ConfigurationView(QWidget):
    """
    Displays the configuration view.
    """

    def __init__(self, parent=None):
        super(ConfigurationView, self).__init__(parent)
        self._layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.setLayout(self._layout)
        self._editView = EditView(parent)
        # initialize list view
        self._listView = QListView()
        self._configuration_model = self._get_config_model()
        self._listView.setModel(self._configuration_model)
        # initialize detail view
        self._detailView = QWidget()
        self._detailLayout = QBoxLayout(QBoxLayout.TopToBottom)
        self._detailView.setLayout(self._detailLayout)

        self._detailPanels = {}
        self._currentDetailPanel = None
        self._currentConfiguration = None # type: Configuration
        self._config_wide_print_amounts = {}
        self._recalculateEffectivePrintAmounts = False

        # add widgets to layout
        self._layout.addWidget(QLabel("List of Configurations"))
        self._layout.addWidget(self._listView)
        self._layout.addWidget(self._detailView)

        self._create_detail_view()
        # hide detail view on start
        self._detailView.hide()

        # selected configs map
        self._selected_configs = {}
        self._selected_counter = 0

        # add event listener for selection change
        self._listView.clicked.connect(self._on_selection_change)
        self._listView.selectionModel().currentChanged.connect(self._on_selection_change)

    def add_configuration(self, configuration):
        """
        Adds the given configuration to the list view and opens the edit view.
        :param configuration:
        :type configuration: Configuration
        """
        item = create_new_list_item(configuration.get_name())
        self._configuration_model.appendRow(item)
        self._editView.show_for_configuration(configuration)

    def select_first_item(self):
        rect = QRect(0,0,1,1)
        self._listView.setSelection(rect, QItemSelectionModel.Select)

    def update_model(self):
        self._configuration_model = self._get_config_model()
        self._listView.setModel(self._configuration_model)

    @staticmethod
    def _get_config_model():
        data = DataStorage()
        configurations_order = data.get_configurations_order()
        model = QStandardItemModel()

        for name in configurations_order:
            item = create_new_list_item(name)
            model.appendRow(item)

        return model

    def _on_selection_change(self, model_index):
        """
        Called on selecting a new item in the listView.
        :param model_index: index of selected item
        :type model_index: QModelIndex
        """
        data = DataStorage()
        configurations = data.get_configurations()
        selected_item = self._configuration_model.itemFromIndex(model_index) # type: QStandardItem
        current_config_name = selected_item.text()
        current_config = configurations[current_config_name] # type: Configuration
        self._show_detail_view(current_config)
        config_wide_print_amount = self._config_wide_print_amounts[current_config_name]
        material_print_amounts = current_config.get_effective_material_print_amounts(
            config_wide_print_amount,
            self._recalculateEffectivePrintAmounts
        )
        self._recalculateEffectivePrintAmounts = False

        if self._selected_counter == 0:
            MaterialView.reset_check_state_and_print_amount()

        for material in current_config.get_materials():
            item = get_item(MaterialView.get_model().invisibleRootItem(), material.get_name())
            if item is not None:
                print_amount = material_print_amounts[material.get_name()]
                if is_checked(selected_item):
                    check_item(item)
                    if current_config_name not in self._selected_configs:
                        print_amount += int(item.text(1))
                    else:
                        print_amount = int(item.text(1))

                item.setText(1, str(print_amount))

        if is_checked(selected_item) and current_config_name not in self._selected_configs:
            self._selected_configs[current_config_name] = True
            self._selected_counter += 1
        if not is_checked(selected_item) and current_config_name in self._selected_configs:
            self._selected_configs.pop(current_config_name)
            self._selected_counter -= 1

        self._currentConfiguration = current_config

    def _create_detail_view(self):
        """
        Adds the permanent elements to the detail view.
        """
        edit_button = QPushButton("Edit")
        edit_button.clicked.connect(self._show_edit_view)
        self._detailLayout.addWidget(QLabel("Detail view for selected configuration"))
        self._detailLayout.addWidget(edit_button)

    def _change_config_wide_print_amount(self, new_value):
        self._config_wide_print_amounts[self._currentConfiguration.get_name()] = new_value
        self._recalculateEffectivePrintAmounts = True

    def _create_update_function_for_sub_configs(self, sub_config, configuration):
        def update_func(new_value):
            if self._currentConfiguration.get_name() == configuration.get_name():
                self._currentConfiguration.set_config_print_amount(sub_config, new_value)
            self._recalculateEffectivePrintAmounts = True
        return update_func
    
    def _show_edit_view(self):
        """
        Shows the edit view for the selected configuration.
        """
        self._editView.show_for_configuration(self._currentConfiguration)
        selected_indexes = self._listView.selectedIndexes()
        self._on_selection_change(selected_indexes[0])

    def _show_detail_view(self, configuration: Configuration):
        """
        Shows the detail view for the selected configuration.
        :param configuration:
        :type configuration: Configuration
        """
        if self._currentDetailPanel is not None:
            self._currentDetailPanel.hide()
        if configuration.get_name() in self._detailPanels:
            self._currentDetailPanel = self._detailPanels[configuration.get_name()]
            self._currentDetailPanel.show()
        else:
            panel = QWidget()
            layout = QFormLayout()
            panel.setLayout(layout)

            config_wide_counter = QSpinBox()
            config_wide_counter.setMinimum(1)
            config_wide_counter.setValue(1)
            config_wide_counter.valueChanged.connect(self._change_config_wide_print_amount)

            # add panel to parent layout
            self._detailLayout.addWidget(panel)
            # save panel for future use
            self._detailPanels[configuration.get_name()] = panel
            self._currentDetailPanel = panel
            self._config_wide_print_amounts[configuration.get_name()] = 1

            # panel
            layout.addRow("Print this config x times", config_wide_counter)
            layout.addRow("Child configurations", QLabel())
            configurations = configuration.get_configurations()
            config_print_amounts = configuration.get_config_print_amounts()
            for config in configurations: # type: Configuration
                config_counter = QSpinBox()
                config_counter.setMinimum(1)
                config_counter.setValue(config_print_amounts[config.get_name()])
                update_func = self._create_update_function_for_sub_configs(config, configuration)
                config_counter.valueChanged.connect(update_func)
                layout.addRow("Print config " + config.get_name() + " x times", config_counter)

        self._detailView.show()
コード例 #31
0
class comic_export_setting_dialog(QDialog):
    acbfStylesList = [
        "speech", "commentary", "formal", "letter", "code", "heading", "audio",
        "thought", "sign", "sound", "emphasis", "strong"
    ]

    def __init__(self):
        super().__init__()
        self.setLayout(QVBoxLayout())
        self.setWindowTitle(i18n("Export Settings"))
        buttons = QDialogButtonBox(QDialogButtonBox.Ok
                                   | QDialogButtonBox.Cancel)

        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        mainWidget = QTabWidget()
        self.layout().addWidget(mainWidget)
        self.layout().addWidget(buttons)

        # Set basic crop settings
        # Set which layers to remove before export.
        mainExportSettings = QWidget()
        mainExportSettings.setLayout(QVBoxLayout())
        groupExportCrop = QGroupBox(i18n("Crop Settings"))
        formCrop = QFormLayout()
        groupExportCrop.setLayout(formCrop)
        self.chk_toOutmostGuides = QCheckBox(i18n("Crop to outmost guides"))
        self.chk_toOutmostGuides.setChecked(True)
        self.chk_toOutmostGuides.setToolTip(
            i18n(
                "This will crop to the outmost guides if possible and otherwise use the underlying crop settings."
            ))
        formCrop.addRow("", self.chk_toOutmostGuides)
        btn_fromSelection = QPushButton(
            i18n("Set Margins from Active Selection"))
        btn_fromSelection.clicked.connect(self.slot_set_margin_from_selection)
        # This doesn't work.
        formCrop.addRow("", btn_fromSelection)
        self.spn_marginLeft = QSpinBox()
        self.spn_marginLeft.setMaximum(99999)
        self.spn_marginLeft.setSuffix(" px")
        formCrop.addRow(i18n("Left:"), self.spn_marginLeft)
        self.spn_marginTop = QSpinBox()
        self.spn_marginTop.setMaximum(99999)
        self.spn_marginTop.setSuffix(" px")
        formCrop.addRow(i18n("Top:"), self.spn_marginTop)
        self.spn_marginRight = QSpinBox()
        self.spn_marginRight.setMaximum(99999)
        self.spn_marginRight.setSuffix(" px")
        formCrop.addRow(i18n("Right:"), self.spn_marginRight)
        self.spn_marginBottom = QSpinBox()
        self.spn_marginBottom.setMaximum(99999)
        self.spn_marginBottom.setSuffix(" px")
        formCrop.addRow(i18n("Bottom:"), self.spn_marginBottom)
        groupExportLayers = QGroupBox(i18n("Layers"))
        formLayers = QFormLayout()
        groupExportLayers.setLayout(formLayers)
        self.cmbLabelsRemove = labelSelector()
        formLayers.addRow(i18n("Label for removal:"), self.cmbLabelsRemove)
        self.ln_text_layer_name = QLineEdit()
        self.ln_text_layer_name.setToolTip(
            i18n(
                "These are keywords that can be used to identify text layers. A layer only needs to contain the keyword to be recognized. Keywords should be comma separated."
            ))
        self.ln_panel_layer_name = QLineEdit()
        self.ln_panel_layer_name.setToolTip(
            i18n(
                "These are keywords that can be used to identify panel layers. A layer only needs to contain the keyword to be recognized. Keywords should be comma separated."
            ))
        formLayers.addRow(i18n("Text Layer Key:"), self.ln_text_layer_name)
        formLayers.addRow(i18n("Panel Layer Key:"), self.ln_panel_layer_name)

        mainExportSettings.layout().addWidget(groupExportCrop)
        mainExportSettings.layout().addWidget(groupExportLayers)
        mainWidget.addTab(mainExportSettings, i18n("General"))

        # CBZ, crop, resize, which metadata to add.
        CBZexportSettings = QWidget()
        CBZexportSettings.setLayout(QVBoxLayout())
        self.CBZactive = QCheckBox(i18n("Export to CBZ"))
        CBZexportSettings.layout().addWidget(self.CBZactive)
        self.CBZgroupResize = comic_export_resize_widget("CBZ")
        CBZexportSettings.layout().addWidget(self.CBZgroupResize)
        self.CBZactive.clicked.connect(self.CBZgroupResize.setEnabled)
        CBZgroupMeta = QGroupBox(i18n("Metadata to Add"))
        # CBZexportSettings.layout().addWidget(CBZgroupMeta)
        CBZgroupMeta.setLayout(QFormLayout())

        mainWidget.addTab(CBZexportSettings, i18n("CBZ"))

        # ACBF, crop, resize, creator name, version history, panel layer, text layers.
        ACBFExportSettings = QWidget()
        ACBFform = QFormLayout()
        ACBFExportSettings.setLayout(QVBoxLayout())
        ACBFdocInfo = QGroupBox()
        ACBFdocInfo.setTitle(i18n("ACBF Document Info"))
        ACBFdocInfo.setLayout(ACBFform)
        self.lnACBFID = QLabel()
        self.lnACBFID.setToolTip(
            i18n(
                "By default this will be filled with a generated universal unique identifier. The ID by itself is merely so that comic book library management programs can figure out if this particular comic is already in their database and whether it has been rated. Of course, the UUID can be changed into something else by manually changing the JSON, but this is advanced usage."
            ))
        self.spnACBFVersion = QSpinBox()
        self.ACBFhistoryModel = QStandardItemModel()
        acbfHistoryList = QListView()
        acbfHistoryList.setModel(self.ACBFhistoryModel)
        btn_add_history = QPushButton(i18n("Add History Entry"))
        btn_add_history.clicked.connect(self.slot_add_history_item)
        self.chkIncludeTranslatorComments = QCheckBox()
        self.chkIncludeTranslatorComments.setText(
            i18n("Include translator's comments"))
        self.chkIncludeTranslatorComments.setToolTip(
            i18n(
                "A PO file can contain translator's comments. If this is checked, the translations comments will be added as references into the ACBF file."
            ))
        self.lnTranslatorHeader = QLineEdit()

        ACBFform.addRow(i18n("ACBF UID:"), self.lnACBFID)
        ACBFform.addRow(i18n("Version:"), self.spnACBFVersion)
        ACBFform.addRow(i18n("Version history:"), acbfHistoryList)
        ACBFform.addRow("", btn_add_history)
        ACBFform.addRow("", self.chkIncludeTranslatorComments)
        ACBFform.addRow(i18n("Translator header:"), self.lnTranslatorHeader)

        ACBFAuthorInfo = QWidget()
        acbfAVbox = QVBoxLayout(ACBFAuthorInfo)
        infoLabel = QLabel(
            i18n(
                "The people responsible for the generation of the CBZ/ACBF files."
            ))
        infoLabel.setWordWrap(True)
        ACBFAuthorInfo.layout().addWidget(infoLabel)
        self.ACBFauthorModel = QStandardItemModel(0, 6)
        labels = [
            i18n("Nick Name"),
            i18n("Given Name"),
            i18n("Middle Name"),
            i18n("Family Name"),
            i18n("Email"),
            i18n("Homepage")
        ]
        self.ACBFauthorModel.setHorizontalHeaderLabels(labels)
        self.ACBFauthorTable = QTableView()
        acbfAVbox.addWidget(self.ACBFauthorTable)
        self.ACBFauthorTable.setModel(self.ACBFauthorModel)
        self.ACBFauthorTable.verticalHeader().setDragEnabled(True)
        self.ACBFauthorTable.verticalHeader().setDropIndicatorShown(True)
        self.ACBFauthorTable.verticalHeader().setSectionsMovable(True)
        self.ACBFauthorTable.verticalHeader().sectionMoved.connect(
            self.slot_reset_author_row_visual)
        AuthorButtons = QHBoxLayout()
        btn_add_author = QPushButton(i18n("Add Author"))
        btn_add_author.clicked.connect(self.slot_add_author)
        AuthorButtons.addWidget(btn_add_author)
        btn_remove_author = QPushButton(i18n("Remove Author"))
        btn_remove_author.clicked.connect(self.slot_remove_author)
        AuthorButtons.addWidget(btn_remove_author)
        acbfAVbox.addLayout(AuthorButtons)

        ACBFStyle = QWidget()
        ACBFStyle.setLayout(QHBoxLayout())
        self.ACBFStylesModel = QStandardItemModel()
        self.ACBFStyleClass = QListView()
        self.ACBFStyleClass.setModel(self.ACBFStylesModel)
        ACBFStyle.layout().addWidget(self.ACBFStyleClass)
        ACBFStyleEdit = QWidget()
        ACBFStyleEditVB = QVBoxLayout(ACBFStyleEdit)
        self.ACBFuseFont = QCheckBox(i18n("Use font"))
        self.ACBFFontList = QListView()
        self.ACBFFontList.setItemDelegate(font_list_delegate())
        self.ACBFuseFont.toggled.connect(self.font_slot_enable_font_view)
        self.ACBFFontListModel = QStandardItemModel()
        self.ACBFFontListModel.rowsRemoved.connect(
            self.slot_font_current_style)
        self.ACBFFontListModel.itemChanged.connect(
            self.slot_font_current_style)
        self.btnAcbfAddFont = QPushButton()
        self.btnAcbfAddFont.setIcon(Application.icon("list-add"))
        self.btnAcbfAddFont.clicked.connect(self.font_slot_add_font)
        self.btn_acbf_remove_font = QPushButton()
        self.btn_acbf_remove_font.setIcon(Application.icon("edit-delete"))
        self.btn_acbf_remove_font.clicked.connect(self.font_slot_remove_font)
        self.ACBFFontList.setModel(self.ACBFFontListModel)
        self.ACBFdefaultFont = QComboBox()
        self.ACBFdefaultFont.addItems(
            ["sans-serif", "serif", "monospace", "cursive", "fantasy"])
        acbfFontButtons = QHBoxLayout()
        acbfFontButtons.addWidget(self.btnAcbfAddFont)
        acbfFontButtons.addWidget(self.btn_acbf_remove_font)
        self.ACBFBold = QCheckBox(i18n("Bold"))
        self.ACBFItal = QCheckBox(i18n("Italic"))
        self.ACBFStyleClass.clicked.connect(self.slot_set_style)
        self.ACBFStyleClass.selectionModel().selectionChanged.connect(
            self.slot_set_style)
        self.ACBFStylesModel.itemChanged.connect(self.slot_set_style)
        self.ACBFBold.toggled.connect(self.slot_font_current_style)
        self.ACBFItal.toggled.connect(self.slot_font_current_style)
        colorWidget = QGroupBox(self)
        colorWidget.setTitle(i18n("Text Colors"))
        colorWidget.setLayout(QVBoxLayout())
        self.regularColor = QColorDialog()
        self.invertedColor = QColorDialog()
        self.btn_acbfRegColor = QPushButton(i18n("Regular Text"), self)
        self.btn_acbfRegColor.clicked.connect(self.slot_change_regular_color)
        self.btn_acbfInvColor = QPushButton(i18n("Inverted Text"), self)
        self.btn_acbfInvColor.clicked.connect(self.slot_change_inverted_color)
        colorWidget.layout().addWidget(self.btn_acbfRegColor)
        colorWidget.layout().addWidget(self.btn_acbfInvColor)
        ACBFStyleEditVB.addWidget(colorWidget)
        ACBFStyleEditVB.addWidget(self.ACBFuseFont)
        ACBFStyleEditVB.addWidget(self.ACBFFontList)
        ACBFStyleEditVB.addLayout(acbfFontButtons)
        ACBFStyleEditVB.addWidget(self.ACBFdefaultFont)
        ACBFStyleEditVB.addWidget(self.ACBFBold)
        ACBFStyleEditVB.addWidget(self.ACBFItal)
        ACBFStyleEditVB.addStretch()
        ACBFStyle.layout().addWidget(ACBFStyleEdit)

        ACBFTabwidget = QTabWidget()
        ACBFTabwidget.addTab(ACBFdocInfo, i18n("Document Info"))
        ACBFTabwidget.addTab(ACBFAuthorInfo, i18n("Author Info"))
        ACBFTabwidget.addTab(ACBFStyle, i18n("Style Sheet"))
        ACBFExportSettings.layout().addWidget(ACBFTabwidget)
        mainWidget.addTab(ACBFExportSettings, i18n("ACBF"))

        # Epub export, crop, resize, other questions.
        EPUBexportSettings = QWidget()
        EPUBexportSettings.setLayout(QVBoxLayout())
        self.EPUBactive = QCheckBox(i18n("Export to EPUB"))
        EPUBexportSettings.layout().addWidget(self.EPUBactive)
        self.EPUBgroupResize = comic_export_resize_widget("EPUB")
        EPUBexportSettings.layout().addWidget(self.EPUBgroupResize)
        self.EPUBactive.clicked.connect(self.EPUBgroupResize.setEnabled)
        mainWidget.addTab(EPUBexportSettings, i18n("EPUB"))

        # For Print. Crop, no resize.
        TIFFExportSettings = QWidget()
        TIFFExportSettings.setLayout(QVBoxLayout())
        self.TIFFactive = QCheckBox(i18n("Export to TIFF"))
        TIFFExportSettings.layout().addWidget(self.TIFFactive)
        self.TIFFgroupResize = comic_export_resize_widget("TIFF")
        TIFFExportSettings.layout().addWidget(self.TIFFgroupResize)
        self.TIFFactive.clicked.connect(self.TIFFgroupResize.setEnabled)
        mainWidget.addTab(TIFFExportSettings, i18n("TIFF"))

        # SVG, crop, resize, embed vs link.
        #SVGExportSettings = QWidget()

        #mainWidget.addTab(SVGExportSettings, i18n("SVG"))

    """
    Add a history item to the acbf version history list.
    """

    def slot_add_history_item(self):
        newItem = QStandardItem()
        newItem.setText(
            str(i18n("v{version}-in this version...")).format(
                version=str(self.spnACBFVersion.value())))
        self.ACBFhistoryModel.appendRow(newItem)

    """
    Get the margins by treating the active selection in a document as the trim area.
    This allows people to snap selections to a vector or something, and then get the margins.
    """

    def slot_set_margin_from_selection(self):
        doc = Application.activeDocument()
        if doc is not None:
            if doc.selection() is not None:
                self.spn_marginLeft.setValue(doc.selection().x())
                self.spn_marginTop.setValue(doc.selection().y())
                self.spn_marginRight.setValue(doc.width() -
                                              (doc.selection().x() +
                                               doc.selection().width()))
                self.spn_marginBottom.setValue(doc.height() -
                                               (doc.selection().y() +
                                                doc.selection().height()))

    """
    Add an author with default values initialised.
    """

    def slot_add_author(self):
        listItems = []
        listItems.append(QStandardItem(i18n("Anon")))  # Nick name
        listItems.append(QStandardItem(i18n("John")))  # First name
        listItems.append(QStandardItem())  # Middle name
        listItems.append(QStandardItem(i18n("Doe")))  # Last name
        listItems.append(QStandardItem())  # email
        listItems.append(QStandardItem())  # homepage
        self.ACBFauthorModel.appendRow(listItems)

    """
    Remove the selected author from the author list.
    """

    def slot_remove_author(self):
        self.ACBFauthorModel.removeRow(
            self.ACBFauthorTable.currentIndex().row())

    """
    Ensure that the drag and drop of authors doesn't mess up the labels.
    """

    def slot_reset_author_row_visual(self):
        headerLabelList = []
        for i in range(self.ACBFauthorTable.verticalHeader().count()):
            headerLabelList.append(str(i))
        for i in range(self.ACBFauthorTable.verticalHeader().count()):
            logicalI = self.ACBFauthorTable.verticalHeader().logicalIndex(i)
            headerLabelList[logicalI] = str(i + 1)
        self.ACBFauthorModel.setVerticalHeaderLabels(headerLabelList)

    """
    Set the style item to the gui item's style.
    """

    def slot_set_style(self):
        index = self.ACBFStyleClass.currentIndex()
        if index.isValid():
            item = self.ACBFStylesModel.item(index.row())
            fontUsed = item.data(role=styleEnum.FONT)
            if fontUsed is not None:
                self.ACBFuseFont.setChecked(fontUsed)
            else:
                self.ACBFuseFont.setChecked(False)
            self.font_slot_enable_font_view()
            fontList = item.data(role=styleEnum.FONTLIST)
            self.ACBFFontListModel.clear()
            for font in fontList:
                NewItem = QStandardItem(font)
                NewItem.setEditable(True)
                self.ACBFFontListModel.appendRow(NewItem)
            self.ACBFdefaultFont.setCurrentText(
                str(item.data(role=styleEnum.FONTGENERIC)))
            bold = item.data(role=styleEnum.BOLD)
            if bold is not None:
                self.ACBFBold.setChecked(bold)
            else:
                self.ACBFBold.setChecked(False)
            italic = item.data(role=styleEnum.ITALIC)
            if italic is not None:
                self.ACBFItal.setChecked(italic)
            else:
                self.ACBFItal.setChecked(False)

    """
    Set the gui items to the currently selected style.
    """

    def slot_font_current_style(self):
        index = self.ACBFStyleClass.currentIndex()
        if index.isValid():
            item = self.ACBFStylesModel.item(index.row())
            fontList = []
            for row in range(self.ACBFFontListModel.rowCount()):
                font = self.ACBFFontListModel.item(row)
                fontList.append(font.text())
            item.setData(self.ACBFuseFont.isChecked(), role=styleEnum.FONT)
            item.setData(fontList, role=styleEnum.FONTLIST)
            item.setData(self.ACBFdefaultFont.currentText(),
                         role=styleEnum.FONTGENERIC)
            item.setData(self.ACBFBold.isChecked(), role=styleEnum.BOLD)
            item.setData(self.ACBFItal.isChecked(), role=styleEnum.ITALIC)
            self.ACBFStylesModel.setItem(index.row(), item)

    """
    Change the regular color
    """

    def slot_change_regular_color(self):
        if (self.regularColor.exec_() == QDialog.Accepted):
            square = QPixmap(32, 32)
            square.fill(self.regularColor.currentColor())
            self.btn_acbfRegColor.setIcon(QIcon(square))

    """
    change the inverted color
    """

    def slot_change_inverted_color(self):
        if (self.invertedColor.exec_() == QDialog.Accepted):
            square = QPixmap(32, 32)
            square.fill(self.invertedColor.currentColor())
            self.btn_acbfInvColor.setIcon(QIcon(square))

    def font_slot_enable_font_view(self):
        self.ACBFFontList.setEnabled(self.ACBFuseFont.isChecked())
        self.btn_acbf_remove_font.setEnabled(self.ACBFuseFont.isChecked())
        self.btnAcbfAddFont.setEnabled(self.ACBFuseFont.isChecked())
        self.ACBFdefaultFont.setEnabled(self.ACBFuseFont.isChecked())
        if self.ACBFFontListModel.rowCount() < 2:
            self.btn_acbf_remove_font.setEnabled(False)

    def font_slot_add_font(self):
        NewItem = QStandardItem(QFont().family())
        NewItem.setEditable(True)
        self.ACBFFontListModel.appendRow(NewItem)

    def font_slot_remove_font(self):
        index = self.ACBFFontList.currentIndex()
        if index.isValid():
            self.ACBFFontListModel.removeRow(index.row())
            if self.ACBFFontListModel.rowCount() < 2:
                self.btn_acbf_remove_font.setEnabled(False)

    """
    Load the UI values from the config dictionary given.
    """

    def setConfig(self, config):
        if "cropToGuides" in config.keys():
            self.chk_toOutmostGuides.setChecked(config["cropToGuides"])
        if "cropLeft" in config.keys():
            self.spn_marginLeft.setValue(config["cropLeft"])
        if "cropTop" in config.keys():
            self.spn_marginTop.setValue(config["cropTop"])
        if "cropRight" in config.keys():
            self.spn_marginRight.setValue(config["cropRight"])
        if "cropBottom" in config.keys():
            self.spn_marginBottom.setValue(config["cropBottom"])
        if "labelsToRemove" in config.keys():
            self.cmbLabelsRemove.setLabels(config["labelsToRemove"])
        if "textLayerNames" in config.keys():
            self.ln_text_layer_name.setText(", ".join(
                config["textLayerNames"]))
        else:
            self.ln_text_layer_name.setText("text")
        if "panelLayerNames" in config.keys():
            self.ln_panel_layer_name.setText(", ".join(
                config["panelLayerNames"]))
        else:
            self.ln_panel_layer_name.setText("panels")
        self.CBZgroupResize.set_config(config)
        if "CBZactive" in config.keys():
            self.CBZactive.setChecked(config["CBZactive"])
        self.EPUBgroupResize.set_config(config)
        if "EPUBactive" in config.keys():
            self.EPUBactive.setChecked(config["EPUBactive"])
        self.TIFFgroupResize.set_config(config)
        if "TIFFactive" in config.keys():
            self.TIFFactive.setChecked(config["TIFFactive"])

        if "acbfAuthor" in config.keys():
            if isinstance(config["acbfAuthor"], list):
                for author in config["acbfAuthor"]:
                    listItems = []
                    listItems.append(QStandardItem(author.get("nickname", "")))
                    listItems.append(
                        QStandardItem(author.get("first-name", "")))
                    listItems.append(QStandardItem(author.get("initials", "")))
                    listItems.append(QStandardItem(author.get("last-name",
                                                              "")))
                    listItems.append(QStandardItem(author.get("email", "")))
                    listItems.append(QStandardItem(author.get("homepage", "")))
                    self.ACBFauthorModel.appendRow(listItems)
                pass
            else:
                listItems = []
                listItems.append(QStandardItem(
                    config["acbfAuthor"]))  # Nick name
                for i in range(0, 5):
                    listItems.append(QStandardItem())  # First name
                self.ACBFauthorModel.appendRow(listItems)

        if "uuid" in config.keys():
            self.lnACBFID.setText(config["uuid"])
        elif "acbfID" in config.keys():
            self.lnACBFID.setText(config["acbfID"])
        else:
            config["uuid"] = QUuid.createUuid().toString()
            self.lnACBFID.setText(config["uuid"])
        if "acbfVersion" in config.keys():
            self.spnACBFVersion.setValue(config["acbfVersion"])
        if "acbfHistory" in config.keys():
            for h in config["acbfHistory"]:
                item = QStandardItem()
                item.setText(h)
                self.ACBFhistoryModel.appendRow(item)
        if "acbfStyles" in config.keys():
            styleDict = config.get("acbfStyles", {})
            for key in self.acbfStylesList:
                keyDict = styleDict.get(key, {})
                style = QStandardItem(key.title())
                style.setCheckable(True)
                if key in styleDict.keys():
                    style.setCheckState(Qt.Checked)
                else:
                    style.setCheckState(Qt.Unchecked)
                fontOn = False
                if "font" in keyDict.keys() or "genericfont" in keyDict.keys():
                    fontOn = True
                style.setData(fontOn, role=styleEnum.FONT)
                if "font" in keyDict:
                    fontlist = keyDict["font"]
                    if isinstance(fontlist, list):
                        font = keyDict.get("font", QFont().family())
                        style.setData(font, role=styleEnum.FONTLIST)
                    else:
                        style.setData([fontlist], role=styleEnum.FONTLIST)
                else:
                    style.setData([QFont().family()], role=styleEnum.FONTLIST)
                style.setData(keyDict.get("genericfont", "sans-serif"),
                              role=styleEnum.FONTGENERIC)
                style.setData(keyDict.get("bold", False), role=styleEnum.BOLD)
                style.setData(keyDict.get("ital", False),
                              role=styleEnum.ITALIC)
                self.ACBFStylesModel.appendRow(style)
            keyDict = styleDict.get("general", {})
            self.regularColor.setCurrentColor(
                QColor(keyDict.get("color", "#000000")))
            square = QPixmap(32, 32)
            square.fill(self.regularColor.currentColor())
            self.btn_acbfRegColor.setIcon(QIcon(square))
            keyDict = styleDict.get("inverted", {})
            self.invertedColor.setCurrentColor(
                QColor(keyDict.get("color", "#FFFFFF")))
            square.fill(self.invertedColor.currentColor())
            self.btn_acbfInvColor.setIcon(QIcon(square))
        else:
            for key in self.acbfStylesList:
                style = QStandardItem(key.title())
                style.setCheckable(True)
                style.setCheckState(Qt.Unchecked)
                style.setData(False, role=styleEnum.FONT)
                style.setData(QFont().family(), role=styleEnum.FONTLIST)
                style.setData("sans-serif", role=styleEnum.FONTGENERIC)
                style.setData(False, role=styleEnum.BOLD)  #Bold
                style.setData(False, role=styleEnum.ITALIC)  #Italic
                self.ACBFStylesModel.appendRow(style)
        self.CBZgroupResize.setEnabled(self.CBZactive.isChecked())
        self.lnTranslatorHeader.setText(
            config.get("translatorHeader", "Translator's Notes"))
        self.chkIncludeTranslatorComments.setChecked(
            config.get("includeTranslComment", False))

    """
    Store the GUI values into the config dictionary given.
    
    @return the config diactionary filled with new values.
    """

    def getConfig(self, config):

        config["cropToGuides"] = self.chk_toOutmostGuides.isChecked()
        config["cropLeft"] = self.spn_marginLeft.value()
        config["cropTop"] = self.spn_marginTop.value()
        config["cropBottom"] = self.spn_marginRight.value()
        config["cropRight"] = self.spn_marginBottom.value()
        config["labelsToRemove"] = self.cmbLabelsRemove.getLabels()
        config["CBZactive"] = self.CBZactive.isChecked()
        config = self.CBZgroupResize.get_config(config)
        config["EPUBactive"] = self.EPUBactive.isChecked()
        config = self.EPUBgroupResize.get_config(config)
        config["TIFFactive"] = self.TIFFactive.isChecked()
        config = self.TIFFgroupResize.get_config(config)
        authorList = []
        for row in range(self.ACBFauthorTable.verticalHeader().count()):
            logicalIndex = self.ACBFauthorTable.verticalHeader().logicalIndex(
                row)
            listEntries = [
                "nickname", "first-name", "initials", "last-name", "email",
                "homepage"
            ]
            author = {}
            for i in range(len(listEntries)):
                entry = self.ACBFauthorModel.data(
                    self.ACBFauthorModel.index(logicalIndex, i))
                if entry is None:
                    entry = " "
                if entry.isspace() is False and len(entry) > 0:
                    author[listEntries[i]] = entry
                elif listEntries[i] in author.keys():
                    author.pop(listEntries[i])
            authorList.append(author)
        config["acbfAuthor"] = authorList
        config["acbfVersion"] = self.spnACBFVersion.value()
        versionList = []
        for r in range(self.ACBFhistoryModel.rowCount()):
            index = self.ACBFhistoryModel.index(r, 0)
            versionList.append(
                self.ACBFhistoryModel.data(index, Qt.DisplayRole))
        config["acbfHistory"] = versionList

        acbfStylesDict = {}
        for row in range(0, self.ACBFStylesModel.rowCount()):
            entry = self.ACBFStylesModel.item(row)
            if entry.checkState() == Qt.Checked:
                key = entry.text().lower()
                style = {}
                if entry.data(role=styleEnum.FONT):
                    font = entry.data(role=styleEnum.FONTLIST)
                    if font is not None:
                        style["font"] = font
                    genericfont = entry.data(role=styleEnum.FONTGENERIC)
                    if font is not None:
                        style["genericfont"] = genericfont
                bold = entry.data(role=styleEnum.BOLD)
                if bold is not None:
                    style["bold"] = bold
                italic = entry.data(role=styleEnum.ITALIC)
                if italic is not None:
                    style["ital"] = italic
                acbfStylesDict[key] = style
        acbfStylesDict["general"] = {
            "color": self.regularColor.currentColor().name()
        }
        acbfStylesDict["inverted"] = {
            "color": self.invertedColor.currentColor().name()
        }
        config["acbfStyles"] = acbfStylesDict
        config["translatorHeader"] = self.lnTranslatorHeader.text()
        config[
            "includeTranslComment"] = self.chkIncludeTranslatorComments.isChecked(
            )

        # Turn this into something that retrieves from a line-edit when string freeze is over.
        config["textLayerNames"] = self.ln_text_layer_name.text().split(",")
        config["panelLayerNames"] = self.ln_panel_layer_name.text().split(",")
        return config
コード例 #32
0
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'PyQt5 file system view - pythonspot.com'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.default_path = (os.path.join(os.path.expanduser('~'),
                                          'labvcnc/nc_files/examples'))
        self.user_path = (os.path.join('/media'))
        self.currentPath = None
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.setNameFilters(["*.ngc", '*.py'])

        self.list = QListView()
        self.list.setModel(self.model)
        self.updateDirectoryView(self.default_path)
        self.list.setWindowTitle("Dir View")
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.clicked)
        self.list.activated.connect(self.load)
        self.list.setAlternatingRowColors(True)

        self.cb = QComboBox()
        self.cb.currentTextChanged.connect(self.filterChanged)
        self.cb.addItems(sorted({'*.ngc', '*.py', '*'}))
        #self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.button = QPushButton()
        self.button.setText('Media')
        self.button.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button.setToolTip('Jump to Media directory')
        self.button.clicked.connect(self.onMediaClicked)

        self.button2 = QPushButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setToolTip('Jump to labvcnc directory')
        self.button2.clicked.connect(self.onUserClicked)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button)
        hbox.addWidget(self.button2)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.list)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    def updateDirectoryView(self, path):
        self.list.setRootIndex(self.model.setRootPath(path))

    def filterChanged(self, text):
        self.model.setNameFilters([text])

    def clicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)

    def onMediaClicked(self):
        self.updateDirectoryView(self.user_path)

    def onUserClicked(self):
        self.updateDirectoryView(self.default_path)

    def select_row(self, style):
        style = style.lower()
        selectionModel = self.list.selectionModel()
        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(self.list.rootIndex())

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows:
                row += 1
            else:
                row = self.rows
        else:
            return
        top = self.model.index(row, 0, self.list.rootIndex())
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_file_path',
                                            self.default_path, str,
                                            'BOOK_KEEPING')
            self.updateDirectoryView(last_path)
            LOG.debug("lAST FILE PATH: {}".format(last_path))
        else:
            LOG.debug("lAST FILE PATH: {}".format(self.default_path))
            self.updateDirectoryView(self.default_path)

    # get current selection and update the path
    # then if the path is good load it into labvcnc
    # record it in the preference file if available
    def load(self):
        row = self.list.selectionModel().currentIndex()
        self.clicked(row)

        fname = self.currentPath
        if fname is None:
            return
        if fname:
            if self.PREFS_:
                self.PREFS_.putpref('last_file_path', fname, str,
                                    'BOOK_KEEPING')
            ACTION.OPEN_PROGRAM(fname)
            STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')

    def up(self):
        self.select_row('up')

    def down(self):
        self.select_row('down')