Exemplo n.º 1
0
class CustomQCompleter(QCompleter):
    def __init__(self, *args):
        super(CustomQCompleter, self).__init__(*args)
        self.local_completion_prefix = ""
        self.source_model = None
        self.filterProxyModel = QSortFilterProxyModel(self)
        self.usingOriginalModel = False

    def setModel(self, model):
        self.source_model = model
        self.filterProxyModel = QSortFilterProxyModel(self)
        self.filterProxyModel.setSourceModel(self.source_model)
        super(CustomQCompleter, self).setModel(self.filterProxyModel)
        self.usingOriginalModel = True

    def updateModel(self):
        if not self.usingOriginalModel:
            self.filterProxyModel.setSourceModel(self.source_model)

        pattern = QRegExp(self.local_completion_prefix, Qt.CaseInsensitive,
                          QRegExp.FixedString)

        self.filterProxyModel.setFilterRegExp(pattern)

    def splitPath(self, path):
        self.local_completion_prefix = path
        self.updateModel()
        if self.filterProxyModel.rowCount() == 0:
            self.usingOriginalModel = False
            self.filterProxyModel.setSourceModel(QStringListModel([path]))
            return [path]

        return []
Exemplo n.º 2
0
class JoinChannelDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.app = QApplication.instance()
        self.chans = ChatChannels()
        self.ui = ui_chatchannelslist.Ui_ChannelsListDialog()
        self.ui.setupUi(self)
        self.ui.joinButton.clicked.connect(self.onJoinClicked)
        self.ui.cancelButton.clicked.connect(functools.partial(self.done, 1))

        self.channelsModel = QStandardItemModel()
        self.channelsModel.setHorizontalHeaderLabels(['Channel', 'Connected'])
        self.channelsProxyModel = QSortFilterProxyModel(self)
        self.channelsProxyModel.setSourceModel(self.channelsModel)
        self.channelsProxyModel.setFilterKeyColumn(0)
        self.channelsProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.ui.channelsView.setModel(self.channelsProxyModel)
        self.ui.channelsView.doubleClicked.connect(
            lambda idx: self.onJoinClicked())
        self.ui.channelsView.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.ui.searchLine.textChanged.connect(self.onApplySearch)

    @ipfsOp
    async def initDialog(self, ipfsop):
        dagChannels = ipfsop.ctx.currentProfile.dagChatChannels
        for channel in dagChannels.channels:
            self.channelsModel.appendRow([
                UneditableItem(channel),
                UneditableItem(str(await self.chans.cnCountByChannel(channel)))
            ])
            await ipfsop.sleep()

    def onApplySearch(self):
        self.channelsProxyModel.setFilterRegExp(self.ui.searchLine.text())

    def onJoinClicked(self):
        try:
            idx = self.ui.channelsView.selectionModel().selectedRows(0).pop()
        except Exception:
            return

        chan = self.channelsProxyModel.data(idx, Qt.DisplayRole)
        if chan:
            ensure(self.onJoinChannel(chan))

        self.done(1)

    @ipfsOp
    async def onJoinChannel(self, ipfsop, channel):
        log.info(f'Joining channel: {channel}')

        widget = await self.chans.joinChannel(channel)
        self.app.mainWindow.registerTab(widget,
                                        name=channel,
                                        icon=getIcon('chat.png'),
                                        current=True,
                                        workspace=WS_PEERS)
Exemplo n.º 3
0
    def txt_dictFind_textChange(self, text):
        if len(text) == 0:
            self.tbl_dictList.setModel(self.dict_list_model)
            return

        filter_model = QSortFilterProxyModel()
        filter_model.setSourceModel(self.dict_list_model)
        filter_model.setFilterKeyColumn(0)

        regex = "^{}".format(text)
        filter_model.setFilterRegExp(
            QtCore.QRegExp(regex, QtCore.Qt.CaseInsensitive))

        self.tbl_dictList.setModel(filter_model)
        pass
Exemplo n.º 4
0
def filterOnFocus(window, focused):
	loclist = getattr(window, 'build_loclist', None)
	if not loclist:
		return

	model = loclist.model()
	if not getattr(model, 'isFilterOnFocus', False):
		orig = model

		model = QSortFilterProxyModel()
		model.isFilterOnFocus = True
		loclist.setModel(model)
		model.setSourceModel(orig)
		model.setFilterRole(AbsolutePathRole)

	model.setFilterRegExp(QRegExp.escape(focused.path or ''))
Exemplo n.º 5
0
def filterOnFocus(window, focused):
    loclist = getattr(window, 'build_loclist', None)
    if not loclist:
        return

    model = loclist.model()
    if not getattr(model, 'isFilterOnFocus', False):
        orig = model

        model = QSortFilterProxyModel()
        model.isFilterOnFocus = True
        loclist.setModel(model)
        model.setSourceModel(orig)
        model.setFilterRole(AbsolutePathRole)

    model.setFilterRegExp(QRegExp.escape(focused.path or ''))
Exemplo n.º 6
0
class PostSelectionWidget(QDialog):
    def __init__(self, app, parent=None):
        super(PostSelectionWidget, self).__init__(parent=parent)
        self.app = app
        self.model = PostsListModel(app)
        self.filtermodel = QSortFilterProxyModel()
        self.filtermodel.setSourceModel(self.model)
        self.resize(450, 250)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        view = QListView(self)
        self.completer = QCompleter(parent=self)
        self.completer.setCompletionMode(QCompleter.InlineCompletion)
        self.completer.setCompletionColumn(0)
        self.completer.setCompletionRole(Qt.DisplayRole)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setModel(self.model)
        self._edit = QLineEdit('')
        self._edit.setCompleter(self.completer)
        self._edit.textEdited.connect(self.setfilter)
        self.layout.addWidget(self._edit)
        self.layout.addWidget(view)
        view.setModel(self.filtermodel)
        view.clicked.connect(self.select)
        view.doubleClicked.connect(self.select_and_edit)
        self._button = QPushButton('Edit')
        self._button.clicked.connect(self.edit)
        self.layout.addWidget(self._button)

    def setfilter(self, text):
        regexp = QRegExp("%s*" % text, Qt.CaseInsensitive, QRegExp.Wildcard)
        self.filtermodel.setFilterRegExp(regexp)

    def select(self, index):
        text = self.filtermodel.data(index)
        self._edit.setText(text)

    def select_and_edit(self, index):
        text = self.filtermodel.data(index)
        self._edit.setText(text)
        self.app.edit_post(text)

    def edit(self):
        self.app.edit_post(self._edit.text())
Exemplo n.º 7
0
class JoinChannelDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.app = QApplication.instance()
        self.chans = ChatChannels()
        self.ui = ui_chatchannelslist.Ui_ChannelsListDialog()
        self.ui.setupUi(self)
        self.ui.joinButton.clicked.connect(self.onJoinClicked)
        self.ui.cancelButton.clicked.connect(functools.partial(self.done, 1))

        self.channelsModel = UneditableStringListModel(self)
        self.channelsProxyModel = QSortFilterProxyModel(self)
        self.channelsProxyModel.setSourceModel(self.channelsModel)
        self.ui.channelsView.setModel(self.channelsProxyModel)
        self.ui.channelsView.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.ui.searchLine.textChanged.connect(self.onApplySearch)

    @ipfsOp
    async def initDialog(self, ipfsop):
        dagChannels = ipfsop.ctx.currentProfile.dagChatChannels
        self.channelsModel.setStringList(dagChannels.channels)

    def onApplySearch(self):
        self.channelsProxyModel.setFilterRegExp(self.ui.searchLine.text())

    def onJoinClicked(self):
        idx = self.ui.channelsView.currentIndex()
        chan = self.channelsProxyModel.data(idx, Qt.DisplayRole)
        if chan:
            ensure(self.onJoinChannel(chan))

        self.done(1)

    @ipfsOp
    async def onJoinChannel(self, ipfsop, channel):
        log.info(f'Joining channel: {channel}')

        widget = await self.chans.joinChannel(channel)
        self.app.mainWindow.registerTab(widget,
                                        name=channel,
                                        icon=getIcon('qta:mdi.chat-outline'),
                                        current=True)
class Window(QWidget):
    def __init__(self):
        super().__init__()

        # Make widgets #################

        self.edit = QLineEdit()
        self.table_view = QTableView()

        self.edit.setPlaceholderText("Filter text (on col. 1)")

        # Set the layout ############################

        vbox = QVBoxLayout()

        vbox.addWidget(self.edit)
        vbox.addWidget(self.table_view)

        self.setLayout(vbox)

        # Set Model and ProxyModel ##################

        my_model = MyModel(None)

        self.proxy_model = QSortFilterProxyModel()  # <--
        self.proxy_model.setSourceModel(my_model)  # <--
        self.table_view.setModel(self.proxy_model)  # <--
        #self.table_view.setModel(my_model)

        #self.proxy_model.setFilterRegExp(QRegExp("1", Qt.CaseInsensitive, QRegExp.FixedString))     # <--
        self.proxy_model.setFilterKeyColumn(0)  # <--
        #self.table_view.setSortingEnabled(True)

        # Set LineEdit slot #########################

        self.edit.textChanged.connect(self.foo)

    def foo(self):
        filter_str = self.edit.text()
        self.proxy_model.setFilterRegExp(
            QRegExp(filter_str, Qt.CaseInsensitive,
                    QRegExp.FixedString))  # <--
class CustomQCompleter(QCompleter):
    """
    adapted from: http://stackoverflow.com/a/7767999/2156909
    """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.local_completion_prefix = ""
        self.source_model = None
        self.filterProxyModel = QSortFilterProxyModel(self)
        self.usingOriginalModel = False

    def setModel(self, strList): 
        self.source_model = QStringListModel(strList)
        self.filterProxyModel = QSortFilterProxyModel(self)
        self.filterProxyModel.setSourceModel(self.source_model)
        super().setModel(self.filterProxyModel)
        self.usingOriginalModel = True


    def updateModel(self):
        if not self.usingOriginalModel:
            self.filterProxyModel.setSourceModel(self.source_model)

        pattern = QRegExp(self.local_completion_prefix,
                                Qt.CaseInsensitive,
                                QRegExp.FixedString)

        self.filterProxyModel.setFilterRegExp(pattern)

    def splitPath(self, path):
        self.local_completion_prefix = path
        self.updateModel()
        if self.filterProxyModel.rowCount() == 0:
            self.usingOriginalModel = False
            self.filterProxyModel.setSourceModel(QStringListModel([path]))
            return [path]

        self.usingOriginalModel = True
        return []
Exemplo n.º 10
0
def run_gui():

    # Get some mutations
    #mutations = generate_mutation_sequence(50)

    reader = ABNAMROReader()
    path = r"C:\Users\z428172\Documents\financien\2019\transacties\TXT190210094911.TAB"
    mutations = reader.read(path)

    app = QApplication(sys.argv)
    window = MainAnotatorWindow()

    model = MutationsTableModel(mutations)
    proxy = QSortFilterProxyModel()
    proxy.setSourceModel(model)
    #proxy.sortByColumn(MutationsTableModel.column_numbers['description'], Qt.AscendingOrder)
    regExp = QRegExp("", Qt.CaseInsensitive, QRegExp.RegExp)
    proxy.setFilterRegExp(regExp)

    window.mutationsListView.setModel(proxy)
    window.show()
    sys.exit(app.exec_())
Exemplo n.º 11
0
class reportUI(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.index = 0
        self.selectActiveOnly = False

        self.model = None

        self.reportChooser = QComboBox()
        self.reportChooser.addItems(["Active Folios", "All Folios"])
        self.reportChooser.currentTextChanged.connect(self.filterChanged)

        self.reportTableView = QTableView()
        self.reportTableView.setSortingEnabled(True)

        layout = QVBoxLayout()
        layout.addWidget(self.reportChooser)
        layout.addWidget(self.reportTableView)

        groupbox = QGroupBox("Account Summary")
        groupbox.setLayout(layout)

        boxLayout = QVBoxLayout(self)
        boxLayout.addWidget(groupbox)

    def setModel(self, model):
        self.model = model
        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setSourceModel(self.model)
        self.reportTableView.setModel(self.proxyModel)
        self.filterChanged(self.reportChooser.currentText())

    @pyqtSlot(str)
    def filterChanged(self, filter):
        if filter == "Active Folios":
            self.proxyModel.setFilterRegExp("^[1-9].*")
            self.proxyModel.setFilterKeyColumn(9)
        else:
            self.proxyModel.setFilterRegExp("")
Exemplo n.º 12
0
class CustomQCompleter(QCompleter):
    """
    adapted from: http://stackoverflow.com/a/7767999/2156909
    """
    def __init__(self, parent=None):
        super().__init__(parent)
        self.local_completion_prefix = ""
        self.source_model = None
        self.filterProxyModel = QSortFilterProxyModel(self)
        self.usingOriginalModel = False

    def setModel(self, strList):
        self.source_model = QStringListModel(strList)
        self.filterProxyModel = QSortFilterProxyModel(self)
        self.filterProxyModel.setSourceModel(self.source_model)
        super().setModel(self.filterProxyModel)
        self.usingOriginalModel = True

    def updateModel(self):
        if not self.usingOriginalModel:
            self.filterProxyModel.setSourceModel(self.source_model)

        pattern = QRegExp(self.local_completion_prefix, Qt.CaseInsensitive,
                          QRegExp.FixedString)

        self.filterProxyModel.setFilterRegExp(pattern)

    def splitPath(self, path):
        self.local_completion_prefix = path
        self.updateModel()
        if self.filterProxyModel.rowCount() == 0:
            self.usingOriginalModel = False
            self.filterProxyModel.setSourceModel(QStringListModel([path]))
            return [path]

        self.usingOriginalModel = True
        return []
class CreateDialogCodeDialog(QDialog, Ui_CreateDialogCodeDialog):
    """
    Class implementing a dialog to generate code for a Qt4/Qt5 dialog.
    """
    DialogClasses = {
        "QDialog", "QWidget", "QMainWindow", "QWizard", "QWizardPage",
        "QDockWidget", "QFrame", "QGroupBox", "QScrollArea", "QMdiArea",
        "QTabWidget", "QToolBox", "QStackedWidget"
    }
    Separator = 25 * "="

    def __init__(self, formName, project, parent=None):
        """
        Constructor
        
        @param formName name of the file containing the form (string)
        @param project reference to the project object
        @param parent parent widget if the dialog (QWidget)
        """
        super(CreateDialogCodeDialog, self).__init__(parent)
        self.setupUi(self)

        self.okButton = self.buttonBox.button(QDialogButtonBox.Ok)

        self.slotsView.header().hide()

        self.project = project

        self.formFile = formName
        filename, ext = os.path.splitext(self.formFile)
        self.srcFile = '{0}{1}'.format(
            filename, self.project.getDefaultSourceExtension())

        self.slotsModel = QStandardItemModel()
        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setDynamicSortFilter(True)
        self.proxyModel.setSourceModel(self.slotsModel)
        self.slotsView.setModel(self.proxyModel)

        # initialize some member variables
        self.__initError = False
        self.__module = None

        if os.path.exists(self.srcFile):
            vm = e5App().getObject("ViewManager")
            ed = vm.getOpenEditor(self.srcFile)
            if ed and not vm.checkDirty(ed):
                self.__initError = True
                return

            try:
                splitExt = os.path.splitext(self.srcFile)
                if len(splitExt) == 2:
                    exts = [splitExt[1]]
                else:
                    exts = None
                from Utilities import ModuleParser
                self.__module = ModuleParser.readModule(self.srcFile,
                                                        extensions=exts,
                                                        caching=False)
            except ImportError:
                pass

        if self.__module is not None:
            self.filenameEdit.setText(self.srcFile)

            classesList = []
            vagueClassesList = []
            for cls in list(self.__module.classes.values()):
                if not set(cls.super).isdisjoint(
                        CreateDialogCodeDialog.DialogClasses):
                    classesList.append(cls.name)
                else:
                    vagueClassesList.append(cls.name)
            classesList.sort()
            self.classNameCombo.addItems(classesList)
            if vagueClassesList:
                if classesList:
                    self.classNameCombo.addItem(
                        CreateDialogCodeDialog.Separator)
                self.classNameCombo.addItems(sorted(vagueClassesList))

        if os.path.exists(self.srcFile) and \
           self.__module is not None and \
           self.classNameCombo.count() == 0:
            self.__initError = True
            E5MessageBox.critical(
                self, self.tr("Create Dialog Code"),
                self.tr("""The file <b>{0}</b> exists but does not contain"""
                        """ any classes.""").format(self.srcFile))

        self.okButton.setEnabled(self.classNameCombo.count() > 0)

        self.__updateSlotsModel()

    def initError(self):
        """
        Public method to determine, if there was an initialzation error.
        
        @return flag indicating an initialzation error (boolean)
        """
        return self.__initError

    def __objectName(self):
        """
        Private method to get the object name of the dialog.
        
        @return object name (string)
        """
        try:
            dlg = uic.loadUi(self.formFile,
                             package=self.project.getProjectPath())
            return dlg.objectName()
        except (AttributeError, ImportError,
                xml.etree.ElementTree.ParseError) as err:
            E5MessageBox.critical(
                self, self.tr("uic error"),
                self.tr("""<p>There was an error loading the form <b>{0}</b>"""
                        """.</p><p>{1}</p>""").format(self.formFile, str(err)))
            return ""

    def __className(self):
        """
        Private method to get the class name of the dialog.
        
        @return class name (sting)
        """
        try:
            dlg = uic.loadUi(self.formFile,
                             package=self.project.getProjectPath())
            return dlg.metaObject().className()
        except (AttributeError, ImportError,
                xml.etree.ElementTree.ParseError) as err:
            E5MessageBox.critical(
                self, self.tr("uic error"),
                self.tr("""<p>There was an error loading the form <b>{0}</b>"""
                        """.</p><p>{1}</p>""").format(self.formFile, str(err)))
            return ""

    def __signatures(self):
        """
        Private slot to get the signatures.
        
        @return list of signatures (list of strings)
        """
        if self.__module is None:
            return []

        signatures = []
        clsName = self.classNameCombo.currentText()
        if clsName:
            cls = self.__module.classes[clsName]
            for meth in list(cls.methods.values()):
                if meth.name.startswith("on_"):
                    if meth.pyqtSignature is not None:
                        sig = ", ".join([
                            bytes(QMetaObject.normalizedType(t)).decode()
                            for t in meth.pyqtSignature.split(",")
                        ])
                        signatures.append("{0}({1})".format(meth.name, sig))
                    else:
                        signatures.append(meth.name)
        return signatures

    def __mapType(self, type_):
        """
        Private method to map a type as reported by Qt's meta object to the
        correct Python type.
        
        @param type_ type as reported by Qt (QByteArray)
        @return mapped Python type (string)
        """
        mapped = bytes(type_).decode()

        if self.project.getProjectLanguage() != "Python2" or \
           self.project.getProjectType == "PySide":
            # 1. check for const
            mapped = mapped.replace("const ", "")

            # 2. check fpr *
            mapped = mapped.replace("*", "")

            # 3. replace QString and QStringList
            mapped = mapped.replace("QStringList", "list")\
                           .replace("QString", "str")

            # 4. replace double by float
            mapped = mapped.replace("double", "float")

        return mapped

    def __updateSlotsModel(self):
        """
        Private slot to update the slots tree display.
        """
        self.filterEdit.clear()

        try:
            dlg = uic.loadUi(self.formFile,
                             package=self.project.getProjectPath())
            objects = dlg.findChildren(QWidget) + dlg.findChildren(QAction)

            signatureList = self.__signatures()

            self.slotsModel.clear()
            self.slotsModel.setHorizontalHeaderLabels([""])
            for obj in objects:
                name = obj.objectName()
                if not name or name.startswith("qt_"):
                    # ignore un-named or internal objects
                    continue

                metaObject = obj.metaObject()
                className = metaObject.className()
                itm = QStandardItem("{0} ({1})".format(name, className))
                self.slotsModel.appendRow(itm)
                for index in range(metaObject.methodCount()):
                    metaMethod = metaObject.method(index)
                    if metaMethod.methodType() == QMetaMethod.Signal:
                        if qVersion() >= "5.0.0":
                            itm2 = QStandardItem("on_{0}_{1}".format(
                                name,
                                bytes(metaMethod.methodSignature()).decode()))
                        else:
                            itm2 = QStandardItem("on_{0}_{1}".format(
                                name, metaMethod.signature()))
                        itm.appendRow(itm2)
                        if self.__module is not None:
                            if qVersion() >= "5.0.0":
                                method = "on_{0}_{1}".format(
                                    name,
                                    bytes(metaMethod.methodSignature()).decode(
                                    ).split("(")[0])
                            else:
                                method = "on_{0}_{1}".format(
                                    name,
                                    metaMethod.signature().split("(")[0])
                            method2 = "{0}({1})".format(
                                method, ", ".join([
                                    self.__mapType(t)
                                    for t in metaMethod.parameterTypes()
                                ]))

                            if method2 in signatureList or \
                                    method in signatureList:
                                itm2.setFlags(Qt.ItemFlags(Qt.ItemIsEnabled))
                                itm2.setCheckState(Qt.Checked)
                                itm2.setForeground(QBrush(Qt.blue))
                                continue

                        pyqtSignature = \
                            ", ".join([self.__mapType(t)
                                       for t in metaMethod.parameterTypes()])

                        parameterNames = metaMethod.parameterNames()
                        if parameterNames:
                            for index in range(len(parameterNames)):
                                if not parameterNames[index]:
                                    parameterNames[index] = \
                                        QByteArray("p{0:d}".format(index)
                                                   .encode("utf-8"))
                        methNamesSig = \
                            ", ".join(
                                [bytes(n).decode() for n in parameterNames])

                        if methNamesSig:
                            if qVersion() >= "5.0.0":
                                pythonSignature = \
                                    "on_{0}_{1}(self, {2})".format(
                                        name,
                                        bytes(metaMethod.methodSignature())
                                        .decode().split("(")[0],
                                        methNamesSig)
                            else:
                                pythonSignature = \
                                    "on_{0}_{1}(self, {2})".format(
                                        name,
                                        metaMethod.signature().split("(")[0],
                                        methNamesSig)
                        else:
                            if qVersion() >= "5.0.0":
                                pythonSignature = "on_{0}_{1}(self)".format(
                                    name,
                                    bytes(metaMethod.methodSignature()).decode(
                                    ).split("(")[0])
                            else:
                                pythonSignature = "on_{0}_{1}(self)".format(
                                    name,
                                    metaMethod.signature().split("(")[0])
                        itm2.setData(pyqtSignature, pyqtSignatureRole)
                        itm2.setData(pythonSignature, pythonSignatureRole)

                        itm2.setFlags(
                            Qt.ItemFlags(Qt.ItemIsUserCheckable
                                         | Qt.ItemIsEnabled
                                         | Qt.ItemIsSelectable))
                        itm2.setCheckState(Qt.Unchecked)

            self.slotsView.sortByColumn(0, Qt.AscendingOrder)
        except (AttributeError, ImportError,
                xml.etree.ElementTree.ParseError) as err:
            E5MessageBox.critical(
                self, self.tr("uic error"),
                self.tr("""<p>There was an error loading the form <b>{0}</b>"""
                        """.</p><p>{1}</p>""").format(self.formFile, str(err)))

    def __generateCode(self):
        """
        Private slot to generate the code as requested by the user.
        """
        # first decide on extension
        if self.filenameEdit.text().endswith(".py") or \
           self.filenameEdit.text().endswith(".pyw"):
            self.__generatePythonCode()
        elif self.filenameEdit.text().endswith(".rb"):
            pass
        # second decide on project language
        elif self.project.getProjectLanguage() in ["Python2", "Python3"]:
            self.__generatePythonCode()
        elif self.project.getProjectLanguage() == "Ruby":
            pass
        else:
            # assume Python (our global default)
            self.__generatePythonCode()

    def __generatePythonCode(self):
        """
        Private slot to generate Python code as requested by the user.
        """
        # init some variables
        sourceImpl = []
        appendAtIndex = -1
        indentStr = "    "
        slotsCode = []

        if self.__module is None:
            # new file
            try:
                if self.project.getProjectLanguage() == "Python2":
                    if self.project.getProjectType() == "PySide":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyside.py2.tmpl")
                    elif self.project.getProjectType() == "PyQt5":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt5.py2.tmpl")
                    else:
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt.py2.tmpl")
                else:
                    if self.project.getProjectType() == "PySide":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyside.py.tmpl")
                    elif self.project.getProjectType() in [
                            "PyQt5", "E6Plugin"
                    ]:
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt5.py.tmpl")
                    else:
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt.py.tmpl")
                tmplFile = open(tmplName, 'r', encoding="utf-8")
                template = tmplFile.read()
                tmplFile.close()
            except IOError as why:
                E5MessageBox.critical(
                    self, self.tr("Code Generation"),
                    self.tr("""<p>Could not open the code template file"""
                            """ "{0}".</p><p>Reason: {1}</p>""").format(
                                tmplName, str(why)))
                return

            objName = self.__objectName()
            if objName:
                template = template\
                    .replace(
                        "$FORMFILE$",
                        os.path.splitext(os.path.basename(self.formFile))[0])\
                    .replace("$FORMCLASS$", objName)\
                    .replace("$CLASSNAME$", self.classNameCombo.currentText())\
                    .replace("$SUPERCLASS$", self.__className())

                sourceImpl = template.splitlines(True)
                appendAtIndex = -1

                # determine indent string
                for line in sourceImpl:
                    if line.lstrip().startswith("def __init__"):
                        indentStr = line.replace(line.lstrip(), "")
                        break
        else:
            # extend existing file
            try:
                srcFile = open(self.srcFile, 'r', encoding="utf-8")
                sourceImpl = srcFile.readlines()
                srcFile.close()
                if not sourceImpl[-1].endswith("\n"):
                    sourceImpl[-1] = "{0}{1}".format(sourceImpl[-1], "\n")
            except IOError as why:
                E5MessageBox.critical(
                    self, self.tr("Code Generation"),
                    self.tr("""<p>Could not open the source file "{0}".</p>"""
                            """<p>Reason: {1}</p>""").format(
                                self.srcFile, str(why)))
                return

            cls = self.__module.classes[self.classNameCombo.currentText()]
            if cls.endlineno == len(sourceImpl) or cls.endlineno == -1:
                appendAtIndex = -1
                # delete empty lines at end
                while not sourceImpl[-1].strip():
                    del sourceImpl[-1]
            else:
                appendAtIndex = cls.endlineno - 1
                while not sourceImpl[appendAtIndex].strip():
                    appendAtIndex -= 1
                appendAtIndex += 1

            # determine indent string
            for line in sourceImpl[cls.lineno:cls.endlineno + 1]:
                if line.lstrip().startswith("def __init__"):
                    indentStr = line.replace(line.lstrip(), "")
                    break

        # do the coding stuff
        if self.project.getProjectLanguage() == "Python2":
            if self.project.getProjectType() == "PySide":
                pyqtSignatureFormat = '@Slot({0})'
            elif self.project.getProjectType() == "PyQt5":
                pyqtSignatureFormat = '@pyqtSlot({0})'
            else:
                pyqtSignatureFormat = '@pyqtSignature("{0}")'
        else:
            if self.project.getProjectType() == "PySide":
                pyqtSignatureFormat = '@Slot({0})'
            else:
                pyqtSignatureFormat = '@pyqtSlot({0})'
        for row in range(self.slotsModel.rowCount()):
            topItem = self.slotsModel.item(row)
            for childRow in range(topItem.rowCount()):
                child = topItem.child(childRow)
                if child.checkState() and \
                   child.flags() & Qt.ItemFlags(Qt.ItemIsUserCheckable):
                    slotsCode.append('{0}\n'.format(indentStr))
                    slotsCode.append('{0}{1}\n'.format(
                        indentStr,
                        pyqtSignatureFormat.format(
                            child.data(pyqtSignatureRole))))
                    slotsCode.append('{0}def {1}:\n'.format(
                        indentStr, child.data(pythonSignatureRole)))
                    slotsCode.append('{0}"""\n'.format(indentStr * 2))
                    slotsCode.append(
                        '{0}Slot documentation goes here.\n'.format(indentStr *
                                                                    2))
                    slotsCode.append('{0}"""\n'.format(indentStr * 2))
                    slotsCode.append('{0}# {1}: not implemented yet\n'.format(
                        indentStr * 2, "TODO"))
                    slotsCode.append('{0}raise NotImplementedError\n'.format(
                        indentStr * 2))

        if appendAtIndex == -1:
            sourceImpl.extend(slotsCode)
        else:
            sourceImpl[appendAtIndex:appendAtIndex] = slotsCode

        # write the new code
        try:
            if self.project.useSystemEol():
                newline = None
            else:
                newline = self.project.getEolString()
            srcFile = open(self.filenameEdit.text(),
                           'w',
                           encoding="utf-8",
                           newline=newline)
            srcFile.write("".join(sourceImpl))
            srcFile.close()
        except IOError as why:
            E5MessageBox.critical(
                self, self.tr("Code Generation"),
                self.tr("""<p>Could not write the source file "{0}".</p>"""
                        """<p>Reason: {1}</p>""").format(
                            self.filenameEdit.text(), str(why)))
            return

        self.project.appendFile(self.filenameEdit.text())

    @pyqtSlot(int)
    def on_classNameCombo_activated(self, index):
        """
        Private slot to handle the activated signal of the classname combo.
        
        @param index index of the activated item (integer)
        """
        if (self.classNameCombo.currentText() ==
                CreateDialogCodeDialog.Separator):
            self.okButton.setEnabled(False)
            self.filterEdit.clear()
            self.slotsModel.clear()
            self.slotsModel.setHorizontalHeaderLabels([""])
        else:
            self.okButton.setEnabled(True)
            self.__updateSlotsModel()

    def on_filterEdit_textChanged(self, text):
        """
        Private slot called, when thext of the filter edit has changed.
        
        @param text changed text (string)
        """
        re = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp2)
        self.proxyModel.setFilterRegExp(re)

    @pyqtSlot()
    def on_newButton_clicked(self):
        """
        Private slot called to enter the data for a new dialog class.
        """
        path, file = os.path.split(self.srcFile)
        objName = self.__objectName()
        if objName:
            dlg = NewDialogClassDialog(objName, file, path, self)
            if dlg.exec_() == QDialog.Accepted:
                className, fileName = dlg.getData()

                self.classNameCombo.clear()
                self.classNameCombo.addItem(className)
                self.srcFile = fileName
                self.filenameEdit.setText(self.srcFile)
                self.__module = None

            self.okButton.setEnabled(self.classNameCombo.count() > 0)

    def on_buttonBox_clicked(self, button):
        """
        Private slot to handle the buttonBox clicked signal.
        
        @param button reference to the button that was clicked
            (QAbstractButton)
        """
        if button == self.okButton:
            self.__generateCode()
            self.accept()
Exemplo n.º 14
0
class HistoryManagerWidget(QWidget):

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

        self.listHistory = []
        self.nam = QtNetwork.QNetworkAccessManager()

        self.setting = QSettings()

        self.searchLineEdit = QLineEdit()
        self.tableView = QTableView()
        self.columnComboBox = QComboBox()
        self.searchLabel = QLabel()
        self.searchLabel.setText("Filter")

        self.model = QStandardItemModel(self)

        searchHbox = QHBoxLayout()
        searchHbox.addWidget(self.searchLabel)
        searchHbox.addWidget(self.searchLineEdit)
        searchHbox.addWidget(self.columnComboBox)

        self.header = "Order ID;Order Status;Card ID;Menu ID;Menu Name;Price;Qty;" \
                 "Item Status;Table Number;Order Time;Modified Time".split(";")
        self.model.setHorizontalHeaderLabels(self.header)
        self.tableView.horizontalHeader().setStretchLastSection(True)

        hboxLayout = QHBoxLayout()
        self.backButton = QPushButton()
        self.backButton.setText("Back")

        self.refreshButton = QPushButton()
        self.refreshButton.setText("Refresh")
        self.refreshButton.clicked.connect(self.refresh)

        self.saveCSVButton = QPushButton()
        self.saveCSVButton.setText("Save as CSV")
        self.saveCSVButton.clicked.connect(self.saveCSV)

        hboxLayout.addWidget(self.backButton)
        hboxLayout.addWidget(self.refreshButton)
        hboxLayout.addWidget(self.saveCSVButton)

        widgetTitleLabel = QLabel()
        widgetTitleLabel.setAlignment(Qt.AlignCenter)
        widgetTitleLabel.setText("History Manager")

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(widgetTitleLabel)
        mainLayout.addLayout(searchHbox)
        mainLayout.addWidget(self.tableView)
        mainLayout.addLayout(hboxLayout)

        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.model)

        self.tableView.setModel(self.proxy)
        self.columnComboBox.addItems(self.header)

        self.searchLineEdit.textChanged.connect(self.on_lineEdit_textChanged)
        self.columnComboBox.currentIndexChanged.connect(self.on_comboBox_currentIndexChanged)

        self.horizontalHeader = self.tableView.horizontalHeader()

        self.setLayout(mainLayout)

    def saveCSV(self):
        data = ""
        rows = self.model.rowCount()
        columns = self.model.columnCount()

        if rows>0:
            for title in self.header:
                data += title
                data += ","
            data += "\n"
            for i in range(rows):
                for j in range(columns):
                    index = self.model.index(i,j)
                    # print(str(self.model.data(index)))
                    data += str(self.model.data(index))
                    data += ","
                data += "\n"

            name, _ = QFileDialog.getSaveFileName(self, 'Save File', "History SELFO.csv", "csv(*.csv)")
            if name:
                file = open(name, 'w')
                file.write(data)
                file.close()
        else:
            QMessageBox.critical(self, "Error", "No Data")

    def clear(self):
        self.listHistory.clear()
        self.model.clear()
        self.model.setHorizontalHeaderLabels(self.header)

    def refresh(self):
        self.clear()
        self.doRequestOrderDetail()

    def populateList(self):
        for rowName in range(len(self.listHistory)):
            self.model.invisibleRootItem().appendRow(
                [QStandardItem("{}".format(self.listHistory[rowName][column]))
                 for column in range(len(self.header))
                 ]
            )
        self.tableView.resizeColumnsToContents()

    def closeHistoryManager(self):
        self.mainWindow.stackedWidget.removeWidget(self)

    def doRequestOrderDetail(self):
        url = self.setting.value("baseURL", "")
        url += "/orderdetail/?sellerID=" + str(self.setting.value("sellerID", "")) \
               # + "&itemStatus=" + "placed"
        req = QtNetwork.QNetworkRequest(QUrl(url))

        reply = self.nam.get(req)
        reply.finished.connect(self.handleResponseOrderDetail)

    def handleResponseOrderDetail(self):
        reply = self.sender()

        er = reply.error()

        if er == QtNetwork.QNetworkReply.NoError:

            bytes_string = reply.readAll()
            data = json.loads(str(bytes_string, 'utf-8'))
            # print(data)

            for history in data:
                # id = history['id']
                orderID = history['orderID']
                orderStatus = history['orderStatus']
                cardID = history['cardID']
                # sellerID = history['sellerID']
                menuID = history['menuID']
                menuName = history['menuName']
                itemStatus = history['itemStatus']
                price = formatRupiah(history['price'])
                qty = history['qty']
                tableNumber = history['tableNumber']
                rawOrderTime = history['orderTime']
                orderTime = datetime.datetime.strptime(
                    rawOrderTime, "%Y-%m-%dT%H:%M:%S.%f+07:00").strftime("%d %b %Y %H:%M:%S")
                rawModifiedTime = history['modifiedTime']
                if rawModifiedTime is not None:
                    modifiedTime = datetime.datetime.strptime(
                        rawModifiedTime, "%Y-%m-%dT%H:%M:%S.%f+07:00").strftime("%d %b %Y %H:%M:%S")
                else:
                    modifiedTime = "null"
                historyItem = [orderID, orderStatus, cardID, menuID, menuName, price, qty, itemStatus, tableNumber, orderTime, modifiedTime]
                self.listHistory.append(historyItem)

            self.populateList()

        else:
            errorMessage = "Error occured: " + str(er) + "\n" + str(reply.errorString())
            QMessageBox.critical(self, "Error Order Detail", errorMessage)
        reply.deleteLater()

    def on_view_horizontalHeader_sectionClicked(self, logicalIndex):
        self.logicalIndex   = logicalIndex
        self.menuValues     = QMenu(self)
        self.signalMapper   = QSignalMapper(self)

        self.columnComboBox.blockSignals(True)
        self.columnComboBox.setCurrentIndex(self.logicalIndex)
        self.columnComboBox.blockSignals(True)

        valuesUnique = [    self.model.item(row, self.logicalIndex).text()
                            for row in range(self.model.rowCount())
                            ]

        actionAll = QAction("All", self)
        actionAll.triggered.connect(self.on_actionAll_triggered)
        self.menuValues.addAction(actionAll)
        self.menuValues.addSeparator()

        for actionNumber, actionName in enumerate(sorted(list(set(valuesUnique)))):
            action = QAction(actionName, self)
            self.signalMapper.setMapping(action, actionNumber)
            action.triggered.connect(self.signalMapper.map)
            self.menuValues.addAction(action)

        self.signalMapper.mapped.connect(self.on_signalMapper_mapped)

        headerPos = self.tableView.mapToGlobal(self.horizontalHeader.pos())

        posY = headerPos.y() + self.horizontalHeader.height()
        posX = headerPos.x() + self.horizontalHeader.sectionPosition(self.logicalIndex)

        self.menuValues.exec_(QPoint(posX, posY))

    def on_actionAll_triggered(self):
        filterColumn = self.logicalIndex
        filterString = QRegExp(  "",
                                        Qt.CaseInsensitive,
                                        QRegExp.RegExp
                                        )

        self.proxy.setFilterRegExp(filterString)
        self.proxy.setFilterKeyColumn(filterColumn)

    def on_signalMapper_mapped(self, i):
        stringAction = self.signalMapper.mapping(i).text()
        filterColumn = self.logicalIndex
        filterString = QRegExp(  stringAction,
                                        Qt.CaseSensitive,
                                        QRegExp.FixedString
                                        )

        self.proxy.setFilterRegExp(filterString)
        self.proxy.setFilterKeyColumn(filterColumn)

    def on_lineEdit_textChanged(self, text):
        search = QRegExp(    text,
                                    Qt.CaseInsensitive,
                                    QRegExp.RegExp
                                    )

        self.proxy.setFilterRegExp(search)

    def on_comboBox_currentIndexChanged(self, index):
        self.proxy.setFilterKeyColumn(index)
Exemplo n.º 15
0
class NormaOdk(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.skrot = QShortcut(QKeySequence(Qt.Key_Return), self)
        self.naglowki = {
            'iddetale': 'ID',
            'nr_detalu': 'Detal',
            'maszyna': 'Maszyna',
            "ilosc_m": 'Ilość maszyn',
            'ilosc_szt': 'Ilość sztuk na operację',
            'nazwa_op': 'Nazwa operacji',
            'nr_op': 'Nr operacji',
            'tm': 'Czas Tm [s]',
            'tp': 'Czas Tp [s]',
            'tj': 'Czas Tj [h]',
            'norma': 'Norma [szt.]',
            'uwagi': 'Uwagi',
            'id_uzytkownika': 'Użytkownik'
        }
        self.proxy = QSortFilterProxyModel(self)
        self.parent = parent
        self.formularz = QGroupBox("Normy")
        self.lbl_w = QLabel("Wyszukaj")
        self.edit_w = QLineEdit(self)
        self.table = QTableView(self)
        self.btn_odswiez = QPushButton("Odśwież bazę")
        sciezka = czy_istnieje()
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(sciezka)
        if self.db.open():
            print('Otworzono bazę danych')
        self.model = QSqlRelationalTableModel(self, self.db)
        self.initUI()

    def initUI(self):
        # Zainicjowanie tabeli zawsze przed wszystkim
        self.tabela()

        # lista wybieralna
        with open('./resources/Maszyny i operacje.json', 'r',
                  encoding='utf-8') as file:
            plik_json = json.load(file)
        masz = plik_json['Maszyny']
        operacje = plik_json['Operacje']
        self.table.setItemDelegateForColumn(2, ComboDelegate(self, masz))
        self.table.setItemDelegateForColumn(6, ComboDelegate(self, operacje))
        for row in range(0, self.model.rowCount()):
            self.table.openPersistentEditor(self.model.index(row, 2))
            self.table.openPersistentEditor(self.model.index(row, 6))

        # Zatwierdzenie
        ok_button = QPushButton("Dodaj")
        cancel_button = QPushButton("Cofnij")
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(self.btn_odswiez)
        hbox.addWidget(ok_button)
        hbox.addWidget(cancel_button)

        # Layouty
        layout_v = QVBoxLayout()
        layout_h = QHBoxLayout()

        # Tabela
        self.proxy.setSourceModel(self.model)
        self.table.setModel(self.proxy)

        # przyporządkowanie
        layout_h.addWidget(self.lbl_w)
        layout_h.addWidget(self.edit_w)
        layout_v.addLayout(layout_h)
        layout_v.addWidget(self.table)
        self.formularz.setLayout(layout_v)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.formularz)
        main_layout.addLayout(hbox)
        self.setLayout(main_layout)

        # export
        # self.export()
        # Funkcje
        cancel_button.clicked.connect(self.anulowanie)
        ok_button.clicked.connect(self.dodaj)
        self.edit_w.textChanged.connect(self.wyszukiwanie)
        self.btn_odswiez.clicked.connect(self.refresh_db)
        self.skrot.activated.connect(self.refresh_db)
        # Menu kontekstowe własne
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.prawoklik)

    def prawoklik(self):
        menu = QMenu(self)
        if self.model.rowCount():
            akcja = QAction('Usuń wiersz', self)
            akcja.triggered.connect(self.usun_wiersz)
            menu.addAction(akcja)
            menu.exec_(QCursor.pos())

    def usun_wiersz(self):
        ok = QMessageBox.question(self, 'Potwierdzenie',
                                  'Czy na pewno chcesz usunąć pozycję?',
                                  QMessageBox.Ok, QMessageBox.Cancel)
        if ok == QMessageBox.Ok:
            selected = self.table.currentIndex()
            self.model.removeRow(selected.row())
            self.model.submitAll()
            self.model.select()

    @pyqtSlot(str)
    def wyszukiwanie(self, text):
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy.setFilterKeyColumn(-1)

    @pyqtSlot()
    def uzupelniene(self):
        # Pobranie tp, tm z bazy
        query = 'SELECT iddetale, tm, tp, ilosc_m, ilosc_szt FROM detale'
        dane_db = multipolaczenie(query)
        for i in range(len(dane_db)):
            # if dane_db[i][1] and dane_db[i][2]:
            tm = dane_db[i][1]
            tp1 = dane_db[i][2]
            ilosc_m = dane_db[i][3]
            ilosc_szt = dane_db[i][4]
            if not ilosc_m:
                ilosc_m = 1
                zm = 1
            else:
                zm = 0.95
            if not ilosc_szt:
                ilosc_szt = 1
            if isinstance(tm, int) and isinstance(tp1, int):
                tw = tm + tp1
            else:
                tw = 0
            tp2 = tw * 0.05
            tj = (tw + tp2) * 1.1
            tjh = tj / 3600

            if tj != 0:
                norma = 8 / tj * 3600 * ilosc_m * zm * ilosc_szt
            else:
                norma = 0
            print(round(norma))
            # update bazy
            query = 'UPDATE "detale" SET "tj" = ' + str(round(
                tjh, 5)) + ', "norma" = ' + str(
                    round(norma)) + ' WHERE "iddetale" = ' + str(dane_db[i][0])
            update_bazy(query)
            # query = 'UPDATE "detale" SET "norma" = ' + str(round(norma)) +
            # ' WHERE "iddetale" = ' + str(dane_db[i][0]) update_bazy(query)

    @pyqtSlot()
    def refresh_db(self):
        try:
            self.uzupelniene()
        except:
            pass
        # Odświeżenie tabeli
        self.model.select()

    def tabela(self):
        self.model.setTable('detale')
        self.model.setRelation(
            12, QSqlRelation('uzytkownicy', 'iduzytkownicy', 'nazwa_uz'))
        # Za zmianę w bazie odpowiada OnFieldChange
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)

        # Ustawianie nagłówków
        ilosc_kolumn = self.model.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model.headerData(i, Qt.Horizontal)
            self.model.setHeaderData(i, Qt.Horizontal,
                                     self.naglowki[nazwa_kolumn])
        self.model.select()

        # Odpowiada za edycję pojednynczym kliknieciem
        '''
        Constant    Value   Description
        QAbstractItemView::NoEditTriggers   0   No editing possible.
        QAbstractItemView::CurrentChanged   1   Editing start whenever current item changes.
        QAbstractItemView::DoubleClicked    2   Editing starts when an item is double clicked.
        QAbstractItemView::SelectedClicked  4   Editing starts when clicking on an already selected item.
        QAbstractItemView::EditKeyPressed   8   Editing starts when the platform edit key has been pressed over an item.
        QAbstractItemView::AnyKeyPressed    16  Editing starts when any key is pressed over an item.
        QAbstractItemView::AllEditTriggers  31  Editing starts for all above actions.
        '''
        if self.odczyt():
            self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)
        else:
            self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table.verticalHeader().setVisible(False)
        self.table.setSortingEnabled(True)
        self.table.resizeColumnsToContents()
        self.table.setModel(self.model)
        self.table.setAlternatingRowColors(True)
        self.table.resizeColumnsToContents()

        # self.table.doubleClicked.connect(self.klikniecie)

    def anulowanie(self):
        self.parent.statusBar().clearMessage()
        from opcje_qt import Wewnatrz
        menu_gl = Wewnatrz(self.parent)
        self.parent.setCentralWidget(menu_gl)

    def odczyt(self):
        id = str(self.parent.id_user[0])
        query = 'SELECT odczyt FROM uzytkownicy WHERE iduzytkownicy=' + id
        return polaczenie(query)[0]

    def dodaj(self):
        poz, masz, op, tm, tp, ok = MultiDialog().getMultidialog(self)
        print(poz, masz, op, tm, tp, ok)
        id = self.parent.id_user[0]
        if ok and poz:
            query = "INSERT INTO detale(nr_detalu,maszyna,nazwa_op,tm,tp," \
                    "id_uzytkownika) VALUES ('" + poz + "','" + masz + "','" + op + "','" + tm + "','" + tp + "','" + str(
                id) + "');"
            print(query)
            polaczenie(query)
            if tm and tp:
                try:
                    self.uzupelniene()
                except:
                    pass
            self.model.select()
            self.parent.statusBar().showMessage("Dodano nową pozycję", 10000)
        else:
            print("Nie wpisano pozycji")
Exemplo n.º 16
0
class CreateDialogCodeDialog(QDialog, Ui_CreateDialogCodeDialog):
    """
    Class implementing a dialog to generate code for a Qt5 dialog.
    """
    DialogClasses = {
        "QDialog", "QWidget", "QMainWindow", "QWizard", "QWizardPage",
        "QDockWidget", "QFrame", "QGroupBox", "QScrollArea", "QMdiArea",
        "QTabWidget", "QToolBox", "QStackedWidget"
    }
    Separator = 25 * "="

    def __init__(self, formName, project, parent=None):
        """
        Constructor
        
        @param formName name of the file containing the form (string)
        @param project reference to the project object
        @param parent parent widget if the dialog (QWidget)
        """
        super(CreateDialogCodeDialog, self).__init__(parent)
        self.setupUi(self)

        self.okButton = self.buttonBox.button(QDialogButtonBox.Ok)

        self.slotsView.header().hide()

        self.project = project

        self.formFile = formName
        filename, ext = os.path.splitext(self.formFile)
        self.srcFile = '{0}{1}'.format(
            filename, self.project.getDefaultSourceExtension())

        self.slotsModel = QStandardItemModel()
        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setDynamicSortFilter(True)
        self.proxyModel.setSourceModel(self.slotsModel)
        self.slotsView.setModel(self.proxyModel)

        # initialize some member variables
        self.__initError = False
        self.__module = None

        packagesRoot = self.project.getUicParameter("PackagesRoot")
        if packagesRoot:
            self.packagesPath = os.path.join(self.project.getProjectPath(),
                                             packagesRoot)
        else:
            self.packagesPath = self.project.getProjectPath()

        if os.path.exists(self.srcFile):
            vm = e5App().getObject("ViewManager")
            ed = vm.getOpenEditor(self.srcFile)
            if ed and not vm.checkDirty(ed):
                self.__initError = True
                return

            try:
                splitExt = os.path.splitext(self.srcFile)
                if len(splitExt) == 2:
                    exts = [splitExt[1]]
                else:
                    exts = None
                from Utilities import ModuleParser
                self.__module = ModuleParser.readModule(self.srcFile,
                                                        extensions=exts,
                                                        caching=False)
            except ImportError:
                pass

        if self.__module is not None:
            self.filenameEdit.setText(self.srcFile)

            classesList = []
            vagueClassesList = []
            for cls in list(self.__module.classes.values()):
                if not set(cls.super).isdisjoint(
                        CreateDialogCodeDialog.DialogClasses):
                    classesList.append(cls.name)
                else:
                    vagueClassesList.append(cls.name)
            classesList.sort()
            self.classNameCombo.addItems(classesList)
            if vagueClassesList:
                if classesList:
                    self.classNameCombo.addItem(
                        CreateDialogCodeDialog.Separator)
                self.classNameCombo.addItems(sorted(vagueClassesList))

        if (os.path.exists(self.srcFile) and self.__module is not None
                and self.classNameCombo.count() == 0):
            self.__initError = True
            E5MessageBox.critical(
                self, self.tr("Create Dialog Code"),
                self.tr("""The file <b>{0}</b> exists but does not contain"""
                        """ any classes.""").format(self.srcFile))

        self.okButton.setEnabled(self.classNameCombo.count() > 0)

        self.__updateSlotsModel()

    def initError(self):
        """
        Public method to determine, if there was an initialzation error.
        
        @return flag indicating an initialzation error (boolean)
        """
        return self.__initError

    def __runUicLoadUi(self, command):
        """
        Private method to run the UicLoadUi.py script with the given command
        and return the output.
        
        @param command uic command to be run
        @type str
        @return tuple of process output and error flag
        @rtype tuple of (str, bool)
        """
        venvName = self.project.getDebugProperty("VIRTUALENV")
        venvManager = e5App().getObject("VirtualEnvManager")
        interpreter = venvManager.getVirtualenvInterpreter(venvName)
        execPath = venvManager.getVirtualenvExecPath(venvName)

        if not interpreter:
            interpreter = sys.executable

        env = QProcessEnvironment.systemEnvironment()
        if execPath:
            if env.contains("PATH"):
                env.insert("PATH",
                           os.pathsep.join([execPath,
                                            env.value("PATH")]))
            else:
                env.insert("PATH", execPath)

        loadUi = os.path.join(os.path.dirname(__file__), "UicLoadUi.py")
        args = [
            loadUi,
            command,
            self.formFile,
            self.packagesPath,
        ]

        uicText = ""
        ok = False

        proc = QProcess()
        proc.setWorkingDirectory(self.packagesPath)
        proc.setProcessEnvironment(env)
        proc.start(interpreter, args)
        started = proc.waitForStarted(5000)
        finished = proc.waitForFinished(30000)
        if started and finished:
            output = proc.readAllStandardOutput()
            outText = str(output, "utf-8", "replace")
            if proc.exitCode() == 0:
                ok = True
                uicText = outText.strip()
            else:
                E5MessageBox.critical(
                    self, self.tr("uic error"),
                    self.tr(
                        """<p>There was an error loading the form <b>{0}</b>"""
                        """.</p><p>{1}</p>""").format(self.formFile, outText))
        else:
            E5MessageBox.critical(
                self, self.tr("uic error"),
                self.tr(
                    """<p>The project specific Python interpreter <b>{0}</b>"""
                    """ could not be started or did not finish within 30"""
                    """ seconds.</p>""").format(interpreter))

        return uicText, ok

    def __objectName(self):
        """
        Private method to get the object name of a form.
        
        @return object name
        @rtype str
        """
        objectName = ""

        output, ok = self.__runUicLoadUi("object_name")
        if ok and output:
            objectName = output

        return objectName

    def __className(self):
        """
        Private method to get the class name of a form.
        
        @return class name
        @rtype str
        """
        className = ""

        output, ok = self.__runUicLoadUi("class_name")
        if ok and output:
            className = output

        return className

    def __signatures(self):
        """
        Private slot to get the signatures.
        
        @return list of signatures (list of strings)
        """
        if self.__module is None:
            return []

        signatures = []
        clsName = self.classNameCombo.currentText()
        if clsName:
            cls = self.__module.classes[clsName]
            for meth in list(cls.methods.values()):
                if meth.name.startswith("on_"):
                    if meth.pyqtSignature is not None:
                        sig = ", ".join([
                            bytes(QMetaObject.normalizedType(t)).decode()
                            for t in meth.pyqtSignature.split(",")
                        ])
                        signatures.append("{0}({1})".format(meth.name, sig))
                    else:
                        signatures.append(meth.name)
        return signatures

    def __mapType(self, type_):
        """
        Private method to map a type as reported by Qt's meta object to the
        correct Python type.
        
        @param type_ type as reported by Qt (QByteArray)
        @return mapped Python type (string)
        """
        mapped = bytes(type_).decode()

        # I. always check for *
        mapped = mapped.replace("*", "")

        if (self.project.getProjectLanguage() != "Python2"
                or self.project.getProjectType in ("PySide", "PySide2")):
            # 1. check for const
            mapped = mapped.replace("const ", "")

            # 2. replace QString and QStringList
            mapped = (mapped.replace("QStringList",
                                     "list").replace("QString", "str"))

            # 3. replace double by float
            mapped = mapped.replace("double", "float")

        return mapped

    def __updateSlotsModel(self):
        """
        Private slot to update the slots tree display.
        """
        self.filterEdit.clear()

        output, ok = self.__runUicLoadUi("signatures")
        if ok and output:
            objectsList = json.loads(output.strip())

            signatureList = self.__signatures()

            self.slotsModel.clear()
            self.slotsModel.setHorizontalHeaderLabels([""])
            for objectDict in objectsList:
                itm = QStandardItem("{0} ({1})".format(
                    objectDict["name"], objectDict["class_name"]))
                self.slotsModel.appendRow(itm)
                for methodDict in objectDict["methods"]:
                    itm2 = QStandardItem(methodDict["signature"])
                    itm.appendRow(itm2)

                    if self.__module is not None:
                        if (methodDict["methods"][0] in signatureList
                                or methodDict["methods"][1] in signatureList):
                            itm2.setFlags(Qt.ItemFlags(Qt.ItemIsEnabled))
                            itm2.setCheckState(Qt.Checked)
                            itm2.setForeground(QBrush(Qt.blue))
                            continue

                    itm2.setData(methodDict["pyqt_signature"],
                                 pyqtSignatureRole)
                    itm2.setData(methodDict["python_signature"],
                                 pythonSignatureRole)
                    itm2.setData(methodDict["return_type"], returnTypeRole)
                    itm2.setData(methodDict["parameter_types"],
                                 parameterTypesListRole)
                    itm2.setData(methodDict["parameter_names"],
                                 parameterNamesListRole)

                    itm2.setFlags(
                        Qt.ItemFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled
                                     | Qt.ItemIsSelectable))
                    itm2.setCheckState(Qt.Unchecked)

            self.slotsView.sortByColumn(0, Qt.AscendingOrder)

    def __generateCode(self):
        """
        Private slot to generate the code as requested by the user.
        """
        # first decide on extension
        if (self.filenameEdit.text().endswith(".py")
                or self.filenameEdit.text().endswith(".pyw")):
            self.__generatePythonCode()
        elif self.filenameEdit.text().endswith(".rb"):
            pass
        # second decide on project language
        elif self.project.getProjectLanguage() in ["Python2", "Python3"]:
            self.__generatePythonCode()
        elif self.project.getProjectLanguage() == "Ruby":
            pass
        else:
            # assume Python (our global default)
            self.__generatePythonCode()

    def __generatePythonCode(self):
        """
        Private slot to generate Python code as requested by the user.
        """
        # init some variables
        sourceImpl = []
        appendAtIndex = -1
        indentStr = "    "
        slotsCode = []

        if self.__module is None:
            # new file
            try:
                if self.project.getProjectLanguage() == "Python2":
                    if self.project.getProjectType() == "PySide":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyside.py2.tmpl")
                    elif self.project.getProjectType() == "PySide2":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyside2.py2.tmpl")
                    elif self.project.getProjectType() == "PyQt5":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt5.py2.tmpl")
                    else:
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt.py2.tmpl")
                else:
                    if self.project.getProjectType() == "PySide":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyside.py.tmpl")
                    elif self.project.getProjectType() == "PySide2":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyside2.py.tmpl")
                    elif self.project.getProjectType() in [
                            "PyQt5", "E6Plugin"
                    ]:
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt5.py.tmpl")
                    else:
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt.py.tmpl")
                tmplFile = open(tmplName, 'r', encoding="utf-8")
                template = tmplFile.read()
                tmplFile.close()
            except IOError as why:
                E5MessageBox.critical(
                    self, self.tr("Code Generation"),
                    self.tr("""<p>Could not open the code template file"""
                            """ "{0}".</p><p>Reason: {1}</p>""").format(
                                tmplName, str(why)))
                return

            objName = self.__objectName()
            if objName:
                template = (template.replace(
                    "$FORMFILE$",
                    os.path.splitext(
                        os.path.basename(self.formFile))[0]).replace(
                            "$FORMCLASS$", objName).replace(
                                "$CLASSNAME$",
                                self.classNameCombo.currentText()).replace(
                                    "$SUPERCLASS$", self.__className()))

                sourceImpl = template.splitlines(True)
                appendAtIndex = -1

                # determine indent string
                for line in sourceImpl:
                    if line.lstrip().startswith("def __init__"):
                        indentStr = line.replace(line.lstrip(), "")
                        break
        else:
            # extend existing file
            try:
                srcFile = open(self.srcFile, 'r', encoding="utf-8")
                sourceImpl = srcFile.readlines()
                srcFile.close()
                if not sourceImpl[-1].endswith("\n"):
                    sourceImpl[-1] = "{0}{1}".format(sourceImpl[-1], "\n")
            except IOError as why:
                E5MessageBox.critical(
                    self, self.tr("Code Generation"),
                    self.tr("""<p>Could not open the source file "{0}".</p>"""
                            """<p>Reason: {1}</p>""").format(
                                self.srcFile, str(why)))
                return

            cls = self.__module.classes[self.classNameCombo.currentText()]
            if cls.endlineno == len(sourceImpl) or cls.endlineno == -1:
                appendAtIndex = -1
                # delete empty lines at end
                while not sourceImpl[-1].strip():
                    del sourceImpl[-1]
            else:
                appendAtIndex = cls.endlineno - 1
                while not sourceImpl[appendAtIndex].strip():
                    appendAtIndex -= 1
                appendAtIndex += 1

            # determine indent string
            for line in sourceImpl[cls.lineno:cls.endlineno + 1]:
                if line.lstrip().startswith("def __init__"):
                    indentStr = line.replace(line.lstrip(), "")
                    break

        # do the coding stuff
        if self.project.getProjectLanguage() == "Python2":
            if self.project.getProjectType() in ("PySide", "PySide2"):
                pyqtSignatureFormat = '@Slot({0})'
            elif self.project.getProjectType() == "PyQt5":
                pyqtSignatureFormat = '@pyqtSlot({0})'
            else:
                pyqtSignatureFormat = '@pyqtSignature("{0}")'
        else:
            if self.project.getProjectType() in ("PySide", "PySide2"):
                pyqtSignatureFormat = '@Slot({0})'
            else:
                pyqtSignatureFormat = '@pyqtSlot({0})'
        for row in range(self.slotsModel.rowCount()):
            topItem = self.slotsModel.item(row)
            for childRow in range(topItem.rowCount()):
                child = topItem.child(childRow)
                if (child.checkState() and
                        child.flags() & Qt.ItemFlags(Qt.ItemIsUserCheckable)):
                    slotsCode.append('{0}\n'.format(indentStr))
                    slotsCode.append('{0}{1}\n'.format(
                        indentStr,
                        pyqtSignatureFormat.format(
                            child.data(pyqtSignatureRole))))
                    slotsCode.append('{0}def {1}:\n'.format(
                        indentStr, child.data(pythonSignatureRole)))
                    indentStr2 = indentStr * 2
                    slotsCode.append('{0}"""\n'.format(indentStr2))
                    slotsCode.append(
                        '{0}Slot documentation goes here.\n'.format(
                            indentStr2))
                    if (child.data(returnTypeRole)
                            or child.data(parameterTypesListRole)):
                        slotsCode.append('{0}\n'.format(indentStr2))
                        if child.data(parameterTypesListRole):
                            for name, type_ in zip(
                                    child.data(parameterNamesListRole),
                                    child.data(parameterTypesListRole)):
                                slotsCode.append(
                                    '{0}@param {1} DESCRIPTION\n'.format(
                                        indentStr2, name))
                                slotsCode.append('{0}@type {1}\n'.format(
                                    indentStr2, type_))
                        if child.data(returnTypeRole):
                            slotsCode.append(
                                '{0}@returns DESCRIPTION\n'.format(indentStr2))
                            slotsCode.append('{0}@rtype {1}\n'.format(
                                indentStr2, child.data(returnTypeRole)))
                    slotsCode.append('{0}"""\n'.format(indentStr2))
                    slotsCode.append('{0}# {1}: not implemented yet\n'.format(
                        indentStr2, "TODO"))
                    slotsCode.append(
                        '{0}raise NotImplementedError\n'.format(indentStr2))

        if appendAtIndex == -1:
            sourceImpl.extend(slotsCode)
        else:
            sourceImpl[appendAtIndex:appendAtIndex] = slotsCode

        # write the new code
        try:
            if self.project.useSystemEol():
                newline = None
            else:
                newline = self.project.getEolString()
            srcFile = open(self.filenameEdit.text(),
                           'w',
                           encoding="utf-8",
                           newline=newline)
            srcFile.write("".join(sourceImpl))
            srcFile.close()
        except IOError as why:
            E5MessageBox.critical(
                self, self.tr("Code Generation"),
                self.tr("""<p>Could not write the source file "{0}".</p>"""
                        """<p>Reason: {1}</p>""").format(
                            self.filenameEdit.text(), str(why)))
            return

        self.project.appendFile(self.filenameEdit.text())

    @pyqtSlot(int)
    def on_classNameCombo_activated(self, index):
        """
        Private slot to handle the activated signal of the classname combo.
        
        @param index index of the activated item (integer)
        """
        if (self.classNameCombo.currentText() ==
                CreateDialogCodeDialog.Separator):
            self.okButton.setEnabled(False)
            self.filterEdit.clear()
            self.slotsModel.clear()
            self.slotsModel.setHorizontalHeaderLabels([""])
        else:
            self.okButton.setEnabled(True)
            self.__updateSlotsModel()

    def on_filterEdit_textChanged(self, text):
        """
        Private slot called, when thext of the filter edit has changed.
        
        @param text changed text (string)
        """
        re = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp2)
        self.proxyModel.setFilterRegExp(re)

    @pyqtSlot()
    def on_newButton_clicked(self):
        """
        Private slot called to enter the data for a new dialog class.
        """
        path, file = os.path.split(self.srcFile)
        objName = self.__objectName()
        if objName:
            dlg = NewDialogClassDialog(objName, file, path, self)
            if dlg.exec_() == QDialog.Accepted:
                className, fileName = dlg.getData()

                self.classNameCombo.clear()
                self.classNameCombo.addItem(className)
                self.srcFile = fileName
                self.filenameEdit.setText(self.srcFile)
                self.__module = None

            self.okButton.setEnabled(self.classNameCombo.count() > 0)

    def on_buttonBox_clicked(self, button):
        """
        Private slot to handle the buttonBox clicked signal.
        
        @param button reference to the button that was clicked
            (QAbstractButton)
        """
        if button == self.okButton:
            self.__generateCode()
            self.accept()
        if role == Qt.DisplayRole:
            return "{}".format(self._data[index.row(), index.column()])

        return QVariant()

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

    table_view = QTableView()
    my_model = MyModel(None)

    proxy_model = QSortFilterProxyModel()   # <--
    proxy_model.setSourceModel(my_model)    # <--
    table_view.setModel(proxy_model)        # <--
    #table_view.setModel(my_model)

    proxy_model.setFilterRegExp(QRegExp("1", Qt.CaseInsensitive, QRegExp.FixedString))     # <--
    proxy_model.setFilterKeyColumn(0)                                                      # <--
    #table_view.setSortingEnabled(True)

    table_view.show()


    # The mainloop of the application. The event handling starts from this point.
    # The exec_() method has an underscore. It is because the exec is a Python keyword. And thus, exec_() was used instead.
    exit_code = app.exec_()

    # The sys.exit() method ensures a clean exit.
    # The environment will be informed, how the application ended.
    sys.exit(exit_code)
Exemplo n.º 18
0
class IncidentView(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(IncidentView, self).__init__(parent)
        self.view = QtWidgets.QTreeView()
        self.view.setAllColumnsShowFocus(True)
        self.view.setUniformRowHeights(True)
        box = QtWidgets.QVBoxLayout()
        box.addWidget(self.view)
        self.load_trace = QtWidgets.QPushButton('&Trace')
        self.load_trace.setToolTip('Load into the Trace Window')
        self.load_trace.setEnabled(False)
        for activation_signal in [
                self.view.activated,
                self.view.entered,
                self.view.pressed]:
            activation_signal.connect(lambda _: self.update_controls_state())
        self.load_trace.clicked.connect(self.load_current_trace)
        self.view.doubleClicked.connect(self.jump_to_index)
        hbox = QtWidgets.QHBoxLayout()
        self.filter = QtWidgets.QLineEdit()
        self.filter.textChanged.connect(self.filter_model)
        filter_label = QtWidgets.QLabel('&Search')
        filter_label.setBuddy(self.filter)
        hbox.addWidget(filter_label)
        hbox.addWidget(self.filter)
        hbox.addWidget(self.load_trace)
        box.addLayout(hbox)
        self.setLayout(box)
        self.model = None
        self.proxy = None

    def display(self, incidents, locations):
        self.model = IncidentModel(incidents, locations, self)
        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.model)
        self.proxy.setFilterRole(self.model.filter_role)
        self.proxy.setFilterRegExp(QRegExp(self.filter.text()))
        self.view.setModel(self.proxy)

    def filter_model(self, txt):
        if self.proxy:
            self.proxy.setFilterRegExp(QRegExp(txt))

    def update_controls_state(self):
        curr = self.view.currentIndex()
        self.load_trace.setEnabled(curr.isValid() and
                                   curr.parent().isValid())

    def load_current_trace(self):
        idx = self.proxy.mapToSource(self.view.currentIndex())
        if not idx.isValid() or index_level(idx) not in (1, 2):
            raise ValueError('load_current_trace: invalid index')

        if index_level(idx) == 2:
            idx = idx.parent()

        incident = self.model.incidents[idx.parent().row()]
        location = incident.locations[idx.row()]
        backtrace = self.model.locations[location]

        for p in reversed(backtrace):
            self.load_trace_point(p)

    def jump_to_index(self, idx):
        idx = self.proxy.mapToSource(idx)
        if index_level(idx) != 2:
            # don't mess with parents, they are used to create children
            return
        grandpa = idx.parent().parent()
        incident = self.model.incidents[grandpa.row()]
        location = incident.locations[idx.parent().row()]
        trace = self.model.locations[location]
        point = trace[idx.row()]
        self.show_trace_point(point)

    def load_trace_point(self, p):
        add_insn_to_trace_view(p.addr)

    def show_trace_point(self, p):
        idaapi.jumpto(p.addr)
Exemplo n.º 19
0
class Customer(QWidget):
    """
    Klasa odpowiedzialna za widget klienci
    """
    def __init__(self, parent, db):
        super(QWidget, self).__init__(parent)
        self.parent = parent
        self.btn_usun = QPushButton('Usuń')
        self.btn_mod = QPushButton('Modyfikuj')

        self.txt_imie = QLineEdit()
        self.txt_nazwisko = QLineEdit()
        self.txt_email = QLineEdit()
        self.txt_tel = QLineEdit()
        self.txt_ulica = QLineEdit()
        self.txt_nr_dom = QLineEdit()
        self.txt_kod = QLineEdit()
        self.txt_miasto = QLineEdit()

        self.proxy = QSortFilterProxyModel(self)
        self.view = QTableView()
        # Parametry połączenia z bazą
        self.model = QSqlTableModel(self, db)
        self.id_modify = -1
        self.initUI()

    def initUI(self):
        """
        Inicjuje UI
        """
        self.table_init()
        self.btn_usun.setDisabled(True)
        self.btn_mod.setDisabled(True)

        # Walidacja
        self.txt_kod.setInputMask('99-999')

        # Tworzenie kontrolek
        lbl_wyszukaj = QLabel('Wyszukaj klienta:')
        txt_wysz = QLineEdit(self)
        btn_dodaj = QPushButton('Dodaj')
        lbl_1 = QLabel('Imię:')
        lbl_2 = QLabel('Nazwisko:')
        lbl_3 = QLabel('Email:')
        lbl_4 = QLabel('Telefon:')
        lbl_5 = QLabel('Ulica:')
        lbl_6 = QLabel('Numer domu:')
        lbl_7 = QLabel('Kod pocztowy:')
        lbl_8 = QLabel('Miejscowość:')

        # Tworzenie widoków
        centralbox = QVBoxLayout()
        hbox_wysz = QHBoxLayout()
        gropubox = QGroupBox('Edycja danych klienta')
        grop_layout = QGridLayout()
        hbox_btn = QHBoxLayout()
        form_left = QFormLayout()
        form_right = QFormLayout()

        # Metody
        self.view.clicked.connect(self.change)
        btn_dodaj.clicked.connect(self.add)
        self.btn_mod.clicked.connect(self.modify)
        self.btn_usun.clicked.connect(self.remove)
        txt_wysz.textChanged.connect(self.searching)

        # Ustawianie widoków
        hbox_wysz.addWidget(lbl_wyszukaj)
        hbox_wysz.addWidget(txt_wysz)
        hbox_btn.addWidget(self.btn_usun)
        hbox_btn.addWidget(self.btn_mod)
        hbox_btn.addWidget(btn_dodaj)
        form_left.setSpacing(9)
        form_right.setSpacing(9)
        form_left.setContentsMargins(0, 0, 10, 0)
        form_right.setContentsMargins(10, 0, 0, 0)
        form_left.addRow(lbl_1, self.txt_imie)
        form_left.addRow(lbl_2, self.txt_nazwisko)
        form_left.addRow(lbl_3, self.txt_email)
        form_left.addRow(lbl_4, self.txt_tel)
        form_right.addRow(lbl_5, self.txt_ulica)
        form_right.addRow(lbl_6, self.txt_nr_dom)
        form_right.addRow(lbl_7, self.txt_kod)
        form_right.addRow(lbl_8, self.txt_miasto)
        grop_layout.addItem(form_left, 0, 0)
        grop_layout.addItem(form_right, 0, 1)
        gropubox.setLayout(grop_layout)
        centralbox.addLayout(hbox_wysz)
        centralbox.addWidget(self.view)
        centralbox.addWidget(gropubox)
        centralbox.addLayout(hbox_btn)
        self.setLayout(centralbox)
        self.show()

    def change(self):
        """
        Metoda edytująca zaznaczone wiersze - Wstawia wartości z wierszy w odpowiednie pola
        """
        index = (self.view.selectionModel().currentIndex())
        value = index.sibling(index.row(), index.column()).data()
        self.id_modify = index.sibling(index.row(), 0).data()
        self.txt_imie.setText(index.sibling(index.row(), 1).data())
        self.txt_nazwisko.setText(str(index.sibling(index.row(), 2).data()))
        self.txt_email.setText(index.sibling(index.row(), 3).data())
        self.txt_tel.setText(index.sibling(index.row(), 4).data())
        self.txt_ulica.setText(index.sibling(index.row(), 5).data())
        self.txt_nr_dom.setText(index.sibling(index.row(), 6).data())
        self.txt_miasto.setText(index.sibling(index.row(), 7).data())
        self.txt_kod.setText(index.sibling(index.row(), 8).data())

        if self.id_modify >= 0 and self.txt_imie.text(
        ) and self.txt_nazwisko.text():
            self.btn_mod.setEnabled(True)
            self.btn_usun.setEnabled(True)
        else:
            self.btn_usun.setDisabled(True)
            self.btn_mod.setDisabled(True)
            value.setText('')

    def table_init(self):
        """
        Inicjuje wygląd tabeli
        """
        self.model.setTable('klienci')
        query = QSqlQuery(
            'SELECT klienci_id, imie, nazwisko, email, telefon, ulica, numer_mieszkania, miejscowosc, poczta FROM '
            'klienci;')
        self.model.setQuery(query)
        self.proxy.setSourceModel(self.model)

        naglowki = {
            'klienci_id': 'ID',
            'imie': 'Imię',
            'nazwisko': 'Nazwisko',
            "email": 'Email',
            'telefon': 'Telefon',
            'ulica': 'Ulica',
            'numer_mieszkania': 'Numer mieszkania',
            'miejscowosc': 'Miejscowosc',
            'poczta': 'Kod pocztowy',
        }
        # Ustawianie nagłówków
        ilosc_kolumn = self.model.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model.headerData(i, Qt.Horizontal)
            self.model.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn])

        self.view.setSizeAdjustPolicy(
            QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.view.setSortingEnabled(True)
        self.view.setAlternatingRowColors(True)

        # Wczytanie danych
        self.view.setModel(self.proxy)
        self.view.hideColumn(0)
        self.view.sortByColumn(1, Qt.AscendingOrder)
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def if_checked(self, txt, q, val=None):
        """
        Sprawdza poprawność wprowadzonych damych.
        :param val: wartości do zapytania
        :param q: zapytanie query MySql
        :param txt: komunikat
        """
        if len(self.txt_imie.text()) < 3 or len(self.txt_nazwisko.text()) < 1:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setText(txt)
            msg.setWindowTitle("Popraw dane")
            msg.exec_()
            return False
        else:
            print('Trwa zmiana w bazie danych')
            if val:
                print('Połączenie')
                query_to_db(q, val)
            else:
                print('Transakcja')
                return transaction_to_db(q)

            return True

    def add(self):
        """
        Dodaje nowego klienta do bazy danych i odświeża widok.
        """
        tekst = 'Nie wprowadzono wszystkich danych'
        # Dodanie nowego użytkownika
        query = 'INSERT INTO klienci (imie, nazwisko, email, telefon, ulica, numer_mieszkania, miejscowosc, ' \
                'poczta) VALUES (%s, %s, %s, %s, %s, %s, %s, %s);'
        val = (self.txt_imie.text(), self.txt_nazwisko.text(),
               self.txt_email.text(), self.txt_tel.text(),
               self.txt_ulica.text(), self.txt_nr_dom.text(),
               self.txt_miasto.text(), self.txt_kod.text())

        if self.if_checked(tekst, query, val):
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Information)
            msg.setText('Klient został dodany do bazy danych')
            msg.setWindowTitle("Dodano nowego klienta")
            msg.exec_()
        # Odświeżanie widoku tabeli
        self.model.select()
        self.view.reset()

    def modify(self):
        """
        Modyfikuje bazę danych
        """
        tekst = 'Nie wprowadzono wszystkich danych'
        # Dodanie nowego użytkownika
        query = 'UPDATE klienci SET imie = %s, nazwisko = %s, email = %s, telefon = %s, ulica = %s, ' \
                'numer_mieszkania = %s, miejscowosc = %s, poczta = %s WHERE klienci_id = %s;'
        val = (self.txt_imie.text(), self.txt_nazwisko.text(),
               self.txt_email.text(), self.txt_tel.text(),
               self.txt_ulica.text(), self.txt_nr_dom.text(),
               self.txt_miasto.text(), self.txt_kod.text(), self.id_modify)
        if self.if_checked(tekst, query, val):
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Information)
            msg.setText('Dane klienta zostały pomyślnie zmodyfikowane')
            msg.setWindowTitle("Dane klienta zostały zmodyfikowane")
            msg.exec_()
        # Odświeżanie widoku tabeli
        self.model.select()
        self.view.reset()

    def remove(self):
        """
        Usuwa klientów z bazy danych
        """
        test = 'Błąd! Nie można usunąć danej usługi!'
        query = 'DELETE FROM klienci WHERE klienci_id = %s'
        query1 = 'DELETE FROM wizyty WHERE klienci_id = %s'
        val = (self.id_modify, )
        ret = QMessageBox.question(
            self, 'Usuwanie klienta',
            "Czy na pewno chcesz usunąć danego klienta?",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if ret == QMessageBox.Yes:
            if self.if_checked(test, [(query1, val), (query, val)]):
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Information)
                msg.setText('Klient został usunięty')
                msg.setWindowTitle("Usunięto")
                msg.exec_()

                self.txt_imie.setText('')
                self.txt_nazwisko.setText(''),
                self.txt_email.setText(''),
                self.txt_tel.setText(''),
                self.txt_ulica.setText(''),
                self.txt_nr_dom.setText(''),
                self.txt_miasto.setText(''),
                self.txt_kod.setText('')

        # Odświeżanie widoku tabeli
        self.model.select()
        self.view.reset()

    @pyqtSlot(str)
    def searching(self, text):
        """
        Wyszukuje po wszystkich kolumnach tabeli
        :param text:
        """
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy.setFilterKeyColumn(-1)
Exemplo n.º 20
0
class ViewDataWindow(QDialog):
    formSubmitted = pyqtSignal()
    closeSignal = pyqtSignal()

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

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

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

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

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

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

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

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

        # Filter groupbox layout

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

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

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

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

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

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

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

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

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

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

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

    def quitButtonClicked(self):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return timestamps, tempdat

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

        brewArrayPos = self.displayedBrewsH.index(brewToRemove)

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

        del self.activeColours[brewArrayPos]

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

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

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

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

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

        self.tabBoil.graph.removeCurve(brewArrayPos)

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

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

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

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

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

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

    # Slot for clearing all filters
    def clearFilters(self):
        self.dateEdit.setDate(self.maxDate)
        self.proxyModel.setFilterRegExp('')
        self.proxyModel.setFilterKeyColumn(0)
        self.proxyModel.setFilterKeyColumn(1)
        self.proxyModel.setFilterKeyColumn(2)
        self.lineEdit_recipe.clear()
        self.edit_batchID.clear()
Exemplo n.º 21
0
class BrowseWidget(QWidget):
    def __init__(self, parent=None):
        super(BrowseWidget, self).__init__(parent)
        self.parent = parent
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.parent)
        self.usersFrame = QtWidgets.QFrame(self.parent)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.usersFrame)
        self.browseUsersFrame = QtWidgets.QFrame(self.usersFrame)
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.browseUsersFrame)
        self.browseUsersLabel = QtWidgets.QLabel(self.browseUsersFrame)
        self.browseUsersLineEdit = QtWidgets.QLineEdit(self.browseUsersFrame)
        self.usersList = QtWidgets.QListView(self.usersFrame)
        self.buttonsFrame = QtWidgets.QFrame(self.parent)
        self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.buttonsFrame)
        self.downloadButton = QtWidgets.QPushButton(self.buttonsFrame)
        self.treeFrame = QtWidgets.QFrame(self.parent)
        self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.treeFrame)
        self.browseFileFrame = QtWidgets.QFrame(self.treeFrame)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.browseFileFrame)
        self.browseFileLabel = QtWidgets.QLabel(self.browseFileFrame)
        self.browseFileLineEdit = QtWidgets.QLineEdit(self.browseFileFrame)
        self.fileTreeView = QtWidgets.QTreeView(self.treeFrame)
        self.foldIcon = QtGui.QIcon()
        self.fileIcon = QtGui.QIcon()
        self.filterType = 0
        self.lastSearchedTreeFilter = None
        self.chosenUserTreeFile = None
        self.usersModel = None
        self.fileTreeModel = None
        self.worker = None
        self.thread = None
        self.fileProxyModel = QSortFilterProxyModel()
        self.setupUi()

    def disableButtons(self):
        self.downloadButton.setEnabled(False)

    def enableButtons(self):
        self.downloadButton.setEnabled(True)

    def fillUsersList(self, users_input):
        self.usersModel = QStandardItemModel()
        with open(users_input, "r") as inp:
            for line in inp.readlines():
                item = UserItem(name=line.strip(),
                                structFile=abspath('./files/user_tree.json'))
                self.usersModel.appendRow(item)
        self.usersList.setModel(self.usersModel)
        self.verticalLayout_3.addWidget(self.usersList)

    def filterUsersList(self, text):
        # search = QtCore.QRegExp(text,
        #                         QtCore.Qt.CaseInsensitive,
        #                         QtCore.QRegExp.RegExp
        #                         )
        # self.usersProxyModel.setFilterRegExp(search)
        searchedText = text.lower()
        for row in range(self.usersModel.rowCount()):
            if searchedText in str(self.usersModel.item(row).text()).lower():
                self.usersList.setRowHidden(row, False)
            else:
                self.usersList.setRowHidden(row, True)

    def renderTree(self, treeFile: str):
        self.fileTreeModel = TreeModelFile(treeInput=treeFile,
                                           foldIcon=self.foldIcon,
                                           fileIcon=self.fileIcon)
        # Allows for scrolling optimizations.
        self.fileTreeView.setAlternatingRowColors(True)
        self.fileTreeView.setUniformRowHeights(True)
        self.fileProxyModel.setSourceModel(self.fileTreeModel)
        # self.fileProxyModel.sort()
        self.fileTreeView.setModel(self.fileProxyModel)
        self.enableButtons()

    def fillStructTree(self, index):
        self.chosenUserTreeFile = self.usersList.model().itemData(index)[
            UserItem.StructFileRole]
        self.renderTree(self.chosenUserTreeFile)

    def simpleTreeFilter(self, searchText):
        if self.fileTreeModel is not None and self.filterType == 0:
            search = QtCore.QRegExp(searchText, QtCore.Qt.CaseInsensitive,
                                    QtCore.QRegExp.RegExp)
            self.fileProxyModel.setFilterRegExp(search)

    def complexTreeFilter(self):
        searchText = self.browseFileLineEdit.text()
        if searchText == "":
            self.renderTree(self.chosenUserTreeFile)
        if self.fileTreeModel is not None and self.filterType == 1:
            if self.lastSearchedTreeFilter is not None and searchText not in self.lastSearchedTreeFilter:
                self.fileTreeModel = TreeModelFile(
                    treeInput=self.chosenUserTreeFile,
                    foldIcon=self.foldIcon,
                    fileIcon=self.fileIcon)
            newTreeDict = self.fileTreeModel.filterTree(searchText)
            if newTreeDict["#_size"] != 0:
                with open(abspath("./files/temp/treeFilterTemp.json"),
                          "w") as filteredTree:
                    json.dump(newTreeDict, filteredTree)
                    self.chosenUserTreeFile = self.fileTreeModel.treeInput
                    self.lastSearchedTreeFilter = searchText
                self.renderTree(filteredTree.name)

    def prepareDownloadItemsAction(self):
        self.disableButtons()
        try:
            self.thread = QtCore.QThread()
            self.worker = DownLoadWorker(self.chosenUserTreeFile,
                                         self.fileTreeModel)
            self.worker.moveToThread(self.thread)

            self.thread.started.connect(self.worker.run)
            self.worker.finished.connect(self.thread.quit)
            self.worker.finished.connect(self.worker.deleteLater)
            self.thread.finished.connect(self.thread.deleteLater)

            self.thread.start()
            self.thread.finished.connect(
                lambda: {self.renderTree(self.chosenUserTreeFile)})
        except Exception as e:
            print(e)
            self.enableButtons()

    def setupUi(self):
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.usersFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.usersFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.usersFrame.setObjectName("usersFrame")
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.browseUsersFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.browseUsersFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.browseUsersFrame.setObjectName("browseUsersFrame")
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        font = QtGui.QFont()
        font.setFamily("Verdana")
        font.setPointSize(9)
        self.browseUsersLabel.setFont(font)
        self.browseUsersLabel.setObjectName("browseUsersLabel")
        self.horizontalLayout_2.addWidget(self.browseUsersLabel)
        self.browseUsersLineEdit.setObjectName("browseUsersLineEdit")
        self.horizontalLayout_2.addWidget(self.browseUsersLineEdit)
        self.verticalLayout_3.addWidget(self.browseUsersFrame)
        self.usersList.viewport().setProperty(
            "cursor", QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.usersList.setObjectName("usersList")

        self.horizontalLayout.addWidget(self.usersFrame)
        self.buttonsFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.buttonsFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.buttonsFrame.setObjectName("buttonsFrame")
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        spacerItem = QtWidgets.QSpacerItem(20, 40,
                                           QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout_4.addItem(spacerItem)
        self.downloadButton.setCursor(
            QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.downloadButton.setLayoutDirection(QtCore.Qt.RightToLeft)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/buttonIcons/downloadIcon"),
                       QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.downloadButton.setIcon(icon)
        self.downloadButton.setIconSize(QtCore.QSize(15, 15))
        self.downloadButton.setObjectName("downloadButton")
        self.verticalLayout_4.addWidget(self.downloadButton)
        spacerItem1 = QtWidgets.QSpacerItem(20, 40,
                                            QtWidgets.QSizePolicy.Minimum,
                                            QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout_4.addItem(spacerItem1)
        self.horizontalLayout.addWidget(self.buttonsFrame)
        self.treeFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.treeFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.treeFrame.setObjectName("treeFrame")
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.browseFileFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.browseFileFrame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.browseFileFrame.setObjectName("browseFileFrame")
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        font = QtGui.QFont()
        font.setFamily("Verdana")
        font.setPointSize(9)
        self.browseFileLabel.setFont(font)
        self.browseFileLabel.setObjectName("browseFileLabel")
        self.horizontalLayout_4.addWidget(self.browseFileLabel)
        self.browseFileLineEdit.setObjectName("browseFileLineEdit")
        self.horizontalLayout_4.addWidget(self.browseFileLineEdit)
        self.verticalLayout_5.addWidget(self.browseFileFrame)
        self.fileTreeView.viewport().setProperty(
            "cursor", QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.fileTreeView.setObjectName("fileTreeView")
        self.verticalLayout_5.addWidget(self.fileTreeView)
        self.horizontalLayout.addWidget(self.treeFrame)
        self.browseUsersLabel.setBuddy(self.browseUsersLineEdit)
        self.browseFileLabel.setBuddy(self.browseFileLineEdit)

        self.browseFileLineEdit.setStyleSheet(
            'background-color: rgb(255, 255, 255);')
        self.browseUsersLineEdit.setStyleSheet(
            'background-color: rgb(255, 255, 255);')
        self.usersList.setStyleSheet('background-color: rgb(255, 255, 255);')
        self.fileTreeView.setStyleSheet(
            'background-color: rgb(255, 255, 255);')

        QtCore.QMetaObject.connectSlotsByName(self)

        self.browseUsersLabel.setText("Browse Users:")
        self.downloadButton.setText("DownLoad")
        self.browseFileLabel.setText("Browse Files:")

        self.fileIcon.addPixmap(QtGui.QPixmap(":/windowIcons/fileIcon"),
                                QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.foldIcon.addPixmap(QtGui.QPixmap(":/windowIcons/foldIcon"),
                                QtGui.QIcon.Normal, QtGui.QIcon.Off)

        self.disableButtons()
        self.fillUsersList(abspath('./files/users_list.txt'))

        self.usersList.clicked['QModelIndex'].connect(self.fillStructTree)
        self.browseUsersLineEdit.textChanged.connect(self.filterUsersList)
        self.browseFileLineEdit.textChanged.connect(self.simpleTreeFilter)
        self.downloadButton.clicked.connect(self.prepareDownloadItemsAction)
Exemplo n.º 22
0
class Employee(QWidget):
    """
    Klasa odpowiedzialna za widget Zmiany hasła
    """
    def __init__(self, parent, db):
        super(QWidget, self).__init__(parent)
        self.btn_usun = QPushButton('Usuń')
        self.btn_modyfikuj = QPushButton('Modyfikuj')
        self.id_modify = -1
        self.view = QTableView()
        self.cb_pracownik = QCheckBox('Pracownik')
        self.txt_login = QLineEdit()
        self.txt_nazwisko = QLineEdit()
        self.txt_imie = QLineEdit()
        self.parent = parent
        self.layout = QHBoxLayout()
        self.lbl_wysz = QLabel("Wyszukaj:")
        self.txt_wysz = QLineEdit(self)
        self.proxy = QSortFilterProxyModel(self)

        # Parametry połączenia z bazą
        self.model = QSqlTableModel(self, db)
        self.initUI()

    def initUI(self):
        """
        Inicjuje UI
        """
        fbox = QFormLayout()
        fbox.addRow(self.lbl_wysz, self.txt_wysz)
        self.txt_wysz.textChanged.connect(self.searching)
        self.table_init()

        # Pokazuje wszystko
        # self.model.select()

        group_box = QGroupBox("Edycja danych użytkownika")
        fbox2 = QFormLayout()
        lbl_imie = QLabel('Imię:')
        lbl_nazwisko = QLabel('Nazwisko:')
        lbl_login = QLabel('Login:'******'Dodaj')
        self.btn_modyfikuj.setDisabled(True)
        self.btn_usun.setDisabled(True)
        fbox2.addRow(lbl_imie, self.txt_imie)
        fbox2.addRow(lbl_nazwisko, self.txt_nazwisko)
        fbox2.addRow(lbl_login, self.txt_login)
        fbox2.addRow(self.cb_pracownik)
        lhbox = QHBoxLayout()
        lhbox.addWidget(self.btn_usun)
        lhbox.addSpacing(35)
        lhbox.addWidget(self.btn_modyfikuj)
        lhbox.addSpacing(35)
        lhbox.addWidget(btn_dodaj)
        fbox2.addRow(lhbox)
        group_box.setLayout(fbox2)
        fbox.addRow(group_box)

        # Formatka dni
        self.group_box_dni = QGroupBox('Godziny pracy')
        fbox_dni = QFormLayout()
        lhbox_pon = QHBoxLayout()
        lhbox_wt = QHBoxLayout()
        lhbox_sr = QHBoxLayout()
        lhbox_czw = QHBoxLayout()
        lhbox_pt = QHBoxLayout()
        lhbox_sob = QHBoxLayout()
        lbl_pon = QLabel('Poniedziałek')
        lbl_wt = QLabel('Wtorek')
        lbl_sr = QLabel('Środa')
        lbl_czw = QLabel('Czwartek')
        lbl_pt = QLabel('Piątek')
        lbl_sob = QLabel('Sobota')
        self.txt_pon_od = QLineEdit()
        self.txt_pon_do = QLineEdit()
        self.txt_wt_od = QLineEdit()
        self.txt_wt_do = QLineEdit()
        self.txt_sr_od = QLineEdit()
        self.txt_sr_do = QLineEdit()
        self.txt_czw_od = QLineEdit()
        self.txt_czw_do = QLineEdit()
        self.txt_pt_od = QLineEdit()
        self.txt_pt_do = QLineEdit()
        self.txt_sob_od = QLineEdit()
        self.txt_sob_do = QLineEdit()
        self.pola = (self.txt_pon_od, self.txt_pon_do, self.txt_wt_od,
                     self.txt_wt_do, self.txt_sr_od, self.txt_sr_do,
                     self.txt_czw_od, self.txt_czw_do, self.txt_pt_od,
                     self.txt_pt_do, self.txt_sob_od, self.txt_sob_do)
        lhbox_pon.addWidget(self.txt_pon_od)
        lhbox_pon.addSpacing(30)
        lhbox_pon.addWidget(self.txt_pon_do)
        lhbox_wt.addWidget(self.txt_wt_od)
        lhbox_wt.addSpacing(30)
        lhbox_wt.addWidget(self.txt_wt_do)
        lhbox_sr.addWidget(self.txt_sr_od)
        lhbox_sr.addSpacing(30)
        lhbox_sr.addWidget(self.txt_sr_do)
        lhbox_czw.addWidget(self.txt_czw_od)
        lhbox_czw.addSpacing(30)
        lhbox_czw.addWidget(self.txt_czw_do)
        lhbox_pt.addWidget(self.txt_pt_od)
        lhbox_pt.addSpacing(30)
        lhbox_pt.addWidget(self.txt_pt_do)
        lhbox_sob.addWidget(self.txt_sob_od)
        lhbox_sob.addSpacing(30)
        lhbox_sob.addWidget(self.txt_sob_do)
        fbox_dni.addRow(lbl_pon, lhbox_pon)
        fbox_dni.addRow(lbl_wt, lhbox_wt)
        fbox_dni.addRow(lbl_sr, lhbox_sr)
        fbox_dni.addRow(lbl_czw, lhbox_czw)
        fbox_dni.addRow(lbl_pt, lhbox_pt)
        fbox_dni.addRow(lbl_sob, lhbox_sob)
        group_box_szablon = QGroupBox('Szablony')
        btn1 = QPushButton('7-15')
        btn2 = QPushButton('8-16')
        btn3 = QPushButton('9-17')
        btn4 = QPushButton('10-18')
        vbox = QVBoxLayout()
        vbox.addWidget(btn1)
        vbox.addWidget(btn2)
        vbox.addWidget(btn3)
        vbox.addWidget(btn4)
        group_box_szablon.setLayout(vbox)
        hbox_dni = QHBoxLayout()
        hbox_dni.addLayout(fbox_dni)
        hbox_dni.addWidget(group_box_szablon)
        self.group_box_dni.setLayout(hbox_dni)
        fbox.addRow(self.group_box_dni)
        self.group_box_dni.setVisible(False)

        self.view.clicked.connect(self.change)
        btn_dodaj.clicked.connect(self.add)
        self.btn_modyfikuj.clicked.connect(self.modify)
        self.btn_usun.clicked.connect(self.remove)
        self.cb_pracownik.stateChanged.connect(self.changeGroupBox)
        btn1.clicked.connect(lambda: self.hour(7))
        btn2.clicked.connect(lambda: self.hour(8))
        btn3.clicked.connect(lambda: self.hour(9))
        btn4.clicked.connect(lambda: self.hour(10))

        self.layout.addLayout(fbox)
        self.layout.addWidget(self.view)
        self.setLayout(self.layout)
        self.show()

    def hour(self, godz):
        """
        Wypełnia godzinami odpowiednie pola
        :param godz: int godzina rozpoczęcia
        """
        for i, value in enumerate(self.pola):
            if i % 2 == 0:
                value.setText(str(timedelta(hours=godz)))
            else:
                value.setText(str(timedelta(hours=godz + 8)))

    def changeGroupBox(self, state):
        """
        Sprawdza, czy zaznaczono checkbox pracownik
        :param state: status pola pracownik
        """
        if state == Qt.Checked:
            self.group_box_dni.setVisible(True)
        else:
            self.group_box_dni.setVisible(False)

    def table_init(self):
        """
        Inicjuje wygląd tabeli
        """
        self.model.setTable('uzytkownik')
        query = QSqlQuery(
            'SELECT uzytkownik_id, uzytkownik_nazwa, imie, nazwisko, pracownik FROM uzytkownik;'
        )
        self.model.setQuery(query)

        self.proxy.setSourceModel(self.model)

        naglowki = {
            'uzytkownik_id': 'ID',
            'uzytkownik_nazwa': 'Login',
            'imie': 'Imię',
            "nazwisko": 'Nazwisko',
            'pracownik': 'Pracownik',
        }
        # Ustawianie nagłówków
        ilosc_kolumn = self.model.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model.headerData(i, Qt.Horizontal)
            self.model.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn])

        # TODO Poprawić wiywietlanie kolumny Pracownik
        self.view.setSizeAdjustPolicy(
            QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.view.setSortingEnabled(True)
        self.view.setAlternatingRowColors(True)

        # Wczytanie danych
        self.view.setModel(self.proxy)
        self.view.hideColumn(0)
        self.view.sortByColumn(1, Qt.AscendingOrder)
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def if_checked(self, txt, q, val=None):
        """
        Sprawdza poprawność wprowadzonych damych.
        :param val: wartości do zapytania
        :param q: zapytanie query MySql
        :param txt: komunikat
        """
        if len(self.txt_imie.text()) < 2 or len(
                self.txt_nazwisko.text()) < 2 or len(
                    self.txt_login.text()) < 5:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Warning)
            msg.setText(txt)
            msg.setWindowTitle("Popraw dane")
            msg.exec_()
            return False
        else:
            print('Trwa zmiana w bazie danych')
            if val:
                print('Połączenie')
                query_to_db(q, val)
            else:
                print('Transakcja')
                return transaction_to_db(q)

            # Odświeżanie widoku tabeli
            self.model.select()
            self.view.reset()
            return True

    def employee_type(self):
        """
        Sprawdza, czy dana osoba jest pracownikiem, czy nie.
        :return: int Pracownik
        """
        return 1 if self.cb_pracownik.checkState() else 0

    def add(self):
        """
        Dodaje nową osobę do bazy danych i odświeża widok.
        """
        tekst = "Dane zostały błędnie wprowadzone.\nLogin musi mieć minimum 5 znaków."

        # Dodanie nowego użytkownika
        query1 = 'INSERT INTO uzytkownik (imie, nazwisko, uzytkownik_nazwa, haslo, pracownik) VALUES (%s, %s, %s, ' \
                 'sha(%s), %s)'
        val1 = (self.txt_imie.text(), self.txt_nazwisko.text(),
                self.txt_login.text(), self.txt_login.text(),
                self.employee_type())

        # Dodanie godzin do pracownika
        if self.cb_pracownik.checkState():
            query2 = 'INSERT INTO godziny (uzytkownik_id, pon_od, pon_do, wt_od, wt_do, sr_od, sr_do, czw_od, czw_do, pt_od, pt_do, sob_od, sob_do) VALUES (LAST_INSERT_ID(),"' + self.txt_pon_od.text(
            ) + '","' + self.txt_pon_do.text() + '","' + self.txt_wt_od.text(
            ) + '","' + self.txt_wt_do.text() + '","' + self.txt_sr_od.text(
            ) + '","' + self.txt_sr_do.text() + '","' + self.txt_czw_od.text(
            ) + '","' + self.txt_czw_do.text() + '","' + self.txt_pt_od.text(
            ) + '","' + self.txt_pt_do.text() + '","' + self.txt_sob_od.text(
            ) + '","' + self.txt_sob_do.text() + '");'
            val2 = None
        else:
            query2 = None
            val2 = None

        if self.if_checked(tekst, [(query1, val1), (query2, val2)]):
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Information)
            msg.setText('Dodano nowego użytkownika')
            msg.setWindowTitle("Dodano użytkownika")
            msg.exec_()
        else:
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Warning)
            msg.setText('Dany użytkownik istnieje już w bazie')
            msg.setWindowTitle("Błąd!")
            msg.exec_()

        # Odświeżanie widoku tabeli
        self.model.select()
        self.view.reset()

    def modify(self):
        """
        Modyfikuje bazę danych
        """
        query = 'SELECT * FROM godziny WHERE uzytkownik_id = %s'
        val = (self.id_modify, )
        wynik = query_to_db(query, val)

        test = 'Dane zostały błędnie zmodyfikowane.'
        query = 'UPDATE uzytkownik SET imie = %s, nazwisko = %s, uzytkownik_nazwa = %s, ' \
                'pracownik = %s WHERE uzytkownik_id = %s'
        val = (self.txt_imie.text(), self.txt_nazwisko.text(),
               self.txt_login.text(), self.employee_type(), self.id_modify)
        self.if_checked(test, query, val)

        if wynik and self.cb_pracownik.checkState():
            query = 'UPDATE godziny SET pon_od = %s, pon_do = %s, wt_od = %s, wt_do = %s, sr_od = %s, sr_do = %s, ' \
                    'czw_od = %s, czw_do = %s, pt_od = %s, pt_do = %s, sob_od = %s, sob_do = %s WHERE uzytkownik_id = %s;'
            val = (self.txt_pon_od.text(), self.txt_pon_do.text(),
                   self.txt_wt_od.text(), self.txt_wt_do.text(),
                   self.txt_sr_od.text(), self.txt_sr_do.text(),
                   self.txt_czw_od.text(), self.txt_czw_do.text(),
                   self.txt_pt_od.text(), self.txt_pt_do.text(),
                   self.txt_sob_od.text(), self.txt_sob_do.text(),
                   self.id_modify)
            query_to_db(query, val)
        elif self.cb_pracownik.checkState():
            query = 'INSERT INTO godziny SET uzytkownik_id = %s, pon_od = %s, pon_do = %s, wt_od = %s, wt_do = %s, ' \
                    'sr_od = %s, ' \
                    'sr_do = %s, ' \
                    'czw_od = %s, czw_do = %s, pt_od = %s, pt_do = %s, sob_od = %s, sob_do = %s; '
            val = (self.id_modify, self.txt_pon_od.text(),
                   self.txt_pon_do.text(), self.txt_wt_od.text(),
                   self.txt_wt_do.text(), self.txt_sr_od.text(),
                   self.txt_sr_do.text(), self.txt_czw_od.text(),
                   self.txt_czw_do.text(), self.txt_pt_od.text(),
                   self.txt_pt_do.text(), self.txt_sob_od.text(),
                   self.txt_sob_do.text())
            query_to_db(query, val)
        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Information)
        msg.setText('Zmodyfikowano dane użytkownika')
        msg.setWindowTitle("Zmodyfikowano użytkownika")
        msg.exec_()

        # Odświeżanie widoku tabeli
        self.model.select()
        self.view.reset()

    def remove(self):
        """
        Usuwa dane z bazy danych
        """
        test = 'Błąd! Nie można usunąć danego użytkownika!'
        query1 = 'DELETE FROM uzytkownik WHERE uzytkownik_id = %s'
        val = (self.id_modify, )
        query2 = 'DELETE FROM godziny WHERE uzytkownik_id = %s'
        query3 = 'DELETE FROM uzytkownik_usluga WHERE uzytkownik_id = %s'
        query4 = 'DELETE FROM wizyty WHERE uzytkownik_id = %s'
        if self.id_modify == 1:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText('Błąd! Nie można usunąć domyślnego użytkownika')
            msg.setWindowTitle("Popraw dane")
            msg.exec_()
        else:
            ret = QMessageBox.question(
                self, 'Usuwanie użytkownika',
                "Czy na pewno chcesz usunąć danego użytkownika?",
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if ret == QMessageBox.Yes:
                if self.if_checked(test, [(query4, val), (query3, val),
                                          (query2, val), (query1, val)]):
                    msg = QMessageBox()
                    msg.setIcon(QMessageBox.Information)
                    msg.setText('Użytkownik został usunięty')
                    msg.setWindowTitle("Usunięto")
                    msg.exec_()

                    self.txt_imie.setText('')
                    self.txt_login.setText('')
                    self.txt_nazwisko.setText('')
                    if self.cb_pracownik.checkState():
                        self.cb_pracownik.toggle()

        # Odświeżanie widoku tabeli
        self.model.select()
        self.view.reset()

    def change(self):
        """
        Metoda edytująca zaznaczone wiersze - Wstawia wartości z wierszy w odpowiednie pola
        """
        index = (self.view.selectionModel().currentIndex())
        value = index.sibling(index.row(), index.column()).data()
        self.id_modify = index.sibling(index.row(), 0).data()
        self.txt_imie.setText(index.sibling(index.row(), 2).data())
        self.txt_nazwisko.setText(index.sibling(index.row(), 3).data())
        self.txt_login.setText(index.sibling(index.row(), 1).data())

        if self.id_modify >= 0 and self.txt_imie.text(
        ) and self.txt_login.text() and self.txt_nazwisko.text():
            self.btn_modyfikuj.setEnabled(True)
            self.btn_usun.setEnabled(True)
        else:
            self.btn_usun.setDisabled(True)
            self.btn_modyfikuj.setDisabled(True)
        if index.sibling(index.row(), 4).data() == 1:
            if not self.cb_pracownik.checkState():
                self.cb_pracownik.toggle()
        else:
            if self.cb_pracownik.checkState():
                for value in self.pola:
                    value.setText('')
                self.cb_pracownik.toggle()

        if self.cb_pracownik.checkState():
            query = 'SELECT * FROM godziny WHERE uzytkownik_id = %s'
            val = (self.id_modify, )
            wynik = query_to_db(query, val)
            for i, value in enumerate(self.pola, 2):
                if wynik:
                    value.setText(str(wynik[i]))
                else:
                    value.setText('')

    @pyqtSlot(str)
    def searching(self, text):
        """
        Wyszukuje po wszystkich kolumnach tabeli
        :param text:
        """
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy.setFilterKeyColumn(-1)
Exemplo n.º 23
0
class IPTagsSelectDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.app = QApplication.instance()

        self.destTags = []

        self.allTagsModel = UneditableStringListModel(self)
        self.destTagsModel = UneditableStringListModel(self)
        self.allTagsProxyModel = QSortFilterProxyModel(self)
        self.allTagsProxyModel.setSourceModel(self.allTagsModel)

        self.ui = ui_iptagsmanager.Ui_IPTagsDialog()
        self.ui.setupUi(self)

        self.ui.destTagsView.setModel(self.destTagsModel)
        self.ui.destTagsView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.ui.destTagsView.doubleClicked.connect(self.onTagDoubleClicked)

        self.ui.addTagButton.clicked.connect(lambda: ensure(self.addTag()))
        self.ui.lineEditTag.textChanged.connect(self.onTagEditChanged)
        self.ui.lineEditTag.setValidator(
            QRegExpValidator(QRegExp(r'[A-Za-z0-9-_@#]+')))
        self.ui.lineEditTag.setMaxLength(128)

        self.ui.tagItButton.clicked.connect(self.onTagObject)
        self.ui.untagItButton.clicked.connect(self.untagObject)
        self.ui.okButton.clicked.connect(lambda: ensure(self.validate()))
        self.ui.noTagsButton.clicked.connect(self.reject)

        self.setMinimumSize(self.app.desktopGeometry.width() / 2,
                            (2 * self.app.desktopGeometry.height()) / 3)

    def onTagEditChanged(self, text):
        self.allTagsProxyModel.setFilterRegExp(text)
        self.ui.allTagsView.clearSelection()

    def onTagDoubleClicked(self, idx):
        ensure(self.tagObject([idx]))

    def onTagObject(self):
        ensure(self.tagObject())

    def untagObject(self):
        try:
            for idx in self.ui.destTagsView.selectedIndexes():
                tag = self.destTagsModel.data(idx, Qt.DisplayRole)

                if tag:
                    tagList = self.destTagsModel.stringList()
                    tagList.remove(tag)
                    self.destTagsModel.setStringList(tagList)
        except Exception:
            pass

    async def tagObject(self, indexes=None):
        if indexes is None:
            indexes = self.ui.allTagsView.selectedIndexes()

        for idx in indexes:
            tag = self.allTagsProxyModel.data(idx, Qt.DisplayRole)

            if tag and tag not in self.destTagsModel.stringList():
                self.destTagsModel.setStringList(
                    self.destTagsModel.stringList() + [tag])

    async def initDialog(self):
        await self.updateAllTags()

    async def addTag(self):
        tagname = self.ui.lineEditTag.text()
        if not tagname:
            return

        await database.ipTagAdd(ipTagsFormat(tagname))
        self.ui.lineEditTag.clear()
        await self.updateAllTags()

    async def updateAllTags(self):
        tags = [t.name for t in await database.ipTagsAll()]
        self.allTagsModel.setStringList(tags)
        self.ui.allTagsView.setModel(self.allTagsProxyModel)
        self.allTagsProxyModel.sort(0)

    async def validate(self):
        self.destTags = self.destTagsModel.stringList()
        self.done(1)
Exemplo n.º 24
0
class Wyswietl(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.parent = parent
        self.proxy = QSortFilterProxyModel(self)
        self.edit_wysz = QLineEdit(self)
        self.combo_typ = QComboBox(self)
        self.lbl_wysz = QLabel("Wyszukaj")
        self.lbl_typ = QLabel("Wybierz typ narzędzia:")
        self.table = QTableView(self)
        sciezka = czy_istnieje()
        db = QSqlDatabase.addDatabase('QSQLITE')
        db.setDatabaseName(sciezka)
        if db.open():
            print('Otworzono bazę danych')
        self.model = QSqlTableModel(self, db)

        self.formularz = QGroupBox("Wyświetl narzędzia")
        self.initUI()

    def initUI(self):
        typy_narzedzi = [
            'Brak',
            'Frez palcowy',
            'Frez płytkowy (głowica)',
            'Gwintownik',
            'Nóż tokarski',
            # 'Oprawka',
            'Piła',
            'Pozostałe',
            'Rozwiertak',
            'Wiertło',
            'Wiertło składane',
            'Wygniatak'
        ]
        self.widok()
        self.combo_typ.addItems(typy_narzedzi)

        cancel_button = QPushButton("Cofnij")
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(cancel_button)

        l_h = QHBoxLayout()
        l_h.addWidget(self.lbl_typ)
        l_h.addWidget(self.combo_typ)

        l_h2 = QHBoxLayout()
        l_h2.addWidget(self.lbl_wysz)
        l_h2.addWidget(self.edit_wysz)

        layout_v = QVBoxLayout()
        layout_v.addLayout(l_h)
        layout_v.addLayout(l_h2)
        layout_v.addWidget(self.table)

        self.proxy.setSourceModel(self.model)
        self.table.setModel(self.proxy)

        main_layout = QVBoxLayout()
        self.formularz.setLayout(layout_v)
        main_layout.addWidget(self.formularz)
        main_layout.addLayout(hbox)
        self.setLayout(main_layout)

        cancel_button.clicked.connect(self.anulowanie)
        self.edit_wysz.textChanged.connect(self.wyszukiwanie)
        self.combo_typ.activated[str].connect(self.onActiveNarz)
        # Menu kontekstowe własne
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.prawoklik)

    def prawoklik(self):
        menu = QMenu(self)
        if self.model.rowCount():
            akcja = QAction('Usuń narzędzie', self)
            akcja.triggered.connect(self.usun_wiersz)
            menu.addAction(akcja)
            menu.exec_(QCursor.pos())

    def usun_wiersz(self):
        ok = QMessageBox.question(self, 'Potwierdzenie',
                                  'Czy na pewno chcesz usunąć narzędzie?',
                                  QMessageBox.Ok, QMessageBox.Cancel)
        if ok == QMessageBox.Ok:
            selected = self.table.currentIndex()
            self.model.removeRow(selected.row())
            self.model.submitAll()
            self.model.select()
            self.parent.statusBar().showMessage("Usunięto narzędzie", 10000)

    def onActiveNarz(self, tekst):
        slownik = {
            'Frez palcowy': 'frezy_palcowe',
            'Frez płytkowy (głowica)': 'frezy_plytkowe',
            'Gwintownik': 'gwintowniki',
            'Nóż tokarski': 'noze_tokarskie',
            'Oprawka': 'oprawki',
            'Piła': 'pily',
            'Pozostałe': 'pozostale',
            'Rozwiertak': 'rozwiertaki',
            'Wiertło': 'wiertla',
            'Wiertło składane': 'wiertla_skladane',
            'Wygniatak': 'wygniataki',
            'Brak': ''
        }
        naglowki = {
            'idfrezy_palcowe': 'ID',
            'symbol_freza': 'Symbol',
            'producent_fr': 'Producent',
            'srednica_fr': 'Średnica',
            'dl_fr': 'Długość całkowita',
            'dl_rob_fr': 'Długość robocza',
            'idfrezy_plytkowe': 'ID',
            'symbol_frez_pl': 'Symbol',
            'producent_fp': 'Producent',
            'srednica_fr_pl': 'Średnica',
            'ilosc_plytek': 'Ilość płytek',
            'symbol_pl': 'Symbol płytek',
            'ilosc_krawedzi_pl': 'Ilość krawędzi płytki',
            'idgwintowniki': 'ID',
            'symbol_g': 'Symbol',
            'producent_gw': 'Producent',
            'rozmiar_gwintu': 'Rozmiar gwintu i skok',
            'typ_gwintownika': 'Typ gwintownika',
            'idnoze_tokarskie': 'ID',
            'symbol_n': 'Symbol',
            'producent_n': 'Producent',
            'plytki_n': 'Symbol płytek',
            'ilosc_krawedzi_pl_n': 'Ilość krawędzi',
            'idpily': 'ID',
            'symbol_p': 'Symbol',
            'producent_pil': 'Producent',
            'srednica_p': 'Średnica',
            'grubosc_p': 'Grubość',
            'rodzaj_pl_p': 'Symbol płytek',
            'ilosc_pl_p': 'Ilość płytek',
            'ilosc_kraw_p': 'Ilość krawędzi płytki',
            'idpozostale': 'ID',
            'symbol_poz': 'Symbol',
            'producent_poz': 'Producent',
            'srednica_poz': 'Średnica',
            'ilosc_pl_poz': 'Ilość płytek',
            'plytki_poz': 'Symbol płytek',
            'idrozwiertaki': 'ID',
            'symbol_r': 'Symbol',
            'producent_roz': 'Producent',
            'rozmiar_r': 'Rozmiar',
            'idwiertla': 'ID',
            'symbol_w': 'Symbol',
            'producent_w': 'Producent',
            'srednica_w': 'Średnica',
            'dlugosc_w': 'Długość [mm]',
            'idwiertla_skladane': 'ID',
            'symbol_w_skl': 'Symbol',
            'producent_ws': 'Producent',
            'srednica_w_skl': 'Średnica',
            'plytki_w_skl': 'Symbol płytek',
            'idwygniataki': 'ID',
            'symbol_wyg': 'Symbol',
            'producent_wyg': 'Producent',
            'rozmiar_gw': 'Rozmiar gwintu'
        }
        self.model.setTable(slownik[tekst])
        self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.model.select()

        # Ustawianie nagłówków
        ilosc_kolumn = self.model.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model.headerData(i, Qt.Horizontal)
            self.model.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn])

    @pyqtSlot(str)
    def wyszukiwanie(self, text):
        search = QRegExp(text,
                         Qt.CaseInsensitive,
                         QRegExp.RegExp
                         )
        self.proxy.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy.setFilterKeyColumn(-1)

    def widok(self):
        # Ustawianie własciwości widoku
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.verticalHeader().setVisible(False)
        self.table.setSortingEnabled(True)
        self.table.setModel(self.model)

    def anulowanie(self):
        self.parent.statusBar().clearMessage()
        from opcje_qt import Wewnatrz
        menu_gl = Wewnatrz(self.parent)
        self.parent.setCentralWidget(menu_gl)
Exemplo n.º 25
0
class FontViewWidget(QWidget):
    def __init__(self, statusBar, config, *args, **kwargs):
        super(FontViewWidget, self).__init__(*args, **kwargs)
        self.statusBar = statusBar
        layout = QVBoxLayout(self)
        self.retButton = QToolButton(self)
        self.retButton.setIconSize(QSize(60, 60))
        self.retButton.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.retButton.setMinimumSize(200, 100)
        self.retButton.setMaximumSize(200, 100)
        layout.addWidget(self.retButton)
        # 过滤输入框
        layout.addWidget(
            QLineEdit(self, textChanged=self.doFilter,
                      placeholderText='过滤...'))
        # Material Font
        self.listView = QListView(self)
        self.listView.setMouseTracking(True)
        self.listView.setViewMode(QListView.IconMode)
        self.listView.setMovement(QListView.Static)
        self.listView.setFlow(QListView.LeftToRight)
        self.listView.setWrapping(True)
        self.listView.setEditTriggers(QListView.NoEditTriggers)
        self.listView.setResizeMode(QListView.Adjust)
        self.listView.doubleClicked.connect(self.onDoubleClicked)
        self.listView.entered.connect(self.onEntered)
        self.dmodel = QStandardItemModel(self.listView)
        self.fmodel = QSortFilterProxyModel(self.listView)
        self.fmodel.setSourceModel(self.dmodel)
        self.fmodel.setFilterRole(Qt.ToolTipRole)
        self.listView.setModel(self.fmodel)
        layout.addWidget(self.listView)

        # 字体加载器
        loader = config[0]

        # 添加Item
        fontMap = json.loads(open(config[1],
                                  'rb').read().decode(encoding='utf_8',
                                                      errors='ignore'),
                             encoding='utf_8')
        for name, _ in fontMap.items():
            item = QStandardItem(loader.icon(name), '')
            item.setData(name, Qt.ToolTipRole)
            item.setData(name, Qt.StatusTipRole)
            item.setTextAlignment(Qt.AlignCenter)
            item.setFlags(item.flags())
            self.dmodel.appendRow(item)

    def doFilter(self, _):
        self.fmodel.setFilterRegExp(self.sender().text())

    def onEntered(self, index):
        index = self.fmodel.mapToSource(index)
        text = index.data(Qt.ToolTipRole)
        if text:
            self.retButton.setText(text)
            self.retButton.setIcon(self.dmodel.itemFromIndex(index).icon())

    def onDoubleClicked(self, index):
        index = self.fmodel.mapToSource(index)
        text = index.data(Qt.ToolTipRole)
        if text:
            QApplication.clipboard().setText(text)
            self.statusBar.showMessage('已复制: %s' % text)
Exemplo n.º 26
0
class CreateDialogCodeDialog(QDialog, Ui_CreateDialogCodeDialog):
    """
    Class implementing a dialog to generate code for a Qt4/Qt5 dialog.
    """
    DialogClasses = {
        "QDialog", "QWidget", "QMainWindow", "QWizard", "QWizardPage",
        "QDockWidget", "QFrame", "QGroupBox", "QScrollArea", "QMdiArea",
        "QTabWidget", "QToolBox", "QStackedWidget"
    }
    Separator = 25 * "="
    
    def __init__(self, formName, project, parent=None):
        """
        Constructor
        
        @param formName name of the file containing the form (string)
        @param project reference to the project object
        @param parent parent widget if the dialog (QWidget)
        """
        super(CreateDialogCodeDialog, self).__init__(parent)
        self.setupUi(self)
        
        self.okButton = self.buttonBox.button(QDialogButtonBox.Ok)
        
        self.slotsView.header().hide()
        
        self.project = project
        
        self.formFile = formName
        filename, ext = os.path.splitext(self.formFile)
        self.srcFile = '{0}{1}'.format(
            filename, self.project.getDefaultSourceExtension())
        
        self.slotsModel = QStandardItemModel()
        self.proxyModel = QSortFilterProxyModel()
        self.proxyModel.setDynamicSortFilter(True)
        self.proxyModel.setSourceModel(self.slotsModel)
        self.slotsView.setModel(self.proxyModel)
        
        # initialize some member variables
        self.__initError = False
        self.__module = None
        
        if os.path.exists(self.srcFile):
            vm = e5App().getObject("ViewManager")
            ed = vm.getOpenEditor(self.srcFile)
            if ed and not vm.checkDirty(ed):
                self.__initError = True
                return
            
            try:
                splitExt = os.path.splitext(self.srcFile)
                if len(splitExt) == 2:
                    exts = [splitExt[1]]
                else:
                    exts = None
                from Utilities import ModuleParser
                self.__module = ModuleParser.readModule(
                    self.srcFile, extensions=exts, caching=False)
            except ImportError:
                pass
        
        if self.__module is not None:
            self.filenameEdit.setText(self.srcFile)
            
            classesList = []
            vagueClassesList = []
            for cls in list(self.__module.classes.values()):
                if not set(cls.super).isdisjoint(
                        CreateDialogCodeDialog.DialogClasses):
                    classesList.append(cls.name)
                else:
                    vagueClassesList.append(cls.name)
            classesList.sort()
            self.classNameCombo.addItems(classesList)
            if vagueClassesList:
                if classesList:
                    self.classNameCombo.addItem(
                        CreateDialogCodeDialog.Separator)
                self.classNameCombo.addItems(sorted(vagueClassesList))
        
        if os.path.exists(self.srcFile) and \
           self.__module is not None and \
           self.classNameCombo.count() == 0:
            self.__initError = True
            E5MessageBox.critical(
                self,
                self.tr("Create Dialog Code"),
                self.tr(
                    """The file <b>{0}</b> exists but does not contain"""
                    """ any classes.""").format(self.srcFile))
        
        self.okButton.setEnabled(self.classNameCombo.count() > 0)
        
        self.__updateSlotsModel()
        
    def initError(self):
        """
        Public method to determine, if there was an initialzation error.
        
        @return flag indicating an initialzation error (boolean)
        """
        return self.__initError
        
    def __objectName(self):
        """
        Private method to get the object name of the dialog.
        
        @return object name (string)
        """
        try:
            dlg = uic.loadUi(
                self.formFile, package=self.project.getProjectPath())
            return dlg.objectName()
        except (AttributeError, ImportError,
                xml.etree.ElementTree.ParseError) as err:
            E5MessageBox.critical(
                self,
                self.tr("uic error"),
                self.tr(
                    """<p>There was an error loading the form <b>{0}</b>"""
                    """.</p><p>{1}</p>""").format(self.formFile, str(err)))
            return ""
        
    def __className(self):
        """
        Private method to get the class name of the dialog.
        
        @return class name (sting)
        """
        try:
            dlg = uic.loadUi(
                self.formFile, package=self.project.getProjectPath())
            return dlg.metaObject().className()
        except (AttributeError, ImportError,
                xml.etree.ElementTree.ParseError) as err:
            E5MessageBox.critical(
                self,
                self.tr("uic error"),
                self.tr(
                    """<p>There was an error loading the form <b>{0}</b>"""
                    """.</p><p>{1}</p>""").format(self.formFile, str(err)))
            return ""
        
    def __signatures(self):
        """
        Private slot to get the signatures.
        
        @return list of signatures (list of strings)
        """
        if self.__module is None:
            return []
            
        signatures = []
        clsName = self.classNameCombo.currentText()
        if clsName:
            cls = self.__module.classes[clsName]
            for meth in list(cls.methods.values()):
                if meth.name.startswith("on_"):
                    if meth.pyqtSignature is not None:
                        sig = ", ".join(
                            [bytes(QMetaObject.normalizedType(t)).decode()
                             for t in meth.pyqtSignature.split(",")])
                        signatures.append("{0}({1})".format(meth.name, sig))
                    else:
                        signatures.append(meth.name)
        return signatures
        
    def __mapType(self, type_):
        """
        Private method to map a type as reported by Qt's meta object to the
        correct Python type.
        
        @param type_ type as reported by Qt (QByteArray)
        @return mapped Python type (string)
        """
        mapped = bytes(type_).decode()
        
        if self.project.getProjectLanguage() != "Python2" or \
           self.project.getProjectType == "PySide":
            # 1. check for const
            mapped = mapped.replace("const ", "")
            
            # 2. check for *
            mapped = mapped.replace("*", "")
            
            # 3. replace QString and QStringList
            mapped = mapped.replace("QStringList", "list")\
                           .replace("QString", "str")
            
            # 4. replace double by float
            mapped = mapped.replace("double", "float")
        
        return mapped
        
    def __updateSlotsModel(self):
        """
        Private slot to update the slots tree display.
        """
        self.filterEdit.clear()
        
        try:
            dlg = uic.loadUi(
                self.formFile, package=self.project.getProjectPath())
            objects = dlg.findChildren(QWidget) + dlg.findChildren(QAction)
            
            signatureList = self.__signatures()
            
            self.slotsModel.clear()
            self.slotsModel.setHorizontalHeaderLabels([""])
            for obj in objects:
                name = obj.objectName()
                if not name or name.startswith("qt_"):
                    # ignore un-named or internal objects
                    continue
                
                metaObject = obj.metaObject()
                className = metaObject.className()
                itm = QStandardItem("{0} ({1})".format(name, className))
                self.slotsModel.appendRow(itm)
                for index in range(metaObject.methodCount()):
                    metaMethod = metaObject.method(index)
                    if metaMethod.methodType() == QMetaMethod.Signal:
                        if qVersion() >= "5.0.0":
                            itm2 = QStandardItem("on_{0}_{1}".format(
                                name,
                                bytes(metaMethod.methodSignature()).decode()))
                        else:
                            itm2 = QStandardItem("on_{0}_{1}".format(
                                name, metaMethod.signature()))
                        itm.appendRow(itm2)
                        if self.__module is not None:
                            if qVersion() >= "5.0.0":
                                method = "on_{0}_{1}".format(
                                    name,
                                    bytes(metaMethod.methodSignature())
                                    .decode().split("(")[0])
                            else:
                                method = "on_{0}_{1}".format(
                                    name, metaMethod.signature().split("(")[0])
                            method2 = "{0}({1})".format(
                                method, ", ".join(
                                    [self.__mapType(t)
                                     for t in metaMethod.parameterTypes()]))
                            
                            if method2 in signatureList or \
                                    method in signatureList:
                                itm2.setFlags(Qt.ItemFlags(Qt.ItemIsEnabled))
                                itm2.setCheckState(Qt.Checked)
                                itm2.setForeground(QBrush(Qt.blue))
                                continue
                        
                        returnType = self.__mapType(
                            metaMethod.typeName().encode())
                        if returnType == 'void':
                            returnType = ""
                        parameterTypesList = [
                            self.__mapType(t)
                            for t in metaMethod.parameterTypes()]
                        pyqtSignature = ", ".join(parameterTypesList)
                        
                        parameterNames = metaMethod.parameterNames()
                        if parameterNames:
                            for index in range(len(parameterNames)):
                                if not parameterNames[index]:
                                    parameterNames[index] = \
                                        QByteArray("p{0:d}".format(index)
                                                   .encode("utf-8"))
                        parameterNamesList = [bytes(n).decode()
                                              for n in parameterNames]
                        methNamesSig = ", ".join(parameterNamesList)
                        
                        if methNamesSig:
                            if qVersion() >= "5.0.0":
                                pythonSignature = \
                                    "on_{0}_{1}(self, {2})".format(
                                        name,
                                        bytes(metaMethod.methodSignature())
                                        .decode().split("(")[0],
                                        methNamesSig)
                            else:
                                pythonSignature = \
                                    "on_{0}_{1}(self, {2})".format(
                                        name,
                                        metaMethod.signature().split("(")[0],
                                        methNamesSig)
                        else:
                            if qVersion() >= "5.0.0":
                                pythonSignature = "on_{0}_{1}(self)".format(
                                    name,
                                    bytes(metaMethod.methodSignature())
                                    .decode().split("(")[0])
                            else:
                                pythonSignature = "on_{0}_{1}(self)".format(
                                    name,
                                    metaMethod.signature().split("(")[0])
                        itm2.setData(pyqtSignature, pyqtSignatureRole)
                        itm2.setData(pythonSignature, pythonSignatureRole)
                        itm2.setData(returnType, returnTypeRole)
                        itm2.setData(parameterTypesList,
                                     parameterTypesListRole)
                        itm2.setData(parameterNamesList,
                                     parameterNamesListRole)
                        
                        itm2.setFlags(Qt.ItemFlags(
                            Qt.ItemIsUserCheckable |
                            Qt.ItemIsEnabled |
                            Qt.ItemIsSelectable)
                        )
                        itm2.setCheckState(Qt.Unchecked)
            
            self.slotsView.sortByColumn(0, Qt.AscendingOrder)
        except (AttributeError, ImportError,
                xml.etree.ElementTree.ParseError) as err:
            E5MessageBox.critical(
                self,
                self.tr("uic error"),
                self.tr(
                    """<p>There was an error loading the form <b>{0}</b>"""
                    """.</p><p>{1}</p>""").format(self.formFile, str(err)))
        
    def __generateCode(self):
        """
        Private slot to generate the code as requested by the user.
        """
        # first decide on extension
        if self.filenameEdit.text().endswith(".py") or \
           self.filenameEdit.text().endswith(".pyw"):
            self.__generatePythonCode()
        elif self.filenameEdit.text().endswith(".rb"):
            pass
        # second decide on project language
        elif self.project.getProjectLanguage() in ["Python2", "Python3"]:
            self.__generatePythonCode()
        elif self.project.getProjectLanguage() == "Ruby":
            pass
        else:
            # assume Python (our global default)
            self.__generatePythonCode()
        
    def __generatePythonCode(self):
        """
        Private slot to generate Python code as requested by the user.
        """
        # init some variables
        sourceImpl = []
        appendAtIndex = -1
        indentStr = "    "
        slotsCode = []
        
        if self.__module is None:
            # new file
            try:
                if self.project.getProjectLanguage() == "Python2":
                    if self.project.getProjectType() == "PySide":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyside.py2.tmpl")
                    elif self.project.getProjectType() == "PyQt5":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt5.py2.tmpl")
                    else:
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt.py2.tmpl")
                else:
                    if self.project.getProjectType() == "PySide":
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyside.py.tmpl")
                    elif self.project.getProjectType() in [
                            "PyQt5", "E6Plugin"]:
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt5.py.tmpl")
                    else:
                        tmplName = os.path.join(
                            getConfig('ericCodeTemplatesDir'),
                            "impl_pyqt.py.tmpl")
                tmplFile = open(tmplName, 'r', encoding="utf-8")
                template = tmplFile.read()
                tmplFile.close()
            except IOError as why:
                E5MessageBox.critical(
                    self,
                    self.tr("Code Generation"),
                    self.tr(
                        """<p>Could not open the code template file"""
                        """ "{0}".</p><p>Reason: {1}</p>""")
                    .format(tmplName, str(why)))
                return
            
            objName = self.__objectName()
            if objName:
                template = template\
                    .replace(
                        "$FORMFILE$",
                        os.path.splitext(os.path.basename(self.formFile))[0])\
                    .replace("$FORMCLASS$", objName)\
                    .replace("$CLASSNAME$", self.classNameCombo.currentText())\
                    .replace("$SUPERCLASS$", self.__className())
                
                sourceImpl = template.splitlines(True)
                appendAtIndex = -1
                
                # determine indent string
                for line in sourceImpl:
                    if line.lstrip().startswith("def __init__"):
                        indentStr = line.replace(line.lstrip(), "")
                        break
        else:
            # extend existing file
            try:
                srcFile = open(self.srcFile, 'r', encoding="utf-8")
                sourceImpl = srcFile.readlines()
                srcFile.close()
                if not sourceImpl[-1].endswith("\n"):
                    sourceImpl[-1] = "{0}{1}".format(sourceImpl[-1], "\n")
            except IOError as why:
                E5MessageBox.critical(
                    self,
                    self.tr("Code Generation"),
                    self.tr(
                        """<p>Could not open the source file "{0}".</p>"""
                        """<p>Reason: {1}</p>""")
                    .format(self.srcFile, str(why)))
                return
            
            cls = self.__module.classes[self.classNameCombo.currentText()]
            if cls.endlineno == len(sourceImpl) or cls.endlineno == -1:
                appendAtIndex = -1
                # delete empty lines at end
                while not sourceImpl[-1].strip():
                    del sourceImpl[-1]
            else:
                appendAtIndex = cls.endlineno - 1
                while not sourceImpl[appendAtIndex].strip():
                    appendAtIndex -= 1
                appendAtIndex += 1
            
            # determine indent string
            for line in sourceImpl[cls.lineno:cls.endlineno + 1]:
                if line.lstrip().startswith("def __init__"):
                    indentStr = line.replace(line.lstrip(), "")
                    break
        
        # do the coding stuff
        if self.project.getProjectLanguage() == "Python2":
            if self.project.getProjectType() == "PySide":
                pyqtSignatureFormat = '@Slot({0})'
            elif self.project.getProjectType() == "PyQt5":
                pyqtSignatureFormat = '@pyqtSlot({0})'
            else:
                pyqtSignatureFormat = '@pyqtSignature("{0}")'
        else:
            if self.project.getProjectType() == "PySide":
                pyqtSignatureFormat = '@Slot({0})'
            else:
                pyqtSignatureFormat = '@pyqtSlot({0})'
        for row in range(self.slotsModel.rowCount()):
            topItem = self.slotsModel.item(row)
            for childRow in range(topItem.rowCount()):
                child = topItem.child(childRow)
                if child.checkState() and \
                   child.flags() & Qt.ItemFlags(Qt.ItemIsUserCheckable):
                    slotsCode.append('{0}\n'.format(indentStr))
                    slotsCode.append('{0}{1}\n'.format(
                        indentStr,
                        pyqtSignatureFormat.format(
                            child.data(pyqtSignatureRole))))
                    slotsCode.append('{0}def {1}:\n'.format(
                        indentStr, child.data(pythonSignatureRole)))
                    indentStr2 = indentStr * 2
                    slotsCode.append('{0}"""\n'.format(indentStr2))
                    slotsCode.append(
                        '{0}Slot documentation goes here.\n'.format(
                            indentStr2))
                    if child.data(returnTypeRole) or \
                            child.data(parameterTypesListRole):
                        slotsCode.append('{0}\n'.format(indentStr2))
                        if child.data(parameterTypesListRole):
                            for name, type_ in zip(
                                child.data(parameterNamesListRole),
                                    child.data(parameterTypesListRole)):
                                slotsCode.append(
                                    '{0}@param {1} DESCRIPTION\n'.format(
                                        indentStr2, name))
                                slotsCode.append('{0}@type {1}\n'.format(
                                    indentStr2, type_))
                        if child.data(returnTypeRole):
                            slotsCode.append(
                                '{0}@returns DESCRIPTION\n'.format(
                                    indentStr2))
                            slotsCode.append('{0}@rtype {1}\n'.format(
                                indentStr2, child.data(returnTypeRole)))
                    slotsCode.append('{0}"""\n'.format(indentStr2))
                    slotsCode.append('{0}# {1}: not implemented yet\n'.format(
                        indentStr2, "TODO"))
                    slotsCode.append('{0}raise NotImplementedError\n'.format(
                        indentStr2))
        
        if appendAtIndex == -1:
            sourceImpl.extend(slotsCode)
        else:
            sourceImpl[appendAtIndex:appendAtIndex] = slotsCode
        
        # write the new code
        try:
            if self.project.useSystemEol():
                newline = None
            else:
                newline = self.project.getEolString()
            srcFile = open(self.filenameEdit.text(), 'w', encoding="utf-8",
                           newline=newline)
            srcFile.write("".join(sourceImpl))
            srcFile.close()
        except IOError as why:
            E5MessageBox.critical(
                self,
                self.tr("Code Generation"),
                self.tr("""<p>Could not write the source file "{0}".</p>"""
                        """<p>Reason: {1}</p>""")
                .format(self.filenameEdit.text(), str(why)))
            return
        
        self.project.appendFile(self.filenameEdit.text())
        
    @pyqtSlot(int)
    def on_classNameCombo_activated(self, index):
        """
        Private slot to handle the activated signal of the classname combo.
        
        @param index index of the activated item (integer)
        """
        if (self.classNameCombo.currentText() ==
                CreateDialogCodeDialog.Separator):
            self.okButton.setEnabled(False)
            self.filterEdit.clear()
            self.slotsModel.clear()
            self.slotsModel.setHorizontalHeaderLabels([""])
        else:
            self.okButton.setEnabled(True)
            self.__updateSlotsModel()
        
    def on_filterEdit_textChanged(self, text):
        """
        Private slot called, when thext of the filter edit has changed.
        
        @param text changed text (string)
        """
        re = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp2)
        self.proxyModel.setFilterRegExp(re)
        
    @pyqtSlot()
    def on_newButton_clicked(self):
        """
        Private slot called to enter the data for a new dialog class.
        """
        path, file = os.path.split(self.srcFile)
        objName = self.__objectName()
        if objName:
            dlg = NewDialogClassDialog(objName, file, path, self)
            if dlg.exec_() == QDialog.Accepted:
                className, fileName = dlg.getData()
                
                self.classNameCombo.clear()
                self.classNameCombo.addItem(className)
                self.srcFile = fileName
                self.filenameEdit.setText(self.srcFile)
                self.__module = None
            
            self.okButton.setEnabled(self.classNameCombo.count() > 0)
        
    def on_buttonBox_clicked(self, button):
        """
        Private slot to handle the buttonBox clicked signal.
        
        @param button reference to the button that was clicked
            (QAbstractButton)
        """
        if button == self.okButton:
            self.__generateCode()
            self.accept()
Exemplo n.º 27
0
class FileChooser(BaseFileChooser):
	def __init__(self, **kwargs):
		super(FileChooser, self).__init__(**kwargs)

		self.options = PropDict()

		self.edit.textEdited.connect(self._onTextEdited)

		self.view.activated.connect(self._onActivated)

		# models
		self.rootChanger = RootChangerProxy()

		fsModel = QFileSystemModel(self)
		self.setModel(fsModel)

		self.filter = QSortFilterProxyModel()
		self.filter.setSourceModel(self.rootChanger)
		self.view.setModel(self.filter)

	def setModel(self, model):
		self.baseModel = model
		self.rootChanger.setSourceModel(self.baseModel)

	@Slot(str)
	def setRoot(self, path):
		self.root = path
		srcIdx = self.baseModel.setRootPath(path)
		self.rootChanger.setRootSource(srcIdx)
		self.view.setRootIndex(QModelIndex())

	@Slot(str)
	def _onTextEdited(self, txt):
		elems = txt.rsplit('/', 1)
		if len(elems) == 2:
			dir, base = elems
		else:
			dir, base = '', elems[0]

		path = os.path.join(self.root, dir)
		self.rootChanger.setRootSource(self.baseModel.index(path))
		self.filter.setFilterRegExp(QRegExp(base, Qt.CaseInsensitive, QRegExp.Wildcard))

		if self.options.get('autosuggest'):
			names = [self.filter.data(self.filter.index(i, 0)).toString()
				 for i in range(self.filter.rowCount(QModelIndex()))]
			names = [n[len(base):] for n in names]
			add = commonPrefix(names)

			cursor = self.edit.cursorPosition()
			self.edit.setText(self.edit.text()[:cursor] + add)
			self.edit.setSelection(cursor, len(self.edit.text()))

	@Slot(QModelIndex)
	def _onActivated(self, idx):
		idx = self.filter.mapToSource(idx)
		idx = self.rootChanger.mapToSource(idx)
		info = self.baseModel.fileInfo(idx)
		if info.isDir():
			return
		path = info.absoluteFilePath()
		self.openFile(path)
Exemplo n.º 28
0
class Reservations(QWidget):
    """
    Klasa odpowiedzialna za widget klienci
    """
    def __init__(self, parent, db):
        super(QWidget, self).__init__(parent)
        self.parent = parent
        self.btn_mod = QPushButton('Zmiana statusu')
        self.btn_usun = QPushButton('Usuń')
        self.btn_dodaj = QPushButton('Dodaj')
        self.lbl_klient_ = QLabel('')
        self.lbl_usluga_ = QLabel('')
        self.lbl_termin_ = QDateTimeEdit()
        self.gb_layout = QVBoxLayout()
        self.kalendarz = QCalendarWidget()
        self.view_u = QTableView()
        self.view_k = QTableView()
        self.view_p = QTableView()
        self.view = QTableView()
        self.proxy_u = QSortFilterProxyModel(self)
        self.proxy_k = QSortFilterProxyModel(self)
        self.proxy_p = QSortFilterProxyModel(self)
        self.proxy = QSortFilterProxyModel(self)
        self.id_klient = -1
        self.id_usluga = -1
        self.id_pracownik = -1
        self.id_rezerwacje = -1
        self.data = None
        self.data_do = None
        self.dzien_tyg = 0
        self.czas = []

        # Lista składana przycisków godzin
        self.btn_godz = [QPushButton(str(i + 1)) for i in range(16)]

        # Parametry połączenia z bazą
        self.model_u = QSqlTableModel(self, db)
        self.model_k = QSqlTableModel(self, db)
        self.model_p = QSqlTableModel(self, db)
        self.model = QSqlTableModel(self, db)

        self.initUI()

    def initUI(self):
        """
        Inicjuje UI
        """
        self.view_u.setObjectName('Usługi')
        self.view_k.setObjectName('Klienci')
        self.view_p.setObjectName('Pracownicy')
        self.view.setObjectName('Rezerwacje')
        self.table_init_u()
        self.table_init_k()
        self.table_init_p()
        self.table_init()
        self.btn_mod.setDisabled(True)
        self.btn_usun.setDisabled(True)
        self.btn_dodaj.setDisabled(True)

        # Tworzenie kontrolek
        lbl_wysz_u = QLabel('Wyszukaj usługę:')
        lbl_wysz_k = QLabel('Wyszukaj klienta:')
        lbl_wysz_p = QLabel('Wyszukaj pracownika:')
        txt_wysz_u = QLineEdit(self)
        txt_wysz_k = QLineEdit(self)
        txt_wysz_p = QLineEdit(self)
        lbl_klient = QLabel('Klient:')
        lbl_usluga = QLabel('Usługa:')
        lbl_termin = QLabel('Termin:')

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.kalendarz.sizePolicy().hasHeightForWidth())
        self.kalendarz.setSizePolicy(sizePolicy)

        # Tworzenie widoków
        centralbox = QHBoxLayout()
        hbox_wysz_u = QHBoxLayout()
        hbox_wysz_k = QHBoxLayout()
        hbox_wysz_p = QHBoxLayout()
        vbox_u = QVBoxLayout()
        vbox_k = QVBoxLayout()
        vbox_p = QVBoxLayout()
        vbox_right = QVBoxLayout()
        hbox_btn = QHBoxLayout()
        hbox_k = QHBoxLayout()
        hbox_u = QHBoxLayout()
        hbox_t = QHBoxLayout()
        vbox_cal = QVBoxLayout()
        groupbox = QGroupBox('Godziny:')
        groupbox.setLayout(self.gb_layout)
        hbox_left = QHBoxLayout()

        # Metody
        self.lbl_termin_.setCalendarWidget(self.kalendarz)
        self.lbl_termin_.setDate(self.kalendarz.selectedDate())
        self.dzien_tyg = self.kalendarz.selectedDate().dayOfWeek()
        txt_wysz_u.textChanged.connect(self.searching_u)
        txt_wysz_k.textChanged.connect(self.searching_k)
        txt_wysz_p.textChanged.connect(self.searching_p)
        self.view_k.clicked.connect(lambda: self.clicked_table(self.view_k))
        self.view_p.clicked.connect(lambda: self.clicked_table(self.view_p))
        self.view_u.clicked.connect(lambda: self.clicked_table(self.view_u))
        self.view.clicked.connect(lambda: self.clicked_table(self.view))
        self.kalendarz.clicked.connect(self.show_data)
        self.btn_dodaj.clicked.connect(self.add)
        self.btn_mod.clicked.connect(self.modify)
        self.btn_usun.clicked.connect(self.remove)

        # Ustawianie widoków
        hbox_wysz_k.addWidget(lbl_wysz_k)
        hbox_wysz_k.addWidget(txt_wysz_k)
        hbox_wysz_p.addWidget(lbl_wysz_p)
        hbox_wysz_p.addWidget(txt_wysz_p)
        hbox_wysz_u.addWidget(lbl_wysz_u)
        hbox_wysz_u.addWidget(txt_wysz_u)
        vbox_u.addLayout(hbox_wysz_u)
        vbox_u.addWidget(self.view_u)
        vbox_k.addLayout(hbox_wysz_k)
        vbox_k.addWidget(self.view_k)
        vbox_p.addLayout(hbox_wysz_p)
        vbox_p.addWidget(self.view_p)
        vbox_right.addLayout(vbox_p)
        vbox_right.addLayout(vbox_u)
        vbox_right.addLayout(vbox_k)
        hbox_btn.addWidget(self.btn_usun)
        hbox_btn.addWidget(self.btn_mod)
        hbox_k.addWidget(lbl_klient)
        hbox_k.addWidget(self.lbl_klient_)
        hbox_u.addWidget(lbl_usluga)
        hbox_u.addWidget(self.lbl_usluga_)
        hbox_t.addWidget(lbl_termin)
        hbox_t.addWidget(self.lbl_termin_)
        vbox_cal.addWidget(self.kalendarz)
        vbox_cal.addLayout(hbox_u)
        vbox_cal.addLayout(hbox_t)
        vbox_cal.addLayout(hbox_k)
        self.view.setSizePolicy(
            QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum))
        vbox_cal.addWidget(self.view)
        vbox_cal.addLayout(hbox_btn)
        vbox_cal.addWidget(self.btn_dodaj)
        hbox_left.addLayout(vbox_cal)
        hbox_left.addWidget(groupbox)
        centralbox.addLayout(hbox_left)
        centralbox.addLayout(vbox_right)

        self.setLayout(centralbox)
        self.show()

    def show_data(self):
        self.lbl_termin_.setDate(self.kalendarz.selectedDate())
        self.dzien_tyg = self.kalendarz.selectedDate().dayOfWeek()
        self.clicked_table(self.view_p)

    def table_init_u(self):
        """
        Inicjuje wygląd tabeli usługi
        """
        # self.model_u.setTable('uslugi')
        query = QSqlQuery(
            'SELECT uslugi.uslugi_id, uslugi.nazwa, uslugi.cena, date_format(uslugi.czas, "%H:%i") AS czas FROM uslugi NATURAL JOIN uzytkownik_usluga WHERE uzytkownik_usluga.uzytkownik_id = '
            + str(self.id_pracownik) + ';')
        self.model_u.setQuery(query)
        # self.model_u.select()

        self.proxy_u.setSourceModel(self.model_u)

        naglowki = {
            'uslugi_id': 'ID',
            'nazwa': 'Nazwa',
            'cena': 'Cena',
            "czas": 'Czas',
        }
        # Ustawianie nagłówków
        ilosc_kolumn = self.model_u.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model_u.headerData(i, Qt.Horizontal)
            self.model_u.setHeaderData(i, Qt.Horizontal,
                                       naglowki[nazwa_kolumn])

        self.view_u.setSizeAdjustPolicy(
            QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.view_u.setSortingEnabled(True)
        self.view_u.setAlternatingRowColors(True)

        # Wczytanie danych
        self.view_u.setModel(self.proxy_u)
        self.view_u.hideColumn(0)
        self.view_u.sortByColumn(1, Qt.AscendingOrder)
        self.view_u.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def table_init_k(self):
        """
        Inicjuje wygląd tabeli klienta
        """
        self.model_k.setTable('klienci')
        query = QSqlQuery(
            'SELECT klienci_id, imie, nazwisko, email, telefon, ulica, numer_mieszkania, miejscowosc, poczta FROM '
            'klienci;')
        self.model_k.setQuery(query)
        # self.model_k.select()

        self.proxy_k.setSourceModel(self.model_k)

        naglowki = {
            'klienci_id': 'ID',
            'imie': 'Imię',
            'nazwisko': 'Nazwisko',
            "email": 'Email',
            'telefon': 'Telefon',
            'ulica': 'Ulica',
            'numer_mieszkania': 'Numer mieszkania',
            'miejscowosc': 'Miejscowosc',
            'poczta': 'Kod pocztowy',
        }
        # Ustawianie nagłówków
        ilosc_kolumn = self.model_k.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model_k.headerData(i, Qt.Horizontal)
            self.model_k.setHeaderData(i, Qt.Horizontal,
                                       naglowki[nazwa_kolumn])

        self.view_k.setSizeAdjustPolicy(
            QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.view_k.setSortingEnabled(True)
        self.view_k.setAlternatingRowColors(True)

        # Wczytanie danych
        self.view_k.setModel(self.proxy_k)
        self.view_k.hideColumn(0)
        self.view_k.sortByColumn(1, Qt.AscendingOrder)
        self.view_k.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def table_init_p(self):
        """
        Inicjuje wygląd tabeli pracownik
        """
        self.model_p.setTable('uzytkownik')
        query = QSqlQuery(
            'SELECT uzytkownik_id,  imie, nazwisko FROM uzytkownik WHERE '
            'pracownik = 1;')
        self.model_p.setQuery(query)
        # self.model_p.select()

        self.proxy_p.setSourceModel(self.model_p)

        naglowki = {
            'uzytkownik_id': 'ID',
            'imie': 'Imię',
            "nazwisko": 'Nazwisko',
        }
        # Ustawianie nagłówków
        ilosc_kolumn = self.model_p.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model_p.headerData(i, Qt.Horizontal)
            self.model_p.setHeaderData(i, Qt.Horizontal,
                                       naglowki[nazwa_kolumn])

        self.view_p.setSizeAdjustPolicy(
            QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.view_p.setSortingEnabled(True)
        self.view_p.setAlternatingRowColors(True)

        # Wczytanie danych
        self.view_p.setModel(self.proxy_p)
        self.view_p.hideColumn(0)
        self.view_p.sortByColumn(1, Qt.AscendingOrder)
        self.view_p.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def table_init(self):
        """
        Inicjuje wygląd tabeli
        """
        query = QSqlQuery(
            'SELECT wizyty.wizyty_id, CONCAT(klienci.imie, " ", klienci.nazwisko) AS klient, uslugi.nazwa, '
            'wizyty.rezerwacja_od, wizyty.rezerwacja_do, wizyty.status FROM klienci, uslugi NATURAL JOIN wizyty WHERE wizyty.rezerwacja_od > CURRENT_TIMESTAMP AND wizyty.uzytkownik_id = '
            + str(self.id_pracownik) + ';')
        self.model.setQuery(query)
        self.proxy.setSourceModel(self.model)

        naglowki = {
            'wizyty_id': 'ID',
            'klient': 'Klient',
            'nazwa': 'Usługa',
            'rezerwacja_od': 'Rezerwacja od',
            "rezerwacja_do": 'Rezerwacja do',
            'status': 'Status rezerwacji'
        }
        # Ustawianie nagłówków
        ilosc_kolumn = self.model.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model.headerData(i, Qt.Horizontal)
            self.model.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn])

        self.view.setSizeAdjustPolicy(
            QAbstractScrollArea.AdjustToContentsOnFirstShow)
        self.view.setSortingEnabled(True)
        self.view.setAlternatingRowColors(True)

        # Wczytanie danych
        self.view.setModel(self.proxy)
        self.view.hideColumn(0)
        self.view.sortByColumn(4, Qt.AscendingOrder)
        self.view.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def clicked_table(self, view):
        """
        Metoda edytująca zaznaczone wiersze - Wstawia wartości z wierszy w odpowiednie pola
        """
        index = (view.selectionModel().currentIndex())
        if view.objectName() == 'Klienci':
            self.id_klient = index.sibling(index.row(), 0).data()
            self.lbl_klient_.setText('<b>' +
                                     index.sibling(index.row(), 1).data() +
                                     ' ' +
                                     index.sibling(index.row(), 2).data() +
                                     '</b>')
        elif view.objectName() == 'Usługi':
            self.id_usluga = index.sibling(index.row(), 0).data()
            self.lbl_usluga_.setText('<b>' +
                                     index.sibling(index.row(), 1).data() +
                                     '</b>')
            self.data_do = index.sibling(index.row(), 3).data()
        elif view.objectName() == 'Rezerwacje':
            self.id_rezerwacje = index.sibling(index.row(), 0).data()
            if self.id_rezerwacje > 0:
                self.btn_mod.setEnabled(True)
                self.btn_usun.setEnabled(True)
        elif view.objectName() == 'Pracownicy':
            self.id_pracownik = index.sibling(index.row(), 0).data()
            self.czas = []
            for i in reversed(range(self.gb_layout.count())):
                self.gb_layout.itemAt(i).widget().setParent(None)
            czas = datetime.datetime(2000, 1, 1, 8, 0)
            dzien = {
                1: ('pon_od', 'pon_do'),
                2: ('wt_od', 'wt_do'),
                3: ('sr_od', 'sr_do'),
                4: ('czw_od', 'czw_do'),
                5: ('pt_od', 'pt_do'),
                6: ('sob_od', 'sob_do'),
                7: ('', '')
            }
            query = 'SELECT date_format({}, "%H") AS g_start, date_format({}, "%H") AS g_stop FROM godziny WHERE ' \
                    'uzytkownik_id = {};'.format(dzien[self.dzien_tyg][0], dzien[self.dzien_tyg][1], self.id_pracownik)
            wynik = query_to_db(query)
            if wynik:
                godzina_stop = (int(wynik[1]) - int(wynik[0])) * 2
                godzina = int(wynik[0])
                for btn in self.btn_godz:
                    btn.setEnabled(True)
            else:
                godzina_stop = 0
                godzina = 1
                for btn in self.btn_godz:
                    btn.setDisabled(True)
            minuta = 0
            czas = datetime.time(godzina, minuta)
            for i in range(godzina_stop):
                self.btn_godz[i].setText(czas.strftime("%H:%M"))
                self.czas.append(czas)
                self.btn_godz[i].setObjectName(str(i))
                self.gb_layout.addWidget(self.btn_godz[i])
                if i % 2 != 0:
                    godzina += 1
                    minuta = 0
                else:
                    minuta = 30
                czas = datetime.time(godzina, minuta)
            QMetaObject.connectSlotsByName(self)

            # Czyszczenie, odświeżanie
            self.refresh()
            query = QSqlQuery(
                'SELECT uslugi.uslugi_id, uslugi.nazwa, uslugi.cena, date_format(uslugi.czas, "%H:%i") AS czas FROM uslugi NATURAL JOIN uzytkownik_usluga WHERE uzytkownik_usluga.uzytkownik_id = '
                + str(self.id_pracownik) + ';')
            self.model_u.setQuery(query)
            self.lbl_klient_.setText('')
            self.lbl_usluga_.setText('')

        if self.id_klient > 0 and self.id_pracownik > 0 and self.id_usluga > 0:
            self.btn_dodaj.setEnabled(True)

    def if_checked(self, txt, q, val=None):
        """
        Sprawdza poprawność wprowadzonych damych.
        :param val: wartości do zapytania
        :param q: zapytanie query MySql
        :param txt: komunikat
        """
        if self.id_klient < 0 and self.id_pracownik < 0 and self.id_usluga < 0 and self.data is None:
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Warning)
            msg.setText(txt)
            msg.setWindowTitle("Popraw dane")
            msg.exec_()
            return False
        else:
            print('Trwa zmiana w bazie danych')
            if val:
                print('Połączenie')
                query_to_db(q, val)
            else:
                print('Transakcja')
                return transaction_to_db(q)

            return True

    def refresh(self):
        """
        Odświeża widok tabeli rezerwacji
        """
        # Odświeżanie widoku tabeli
        query = QSqlQuery(
            'SELECT wizyty.wizyty_id, CONCAT(klienci.imie, " ", klienci.nazwisko) AS klient, uslugi.nazwa, '
            'wizyty.rezerwacja_od, wizyty.rezerwacja_do, wizyty.status FROM wizyty,klienci,uslugi WHERE wizyty.klienci_id= klienci.klienci_id AND wizyty.uslugi_id = uslugi.uslugi_id AND wizyty.rezerwacja_od > CURRENT_TIMESTAMP AND wizyty.uzytkownik_id = '
            + str(self.id_pracownik) + ';')
        self.model.setQuery(query)
        self.view.reset()

    def add(self):
        """
        Dodaje rezerwację do bazy danych i odświeża widok.
        """
        tekst = 'Nie wprowadzono wszystkich danych'
        self.data = self.lbl_termin_.dateTime().toString(Qt.ISODate)
        self.data_do = datetime.datetime.fromisoformat(
            self.data) + datetime.timedelta(
                hours=datetime.time.fromisoformat(self.data_do).hour,
                minutes=datetime.time.fromisoformat(self.data_do).minute)
        # Dodanie nowego użytkownika
        query = 'INSERT INTO wizyty (klienci_id, uslugi_id, uzytkownik_id, rezerwacja_od, rezerwacja_do, ' \
                'status) VALUES (%s, %s, %s, %s, %s, %s);'
        val = (self.id_klient, self.id_usluga, self.id_pracownik, self.data,
               str(self.data_do.isoformat()), 'oczekuje')
        print(val)

        if self.if_checked(tekst, query, val):
            msg = QMessageBox(self)
            msg.setIcon(QMessageBox.Information)
            msg.setText('Rezerwacja została dodana do bazy danych')
            msg.setWindowTitle("Dodano nową rezerwację")
            msg.exec_()
            self.refresh()

    def modify(self):
        """
        Zmienia status rezerwacji i odświeża widok.
        """
        tekst = 'Nie wprowadzono wszystkich danych'

        items = ('Oczekuje', 'Wykonana', 'Rezygnacja')
        item, ok = QInputDialog.getItem(self, "Wybierz status",
                                        "Wybierz nowy status rezerwacji",
                                        items, 0, False)

        if ok and item:
            # Zmodyfikowanie statusu
            query = 'UPDATE wizyty SET status = %s WHERE wizyty_id = %s;'
            val = (item.lower(), self.id_rezerwacje)

            if self.if_checked(tekst, query, val):
                msg = QMessageBox(self)
                msg.setIcon(QMessageBox.Information)
                msg.setText('Status rezerwacji został zmodyfikowany')
                msg.setWindowTitle("Zmodyfikowano status")
                msg.exec_()
                self.refresh()

    def remove(self):
        """
        Usuwa rezerwację z bazy danych
        """
        test = 'Błąd! Nie można usunąć danej rezerwacji!'
        query = 'DELETE FROM wizyty WHERE wizyty_id = %s'
        val = (self.id_rezerwacje, )
        ret = QMessageBox.question(
            self, 'Usuwanie rezerwacji',
            "Czy na pewno chcesz usunąć daną rezerwację klienta?",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if ret == QMessageBox.Yes:
            if self.if_checked(test, query, val):
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Information)
                msg.setText('Rezerwacja została usunięta')
                msg.setWindowTitle("Usunięto")
                msg.exec_()

                self.refresh()

    @pyqtSlot()
    def on_0_clicked(self):
        self.lbl_termin_.setTime(self.czas[0])

    @pyqtSlot()
    def on_1_clicked(self):
        self.lbl_termin_.setTime(self.czas[1])

    @pyqtSlot()
    def on_2_clicked(self):
        self.lbl_termin_.setTime(self.czas[2])

    @pyqtSlot()
    def on_3_clicked(self):
        self.lbl_termin_.setTime(self.czas[3])

    @pyqtSlot()
    def on_4_clicked(self):
        self.lbl_termin_.setTime(self.czas[4])

    @pyqtSlot()
    def on_5_clicked(self):
        self.lbl_termin_.setTime(self.czas[5])

    @pyqtSlot()
    def on_6_clicked(self):
        self.lbl_termin_.setTime(self.czas[6])

    @pyqtSlot()
    def on_7_clicked(self):
        self.lbl_termin_.setTime(self.czas[7])

    @pyqtSlot()
    def on_8_clicked(self):
        self.lbl_termin_.setTime(self.czas[8])

    @pyqtSlot()
    def on_9_clicked(self):
        self.lbl_termin_.setTime(self.czas[9])

    @pyqtSlot()
    def on_10_clicked(self):
        self.lbl_termin_.setTime(self.czas[10])

    @pyqtSlot()
    def on_11_clicked(self):
        self.lbl_termin_.setTime(self.czas[11])

    @pyqtSlot()
    def on_12_clicked(self):
        self.lbl_termin_.setTime(self.czas[12])

    @pyqtSlot()
    def on_13_clicked(self):
        self.lbl_termin_.setTime(self.czas[13])

    @pyqtSlot()
    def on_14_clicked(self):
        self.lbl_termin_.setTime(self.czas[14])

    @pyqtSlot()
    def on_15_clicked(self):
        self.lbl_termin_.setTime(self.czas[15])

    @pyqtSlot(str)
    def searching_u(self, text):
        """
        Wyszukuje po wszystkich kolumnach tabeli
        :param text:
        """
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy_u.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy_u.setFilterKeyColumn(-1)

    @pyqtSlot(str)
    def searching_k(self, text):
        """
        Wyszukuje po wszystkich kolumnach tabeli
        :param text:
        """
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy_k.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy_k.setFilterKeyColumn(-1)

    @pyqtSlot(str)
    def searching_p(self, text):
        """
        Wyszukuje po wszystkich kolumnach tabeli
        :param text:
        """
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy_p.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy_p.setFilterKeyColumn(-1)
Exemplo n.º 29
0
class UiRenters(QtWidgets.QDialog):
    def __init__(self):
        super().__init__()
        uic.loadUi('Ui/UiRenters.ui', self)

        self.add_renter_window = None
        self.edit_renter_window = None

        self.data_proxy = DataProxy()

        self.populate_model()

        self.search_comboBox.addItems(self.renters_model.headers)

        self.renters_count.setText(str(self.renters_model.rowCount(self)))

        self.add_new_renter_button.clicked.connect(self.add_new_renter_button_clicked)
        self.search_comboBox.currentIndexChanged.connect(self.change_search_column)
        self.search_input.textChanged.connect(self.search)
        self.renters_model.dataChanged.connect(self.update_renters_count)
        self.close_button.clicked.connect(self.close)

        self.renters_QTableView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.renters_QTableView.customContextMenuRequested.connect(self.show_context_menu)
        self.renters_QTableView.setSelectionBehavior(QAbstractItemView.SelectRows)

        self.setModal(True)

        self.renters_QTableView.resizeColumnsToContents()
        # self.renters_QTableView.setSortingEnabled(True)  # Shouldn't be enabled, screws indexes badly, and needs
        # tons of boiler plate code to work.
        self.show()

    def populate_model(self):
        self.renters_model = RenterModel(self.renters_QTableView)
        self.renters_proxy_model = QSortFilterProxyModel(self)
        self.renters_proxy_model.setSourceModel(self.renters_model)
        self.renters_QTableView.setModel(self.renters_proxy_model)

    def add_new_renter_button_clicked(self):
        self.add_renter_window = UiAddRenter(self)

    def change_search_column(self, index):
        self.renters_proxy_model.setFilterKeyColumn(index)

    def search(self, text):
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.renters_proxy_model.setFilterRegExp(search)

    def update_renters_count(self):
        self.renters_count.setText(str(self.renters_model.rowCount(self)))

    def show_context_menu(self, event):
        index = self.renters_QTableView.indexAt(event)
        if index.isValid():
            menu = QMenu(self)
            menu.addAction('Edit Renter', lambda: self.edit_renter(index))
            menu.addAction('Remove Renter', lambda: self.remove_renter(index))
            menu.popup(QCursor.pos())

    def edit_renter(self, index):
        self.edit_renter_window = UiEditRenter(self, index, self.renters_model.get_data(index))

    def remove_renter(self, index):
        renter_id = self.renters_model.get_data(index)['id']
        if self.data_proxy.delete_renter(renter_id):
            self.populate_model()
            self.update_renters_count()
Exemplo n.º 30
0
class MyWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        horizontalLayout = QHBoxLayout()
        self.dayView = QTableView()
        self.dayView.setFrameShape(QFrame.Box)
        self.dayView.horizontalHeader().setStretchLastSection(True)
        self.dayView.verticalHeader().setVisible(False)
        horizontalLayout.addWidget(self.dayView)

        verticalLayout = QVBoxLayout()
        self.calendarWidget = QCalendarWidget()
        self.calendarWidget.setMinimumSize(QSize(250, 200))
        self.calendarWidget.setMaximumSize(QSize(250, 200))
        self.calendarWidget.setMinimumDate(QDate(2017, 1, 1))
        self.calendarWidget.setMaximumDate(QDate(2030, 1, 1))
        self.calendarWidget.selectionChanged.connect(self.dataChange)
        self.calendarWidget.setSelectedDate(QDate.currentDate())

        verticalLayout.addWidget(self.calendarWidget)

        titleFV = QLabel('Food View')
        verticalLayout.addWidget(titleFV)

        self.filterLine = QLineEdit()
        self.filterLine.setMaximumSize(QSize(200, 25))

        self.filterLine.textChanged.connect(self.filterChange)

        buttonAdd = QPushButton(QIcon("images/add.png"), '', None)
        buttonAdd.setMaximumSize(QSize(20, 30))
        buttonAdd.clicked.connect(self.addFood)
        buttonDell = QPushButton(QIcon("images/del.png"), '', None)
        buttonDell.setMaximumSize(QSize(20, 30))
        buttonDell.clicked.connect(self.delFood)

        lineEditLayout = QHBoxLayout()
        lineEditLayout.addWidget(self.filterLine)
        lineEditLayout.addWidget(buttonAdd)
        lineEditLayout.addWidget(buttonDell)

        verticalLayout.addLayout(lineEditLayout)

        self.foodView = QTableView()
        self.foodView.setMinimumSize(QSize(0, 0))
        self.foodView.setMaximumSize(QSize(250, 1000))
        self.foodView.verticalHeader().setVisible(False)
        self.foodView.horizontalHeader().setStretchLastSection(True)

        verticalLayout.addWidget(self.foodView)
        horizontalLayout.addLayout(verticalLayout)

        self.setLayout(horizontalLayout)

        model_in = QSqlRelationalTableModel()
        model_in.setEditStrategy(QSqlTableModel.OnFieldChange)
        model_in.setTable("intake_food")

        id_food = model_in.fieldIndex("id_food")
        date = model_in.fieldIndex("food_date")
        mass = model_in.fieldIndex("mass")

        # Set model, hide ID column
        model_in.setRelation(id_food, QSqlRelation("food", "id", "name"))
        model_in.setHeaderData(id_food, Qt.Horizontal, "Food")
        model_in.setHeaderData(date, Qt.Horizontal, "Date")
        model_in.setHeaderData(mass, Qt.Horizontal, "Mass")

        if not model_in.select():
            self.showError(model_in.lastError())
            return

        self.proxyModel_in = QSortFilterProxyModel()
        self.proxyModel_in.setSourceModel(model_in)
        self.proxyModel_in.setFilterKeyColumn(2)

        self.dayView.setItemDelegate(FlipProxyDelegate())
        self.dayView.setModel(self.proxyModel_in)
        self.dayView.setColumnHidden(0, True)
        self.dayView.setColumnHidden(2, True)
        self.dayView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.dayView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.dayView.customContextMenuRequested.connect(self.ShowContextMenu)
        # filter day food by calendar widget
        self.dataChange()

        self.model_f = QSqlRelationalTableModel()
        self.model_f.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.model_f.setTable("food")

        self.model_f.setHeaderData(1, Qt.Horizontal, "Food")
        self.model_f.setHeaderData(2, Qt.Horizontal, "Rate")

        if not self.model_f.select():
            self.showError(self.model_f.lastError())
            return

        self.proxyModel_f = QSortFilterProxyModel()
        self.proxyModel_f.setSourceModel(self.model_f)
        self.proxyModel_f.setFilterKeyColumn(1)

        self.foodView.setModel(self.proxyModel_f)
        self.foodView.setColumnHidden(0, True)
        self.foodView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.foodView.setColumnWidth(1, 150)
        self.foodView.setColumnWidth(2, 90)

    def showError(self, err):

        QMessageBox.critical(self, "Unable to initialize Database",
                             "Error initializing database: " + err.text())

    def filterChange(self):
        regExp = QRegExp(self.filterLine.text(), Qt.CaseInsensitive,
                         QRegExp.FixedString)
        self.proxyModel_f.setFilterRegExp(regExp)

    def dataChange(self):
        date = self.calendarWidget.selectedDate().toString('dd.MM.yyyy')
        regExp = QRegExp(date, Qt.CaseInsensitive, QRegExp.FixedString)
        self.proxyModel_in.setFilterRegExp(regExp)

    def addFood(self):
        self.model_f.insertRow(self.model_f.rowCount())

    def delFood(self):
        self.model_f.removeRow(self.foodView.currentIndex().row())
        self.model_f.select()

    def resizeEvent(self, event):
        self.dayView.setColumnWidth(1, self.dayView.width() * 0.7)
        self.dayView.setColumnWidth(3, self.dayView.width() * 0.2)

        QWidget.resizeEvent(self, event)

    def ShowContextMenu(self, pos):
        contextMenu = QMenu("Context menu", self)

        action1 = QAction("Add food eaten", self)
        contextMenu.addAction(action1)
        contextMenu.exec(self.mapToGlobal(pos))
Exemplo n.º 31
0
class UiMainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi('Ui/UiMainWindow.ui', self)

        self.books_window = None
        self.renters_window = None
        self.add_book_window = None
        self.add_new_book_rent_window = None

        self.data_proxy = DataProxy()

        self.populate_model()

        self.search_comboBox.addItems(self.rented_books_model.headers)

        self.update_counters()

        self.btn_show_books.clicked.connect(self.show_books_clicked)
        self.btn_show_renters.clicked.connect(self.show_renters_clicked)
        self.add_new_book_rent_button.clicked.connect(self.add_new_book_rent_button_clicked)
        self.search_comboBox.currentIndexChanged.connect(self.change_search_column)
        self.search_input.textChanged.connect(self.search)
        self.rented_books_model.dataChanged.connect(self.update_counters)

        self.rented_books_QTableView.resizeColumnsToContents()
        # self.rented_books_QTableView.setSortingEnabled(True)

        self.rented_books_QTableView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.rented_books_QTableView.customContextMenuRequested.connect(self.show_context_menu)
        self.rented_books_QTableView.setSelectionBehavior(QAbstractItemView.SelectRows)

        self.show()

    def populate_model(self):
        self.rented_books_model = RentedBookModel(self.rented_books_QTableView)
        self.rented_books_proxy_model = QSortFilterProxyModel(self)
        self.rented_books_proxy_model.setSourceModel(self.rented_books_model)
        self.rented_books_QTableView.setModel(self.rented_books_proxy_model)

    def show_books_clicked(self):
        self.books_window = UiBooks()

    def show_renters_clicked(self):
        self.renters_window = UiRenters()

    def add_new_book_rent_button_clicked(self):
        self.add_new_book_rent_window = UiAddBookRent(self)

    def change_search_column(self, index):
        self.rented_books_proxy_model.setFilterKeyColumn(index)

    def search(self, text):
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.rented_books_proxy_model.setFilterRegExp(search)

    def show_context_menu(self, event):
        index = self.rented_books_QTableView.indexAt(event)
        if index.isValid():
            menu = QMenu(self)
            menu.addAction('Remove Rent', lambda: self.remove_rent(index))
            menu.popup(QCursor.pos())

    def remove_rent(self, index):
        rent_id = self.rented_books_model.get_data(index)['id']
        if self.data_proxy.delete_rented_book(rent_id):
            self.populate_model()
            self.update_counters()

    def update_rented_books_count(self):
        self.rented_books_count.setText(str(self.rented_books_model.rowCount(self)))

    def update_overdue_counter(self):
        self.overdue_books_count.setText(str(self.rented_books_model.overdue_counter()))

    def update_counters(self):
        self.update_rented_books_count()
        self.update_overdue_counter()
Exemplo n.º 32
0
class NarzPoz(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.pozycja = 'Brak'
        self.proxy = QSortFilterProxyModel(self)
        self.proxy_poz = QSortFilterProxyModel(self)
        self.edit_wysz = QLineEdit(self)
        self.combo_typ = QComboBox(self)
        self.lbl_wysz = QLabel("Wyszukaj")
        self.lbl_typ = QLabel("Wybierz typ narzędzia:")
        self.combo_poz = QComboBox(self)
        self.lbl_poz = QLabel("Wybierz pozycję:")
        self.listaPozycji = []
        self.table = QTableView(self)
        self.table_narz = QTableView(self)
        sciezka = czy_istnieje()
        db = QSqlDatabase.addDatabase('QSQLITE')
        db.setDatabaseName(sciezka)
        if db.open():
            print('Otworzono bazę danych')
        self.model = QSqlTableModel(self, db)
        self.model_poz = QSqlTableModel(self, db)

        self.parent = parent
        self.formularz = QGroupBox("Przypisz narzędzia")
        self.initUI()

    def initUI(self):
        self.naglowki_kolumn()

        # todo dodać okno z wyborem oprawki po wyborze narzędzia
        typy_narzedzi = [
            'Brak',
            'Frez palcowy',
            'Frez płytkowy (głowica)',
            'Gwintownik',
            'Nóż tokarski',
            # 'Oprawka',
            'Piła',
            'Pozostałe',
            'Rozwiertak',
            'Wiertło',
            'Wiertło składane',
            'Wygniatak'
        ]

        self.widok()
        # Zatwierdzenie
        ok_button = QPushButton("Dodaj do pozycji")
        cancel_button = QPushButton("Cofnij")
        wydrukuj_btn = QPushButton("Wyeksportuj")
        usun_btn = QPushButton("Usuń pozycję")
        dodaj_btn = QPushButton("Dodaj pozycję")
        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(ok_button)
        hbox.addWidget(cancel_button)

        # Layouty
        layout_v = QVBoxLayout()
        l_1 = QHBoxLayout()
        l_2 = QHBoxLayout()
        l_3 = QHBoxLayout()
        layout_h = QHBoxLayout()

        # Funkcje
        self.combo_typ.addItems(typy_narzedzi)
        self.combo_poz.addItems(self.listaPozycji)
        self.proxy_poz.setSourceModel(self.model_poz)
        self.table.setModel(self.proxy_poz)
        self.proxy.setSourceModel(self.model)
        self.table_narz.setModel(self.proxy)

        # Przyporzadkowanie
        l_1.addWidget(self.lbl_typ)
        l_1.addWidget(self.combo_typ)
        l_2.addWidget(self.lbl_wysz)
        l_2.addWidget(self.edit_wysz)
        l_3.addWidget(wydrukuj_btn)
        l_3.addWidget(usun_btn)
        l_3.addWidget(dodaj_btn)
        layout_h.addWidget(self.lbl_poz)
        layout_h.addWidget(self.combo_poz)
        layout_v.addLayout(layout_h, 1)
        layout_v.addLayout(l_1)
        layout_v.addLayout(l_2)
        layout_v.addLayout(l_3)
        layout_v.addWidget(self.table)
        layout_v.addWidget(self.table_narz)
        self.formularz.setLayout(layout_v)
        main_layout = QVBoxLayout()
        main_layout.addWidget(self.formularz)
        main_layout.addLayout(hbox)
        self.setLayout(main_layout)

        # connecty
        # ok_button.clicked.connect(self.dodaj)
        cancel_button.clicked.connect(self.anulowanie)
        dodaj_btn.clicked.connect(self.dodaj_poz)
        ok_button.clicked.connect(self.klikniecie)
        usun_btn.clicked.connect(self.usun_pozycje)
        wydrukuj_btn.clicked.connect(self.wydrukuj)
        self.edit_wysz.textChanged.connect(self.wyszukiwanie)
        self.combo_typ.activated[str].connect(self.onActiveNarz)
        self.combo_poz.activated[str].connect(self.onActivePoz)
        # Menu kontekstowe własne
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.prawoklik)

    def wydrukuj(self):
        poz_lista = [
            'Wykaz narzędzi ' + self.pozycja,
            "SELECT * FROM '" + self.pozycja + "'",
            'Baza nie zawiera żadnych pozycji. Plik nie zostanie zapisany.',
        ]
        from gui import Window
        if self.pozycja != 'Brak':
            Window.export(self, poz_lista)
            self.parent.statusBar().showMessage("Wyeksportowano do pliku",
                                                10000)
        else:
            QMessageBox.critical(self, 'Wybierz pozycję',
                                 'Nie wybrano żadnej pozycji!', QMessageBox.Ok,
                                 QMessageBox.Ok)

    def naglowki_kolumn(self):
        # Nagłówki kolumn
        self.listaPozycji.append('Brak')
        for i in naglowki():
            if "/" in i[0]:
                self.listaPozycji.append(i[0])

    def usun_pozycje(self):
        text, ok = QInputDialog.getItem(self,
                                        'Usuń pozycje',
                                        'Wybierz pozycję do usunięcia',
                                        self.listaPozycji[1:],
                                        editable=False)
        if ok:
            if text != 'Brak':
                print(text)
                query = 'DROP TABLE "main"."' + text + '";'
                polaczenie(query)
                self.listaPozycji.clear()
                self.naglowki_kolumn()
                indeks = self.combo_poz.findText(text)
                self.combo_poz.removeItem(indeks)
                self.parent.statusBar().showMessage("Usunięto pozycję", 10000)
            else:
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Warning)
                msg.setWindowIcon(QIcon('icons/cow.png'))
                msg.setText("Wybierz poprawną pozycję")
                msg.setWindowTitle("Niewłaściwa pozycja")
                msg.exec_()
                self.usun_pozycje()

    def prawoklik(self):
        menu = QMenu(self)
        akcja = QAction('Usuń narzędzie', self)
        akcja.triggered.connect(self.usun_wiersz)
        menu.addAction(akcja)
        menu.exec_(QCursor.pos())

    def usun_wiersz(self):
        selected = self.table.currentIndex()
        self.model_poz.removeRow(selected.row())
        self.model_poz.submitAll()
        self.model_poz.select()
        self.parent.statusBar().showMessage("Usunięto narzędzie", 10000)

    def dodaj_poz(self):
        text, ok = QInputDialog.getText(self, 'Wprowadź pozycje', 'Pozycja:')
        if ok and text:
            query = 'CREATE TABLE IF NOT EXISTS "' + text + '" ("id_poz" INTEGER PRIMARY ' \
                                              'KEY AUTOINCREMENT, ' \
                                              '"symbol_narz"	TEXT, ' \
                                              '"vc" INTEGER,	"obroty" ' \
                                              'INTEGER, "fz" REAL, "posuw" ' \
                                              'INTEGER); '
            print(query)
            polaczenie(query)
            self.listaPozycji.clear()
            self.combo_poz.addItem(text)
            self.naglowki_kolumn()
            self.parent.statusBar().showMessage("Dodano pozycję " + text,
                                                10000)
        else:
            print("Nie wpisano pozycji")

    def onActivePoz(self, tekst):
        self.pozycja = tekst
        naglowki = {
            'id_poz': 'ID',
            'symbol_narz': 'Symbol narzędzia',
            'vc': 'Prędkość skrawania Vc [m/min]',
            'obroty': 'Obroty n [obr/min]',
            'fz': 'Posuw na ząb fz [mm/ostrze]',
            'posuw': 'Posuw liniowy f [mm/min]'
        }
        self.model_poz.setTable(tekst)
        self.model_poz.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.model_poz.select()

        # Ustawianie nagłówków
        ilosc_kolumn = self.model_poz.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model_poz.headerData(i, Qt.Horizontal)
            self.model_poz.setHeaderData(i, Qt.Horizontal,
                                         naglowki[nazwa_kolumn])

    def onActiveNarz(self, tekst):
        slownik = {
            'Frez palcowy': 'frezy_palcowe',
            'Frez płytkowy (głowica)': 'frezy_plytkowe',
            'Gwintownik': 'gwintowniki',
            'Nóż tokarski': 'noze_tokarskie',
            'Oprawka': 'oprawki',
            'Piła': 'pily',
            'Pozostałe': 'pozostale',
            'Rozwiertak': 'rozwiertaki',
            'Wiertło': 'wiertla',
            'Wiertło składane': 'wiertla_skladane',
            'Wygniatak': 'wygniataki',
            'Brak': ''
        }
        naglowki = {
            'idfrezy_palcowe': 'ID',
            'symbol_freza': 'Symbol',
            'producent_fr': 'Producent',
            'srednica_fr': 'Średnica',
            'dl_fr': 'Długość całkowita',
            'dl_rob_fr': 'Długość robocza',
            'idfrezy_plytkowe': 'ID',
            'symbol_frez_pl': 'Symbol',
            'producent_fp': 'Producent',
            'srednica_fr_pl': 'Średnica',
            'ilosc_plytek': 'Ilość płytek',
            'symbol_pl': 'Symbol płytek',
            'ilosc_krawedzi_pl': 'Ilość krawędzi płytki',
            'idgwintowniki': 'ID',
            'symbol_g': 'Symbol',
            'producent_gw': 'Producent',
            'rozmiar_gwintu': 'Rozmiar gwintu i skok',
            'typ_gwintownika': 'Typ gwintownika',
            'idnoze_tokarskie': 'ID',
            'symbol_n': 'Symbol',
            'producent_n': 'Producent',
            'plytki_n': 'Symbol płytek',
            'ilosc_krawedzi_pl_n': 'Ilość krawędzi',
            'idpily': 'ID',
            'symbol_p': 'Symbol',
            'producent_pil': 'Producent',
            'srednica_p': 'Średnica',
            'grubosc_p': 'Grubość',
            'rodzaj_pl_p': 'Symbol płytek',
            'ilosc_pl_p': 'Ilość płytek',
            'ilosc_kraw_p': 'Ilość krawędzi płytki',
            'idpozostale': 'ID',
            'symbol_poz': 'Symbol',
            'producent_poz': 'Producent',
            'srednica_poz': 'Średnica',
            'ilosc_pl_poz': 'Ilość płytek',
            'plytki_poz': 'Symbol płytek',
            'idrozwiertaki': 'ID',
            'symbol_r': 'Symbol',
            'producent_roz': 'Producent',
            'rozmiar_r': 'Rozmiar',
            'idwiertla': 'ID',
            'symbol_w': 'Symbol',
            'producent_w': 'Producent',
            'srednica_w': 'Średnica',
            'dlugosc_w': 'Długość [mm]',
            'idwiertla_skladane': 'ID',
            'symbol_w_skl': 'Symbol',
            'producent_ws': 'Producent',
            'srednica_w_skl': 'Średnica',
            'plytki_w_skl': 'Symbol płytek',
            'idwygniataki': 'ID',
            'symbol_wyg': 'Symbol',
            'producent_wyg': 'Producent',
            'rozmiar_gw': 'Rozmiar gwintu'
        }
        self.model.setTable(slownik[tekst])
        self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.model.select()

        # Ustawianie nagłówków
        ilosc_kolumn = self.model.columnCount()
        for i in range(ilosc_kolumn):
            nazwa_kolumn = self.model.headerData(i, Qt.Horizontal)
            self.model.setHeaderData(i, Qt.Horizontal, naglowki[nazwa_kolumn])

    @pyqtSlot(str)
    def wyszukiwanie(self, text):
        search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(search)
        # Odpowiedzialne za kolumnę, po której filtruje
        self.proxy.setFilterKeyColumn(-1)

    # opcja z wyszukiwaniem
    def widok(self):
        # Ustawianie własciwości widoku
        self.table_narz.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_narz.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_narz.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_narz.verticalHeader().setVisible(False)
        self.table_narz.setSortingEnabled(True)
        self.table_narz.setModel(self.model)
        self.table.verticalHeader().setVisible(False)
        self.table.setSortingEnabled(True)
        self.table.setAlternatingRowColors(True)
        self.table.setModel(self.model_poz)
        # self.table.hideColumn(0)
        self.table_narz.doubleClicked.connect(self.klikniecie)

    @pyqtSlot()
    def klikniecie(self):
        x = self.table_narz.currentIndex().row()
        y = self.table_narz.currentIndex().column()
        nazwa = self.table_narz.currentIndex().sibling(x, 1).data()
        print(nazwa)

        # Dodanie narzędzia do pozycji
        if nazwa:
            print(nazwa)
            query = "INSERT INTO '" + self.model_poz.tableName(
            ) + "'(symbol_narz) VALUES ('" + nazwa + "') "
            polaczenie(query)
            # Odświeża tabelę
            self.model_poz.select()
            self.parent.statusBar().showMessage(
                "Dodano narzędzie " + nazwa + " do pozycji " +
                self.model_poz.tableName(), 10000)
        else:
            print(self.model_poz.tableName())
            print("Brak wybranego narzędzia")

    def anulowanie(self):
        self.parent.statusBar().clearMessage()
        from opcje_qt import Wewnatrz
        menu_gl = Wewnatrz(self.parent)
        self.parent.setCentralWidget(menu_gl)
Exemplo n.º 33
0
class Shtat(QMainWindow):
    """
    Класс, реализующий окно для работы со штатным расписанием в виде таблицы
    """
    con = QSqlDatabase.addDatabase('QSQLITE')
    con.setDatabaseName(settings.db_name)

    def __init__(self, parent: any = None) -> None:
        """
        Функция инициализации окна штатного расписания
        :param parent: Родительский виджет (окно)
        """
        super().__init__(parent)
        self.filters = ['Номер',
                        'Подразделение',
                        'Должность',
                        'Количество',
                        'Тариф',
                        'Оклад',
                        'ФИО',
                        'Декрет',
                        'История',
                        'Оклад замещающего работника',
                        'Вид позиции',
                        ]
        self.setObjectName("ShtatWindow")
        self.resize(1380, 886)
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setObjectName("centralwidget")

        self.view = QTableView(self.centralwidget)
        self.view.setGeometry(QRect(0, 0, 1381, 821))
        self.view.setObjectName("shtat_table_view")
        self.view.setSortingEnabled(True)

        self.filter_combo_box = QtWidgets.QComboBox(self.centralwidget)
        self.filter_combo_box.setGeometry(QRect(250, 840, 231, 31))
        self.filter_combo_box.setObjectName("filter_combo_box")
        self.filter_input = QtWidgets.QLineEdit(self.centralwidget)
        self.filter_input.setGeometry(QRect(500, 840, 281, 31))
        self.filter_input.setObjectName("filter_input")
        self.filter_label = QtWidgets.QLabel(self.centralwidget)
        self.filter_label.setGeometry(QRect(10, 840, 221, 31))
        font = QFont()
        font.setFamily("Times New Roman")
        font.setPointSize(12)
        self.filter_label.setFont(font)
        self.filter_label.setObjectName("filter_label")
        self.filter_button = QtWidgets.QPushButton(self.centralwidget)
        self.filter_button.setGeometry(QRect(800, 840, 171, 31))
        self.save_shtat_button = QtWidgets.QPushButton(self.centralwidget)
        self.save_shtat_button.setGeometry(QRect(1000, 840, 225, 31))
        self.filter_button.setFont(font)
        self.save_shtat_button.setFont(font)
        self.filter_button.setObjectName("filter_button")
        self.setCentralWidget(self.centralwidget)

        _translate = QCoreApplication.translate
        self.setWindowTitle(_translate("ShtatWindow", "Работа со штатным расписанием"))
        self.filter_label.setText(_translate("ShtatWindow", "Фильтровать по столбцу:"))
        self.filter_button.setText(_translate("ShtatWindow", "Поиск"))
        self.save_shtat_button.setText(_translate("ShtatWindow", "Выгрузить штатное расписание"))

        self.model = QSqlRelationalTableModel(self.view)
        self.model.setTable('salaries')
        self.model.setEditStrategy(QSqlRelationalTableModel.OnFieldChange)
        self.model.setRelation(1, QSqlRelation("departments", "code", "department"))
        self.model.setRelation(10, QSqlRelation("positions", "position_code", "position_name"))
        for i in range(0, len(self.filters)):
            self.model.setHeaderData(i, Qt.Horizontal, self.filters[i])
        self.model.select()

        self.proxyModelContact = QSortFilterProxyModel(self)
        self.proxyModelContact.setSourceModel(self.model)
        self.view.setModel(self.proxyModelContact)
        self.view.resizeColumnsToContents()
        self.view.setItemDelegate(QSqlRelationalDelegate(self.view))
        self.filter_combo_box.addItems(self.filters)
        self.filter_button.clicked.connect(self.use_filter_button)
        self.save_shtat_button.clicked.connect(self.use_save_shtat_button)
        self.view.setItemDelegate(QSqlRelationalDelegate(self.view))

    def use_filter_button(self) -> None:
        """
        Функция кнопки "Поиск". Считывает паттерн из поля фильтра и применяет его к столбцу,
        выбранного в комбо-боксе фильтра
        :return: None
        """
        self.proxyModelContact.setFilterKeyColumn(self.filters.index(self.filter_combo_box.currentText()))
        self.proxyModelContact.setFilterRegExp(self.filter_input.text())

    @staticmethod
    def use_save_shtat_button() -> None:
        """
        Функция кнопки "Выгрузить штатное расписание". Выгружает все штатное расписание в
        файл формата Excel
        :return: None
        """
        file = QtWidgets.QFileDialog.getSaveFileName()[0]
        saver = FullShtatToExcel(file if file.endswith(".xlsx") else f"{file}.xlsx")
        saver.full_shtat_to_excel()
Exemplo n.º 34
0
class MinibufferInput(QLineEdit):
    completion_activated = Signal(QModelIndex)

    FuzzyMatch = Prompt.FuzzyMatch
    SimpleMatch = Prompt.SimpleMatch

    def __init__(self, parent, window):
        QLineEdit.__init__(self, parent)
        self._completer_model = None
        self._popup = Popup(window, self)
        self.textEdited.connect(self._show_completions)
        self._popup.installEventFilter(self)
        self.installEventFilter(self)
        self._eat_focusout = False
        self._proxy_model = QSortFilterProxyModel(self)
        self._proxy_model.setFilterKeyColumn(-1)
        self._popup.setModel(self._proxy_model)
        self._popup.activated.connect(self._on_completion_activated)
        self._popup.selectionModel().currentRowChanged.connect(
            self._on_row_changed)
        self._right_italic_text = ""
        self._mark = False
        self.configure_completer({})

        from ..keyboardhandler import LOCAL_KEYMAP_SETTER
        LOCAL_KEYMAP_SETTER.register_minibuffer_input(self)

    def configure_completer(self, opts):
        self._popup._max_visible_items = opts.get("max-visible-items", 10)
        self._match = opts.get("match", self.SimpleMatch)
        self._autocomplete_single = opts.get("autocomplete-single", True)
        self._autocomplete = opts.get("autocomplete", False)
        if self._autocomplete:
            self._autocomplete_single = False
        self._complete_empty = opts.get("complete-empty", False)

    def keymap(self):
        prompt = self.parent()._prompt
        if prompt and prompt.keymap:
            return prompt.keymap
        return KEYMAP

    def eventFilter(self, obj, event):
        etype = event.type()
        if etype == QEvent.FocusOut and obj == self and self._eat_focusout \
           and self._popup.isVisible():
            # keep the focus on the line edit
            return True
        elif etype == QEvent.MouseButtonPress:
            # if we've clicked in the widget (or its descendant), let it handle
            # the click
            pos = obj.mapToGlobal(event.pos())
            target = QApplication.widgetAt(pos)
            if target and (self.isAncestorOf(target) or target == self):
                if not self._popup.underMouse():
                    self._popup.hide()
                target.event(event)
                return True

            if not self._popup.underMouse():
                self._popup.hide()
                return True
        elif etype in (QEvent.KeyPress, QEvent.KeyRelease):
            # send event to the line edit
            self._eat_focusout = True
            self.event(event)
            self._eat_focusout = False
            return True

        return QLineEdit.eventFilter(self, obj, event)

    def set_completer_model(self, completer_model):
        self._proxy_model.setSourceModel(completer_model)

    def completer_model(self):
        return self._proxy_model.sourceModel()

    def set_match(self, type):
        self._match = type
        if self._popup.isVisible():
            self._show_completions(self.text)

    def _on_row_changed(self, current, old):
        if self._autocomplete:
            self.complete(hide_popup=False)

    def _show_completions(self, txt, force=False):
        force = force or self._complete_empty
        if self._match == self.SimpleMatch:
            pattern = "^" + QRegExp.escape(txt)
        else:
            pattern = ".*".join(QRegExp.escape(t) for t in txt.split())

        self._proxy_model.setFilterRegExp(QRegExp(pattern, Qt.CaseInsensitive))
        if self._proxy_model.rowCount() == 0:
            self._popup.hide()
        elif not txt and not force:
            self._popup.hide()
        else:
            self._popup.popup()

    def show_completions(self):
        self._show_completions(self.text(), True)

    def _on_completion_activated(self, index, hide_popup=True):
        if hide_popup:
            self._popup.hide()
        model = index.model()
        if index.column() != 0:
            index = model.index(index.row(), 0)

        self.setText(model.data(index))
        self.completion_activated.emit(model.mapToSource(index))

    def popup(self):
        return self._popup

    def complete(self, hide_popup=True):
        if not self._popup.isVisible():
            return

        index = self._popup.selectionModel().currentIndex()
        if index.isValid():
            self._on_completion_activated(index, hide_popup=hide_popup)
        elif self._autocomplete_single and self._proxy_model.rowCount() == 1:
            self._on_completion_activated(self._proxy_model.index(0, 0),
                                          hide_popup=hide_popup)

    def select_next_completion(self, forward=True):
        model = self._proxy_model
        entries = model.rowCount()
        if entries == 0:
            return

        selection = self._popup.selectionModel().currentIndex()
        if not selection.isValid():
            row = 0 if forward else (entries - 1)
        else:
            row = selection.row()
            if forward:
                row = row + 1
                if row >= entries:
                    row = 0
            else:
                row = row - 1
                if row < 0:
                    row = (entries - 1)

        self._popup.selectRow(row)

    def mark(self):
        return self._mark

    def set_mark(self, value=None):
        if value is None:
            value = not self._mark
        self._mark = value
        return self._mark

    def reinit(self):
        self.setText("")
        self.setEchoMode(self.Normal)
        self.setValidator(None)
        self._right_italic_text = ""

    def set_right_italic_text(self, text):
        self._right_italic_text = text
        self.update()

    def paintEvent(self, event):
        QLineEdit.paintEvent(self, event)
        if not self._right_italic_text:
            return
        painter = QPainter(self)
        font = painter.font()
        font.setItalic(True)
        painter.setFont(font)
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.drawText(self.rect().adjusted(0, 0, -10, 0), Qt.AlignRight,
                         self._right_italic_text)
Exemplo n.º 35
0
class QtComparePanel(QWidget):

    filterChanged = pyqtSignal(str)

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

        self.visibility_flags = []
        self.visibility_buttons = []
        self.labels_projects = []

        self.setSizePolicy(QSizePolicy.MinimumExpanding,
                           QSizePolicy.MinimumExpanding)
        self.setMinimumWidth(400)
        self.setMinimumHeight(100)

        self.data_table = QTableView()
        self.data_table.setSizePolicy(QSizePolicy.MinimumExpanding,
                                      QSizePolicy.MinimumExpanding)
        self.data_table.setSelectionMode(QAbstractItemView.MultiSelection)
        self.data_table.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.data_table.setSelectionBehavior(QAbstractItemView.SelectRows)

        self.model = None
        self.data = None

        self.combodelegate1 = ComboBoxItemDelegate(self.data_table)
        self.combodelegate2 = ComboBoxItemDelegate(self.data_table)

        lblFilter = QLabel("Filter: ")
        self.comboboxFilter = QComboBox()
        self.comboboxFilter.setMinimumWidth(80)
        self.comboboxFilter.addItem("All")
        self.comboboxFilter.addItem("Same")
        self.comboboxFilter.addItem("Born")
        self.comboboxFilter.addItem("Dead")
        self.comboboxFilter.addItem("Grow")
        self.comboboxFilter.addItem("Shrink")

        filter_layout = QHBoxLayout()
        filter_layout.addWidget(lblFilter)
        filter_layout.addWidget(self.comboboxFilter)
        filter_layout.addStretch()

        layout = QVBoxLayout()
        layout.addLayout(filter_layout)
        layout.addWidget(self.data_table)
        self.setLayout(layout)

        self.correspondences = None
        self.data = None

        self.comboboxFilter.currentTextChanged.connect(self.changeFilter)

    def setTable(self, project, img1idx, img2idx):

        self.correspondences = project.getImagePairCorrespondences(
            img1idx, img2idx)
        self.data = self.correspondences.data

        self.model = TableModel(self.data)
        self.sortfilter = QSortFilterProxyModel(self)
        self.sortfilter.setSourceModel(self.model)
        self.data_table.setModel(self.sortfilter)

        self.data_table.setVisible(False)
        self.data_table.verticalHeader().hide()
        self.data_table.resizeColumnsToContents()
        self.data_table.setVisible(True)

        self.data_table.setItemDelegateForColumn(5, self.combodelegate1)
        self.data_table.setItemDelegateForColumn(6, self.combodelegate2)
        self.data_table.setEditTriggers(QAbstractItemView.DoubleClicked)

        self.data_table.update()

        self.data_table.setStyleSheet(
            "QHeaderView::section { background-color: rgb(40,40,40) }")

    def updateData(self, corr):

        if corr is None:
            return

        self.correspondences = corr
        self.sortfilter.beginResetModel()
        self.model.beginResetModel()
        self.model._data = corr.data
        self.sortfilter.endResetModel()
        self.model.endResetModel()

        self.data_table.update()

    def selectRows(self, rows):
        self.data_table.clearSelection()

        indexes = [self.model.index(r, 0) for r in rows]
        mode = QItemSelectionModel.Select | QItemSelectionModel.Rows
        [
            self.data_table.selectionModel().select(index, mode)
            for index in indexes
        ]

        if len(rows) > 0:
            value = self.data_table.horizontalScrollBar().value()
            column = self.data_table.columnAt(value)
            self.data_table.scrollTo(self.data_table.model().index(
                rows[0], column))

    @pyqtSlot(QModelIndex)
    def getData(self, index):

        pass
        #column = index.column()
        #row = index.row()
        #self.data_table.model().index(row, column).data()

    @pyqtSlot(str)
    def changeFilter(self, txt):

        if self.data is None:
            return

        if txt == 'All':
            self.sortfilter.setFilterRegExp(QRegExp())
        else:
            self.sortfilter.setFilterKeyColumn(5)
            self.sortfilter.setFilterRegExp(txt.lower())
            self.sortfilter.setFilterRole(Qt.DisplayRole)

        self.filterChanged.emit(txt.lower())
class ScanTableWidget(QWidget):
    """
    Used for displaying information in a table.

    ===============================  =========================================
    **Signals:**
    sigScanClicked                   Emitted when the user has clicked
                                     on a row of the table and returns the
                                     current index. This index contains
                                     information about the current rows column
                                     data.

    ===============================  =========================================
    """

    sigScanClicked = pyqtSignal(QModelIndex, name="scanClicked")

    header = [
        "MS level",
        "Index",
        "RT (min)",
        "precursor m/z",
        "charge",
        "ID",
        "PeptideSeq",
        "PeptideIons",
    ]

    def __init__(self, ms_experiment, *args):
        QWidget.__init__(self, *args)
        self.ms_experiment = ms_experiment

        self.table_model = ScanTableModel(self, self.ms_experiment,
                                          self.header)
        self.table_view = QTableView()

        # register a proxy class for filering and sorting the scan table
        self.proxy = QSortFilterProxyModel(self)
        self.proxy.setSourceModel(self.table_model)

        self.table_view.sortByColumn(1, Qt.AscendingOrder)

        # setup selection model
        self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_view.setModel(self.proxy)
        self.table_view.setSelectionModel(QItemSelectionModel(self.proxy))

        # header
        self.horizontalHeader = self.table_view.horizontalHeader()
        self.horizontalHeader.sectionClicked.connect(self.onHeaderClicked)

        # enable sorting
        self.table_view.setSortingEnabled(True)

        # connect signals to slots
        self.table_view.selectionModel().currentChanged.connect(
            self.onCurrentChanged)  # keyboard moves to new row
        self.horizontalHeader.sectionClicked.connect(self.onHeaderClicked)

        layout = QVBoxLayout(self)
        layout.addWidget(self.table_view)
        self.setLayout(layout)

        # hide column 7 with the PepIon data, intern information usage
        self.table_view.setColumnHidden(7, True)

        # Add rt in minutes for better TIC interaction
        self.table_view.setItemDelegateForColumn(2, RTUnitDelegate(self))
        self.table_view.setColumnWidth(2, 160)

        # default : first row selected. in OpenMSWidgets

    def onRowSelected(self, index):
        """se_comment: hard-refactoring to comply to pep8"""
        if index.siblingAtColumn(1).data() is None:
            return  # prevents crash if row gets filtered out
        self.curr_spec = self.ms_experiment.getSpectrum(
            index.siblingAtColumn(1).data())
        self.scanClicked.emit(index)

    def onCurrentChanged(self, new_index, old_index):
        self.onRowSelected(new_index)

    def onHeaderClicked(self, logicalIndex):
        if logicalIndex != 0:
            return  # allow filter on first column only for now

        self.logicalIndex = logicalIndex
        self.menuValues = QMenu(self)
        self.signalMapper = QSignalMapper(self)

        # get unique values from (unfiltered) model
        valuesUnique = set([
            self.table_model.index(row, self.logicalIndex).data()
            for row in range(
                self.table_model.rowCount(
                    self.table_model.index(-1, self.logicalIndex)))
        ])

        if len(valuesUnique) == 1:
            return  # no need to select anything

        actionAll = QAction("Show All", self)
        actionAll.triggered.connect(self.onShowAllRows)
        self.menuValues.addAction(actionAll)
        self.menuValues.addSeparator()
        """se_comment: hard-refactoring to comply to pep8"""
        l: enumerate = enumerate(sorted(list(set(valuesUnique))))
        for actionNumber, actionName in l:
            action = QAction(actionName, self)
            self.signalMapper.setMapping(action, actionNumber)
            action.triggered.connect(self.signalMapper.map)
            self.menuValues.addAction(action)

        self.signalMapper.mapped.connect(self.onSignalMapper)

        # get screen position of table header and open menu
        headerPos = self.table_view.mapToGlobal(self.horizontalHeader.pos())
        posY = headerPos.y() + self.horizontalHeader.height()
        posX = headerPos.x() + \
            self.horizontalHeader.sectionPosition(self.logicalIndex)
        self.menuValues.exec_(QPoint(posX, posY))

    def onShowAllRows(self):
        filterColumn = self.logicalIndex
        filterString = QRegExp("", Qt.CaseInsensitive, QRegExp.RegExp)

        self.proxy.setFilterRegExp(filterString)
        self.proxy.setFilterKeyColumn(filterColumn)

    def onSignalMapper(self, i):
        stringAction = self.signalMapper.mapping(i).text()
        filterColumn = self.logicalIndex
        filterString = QRegExp(stringAction, Qt.CaseSensitive,
                               QRegExp.FixedString)

        self.proxy.setFilterRegExp(filterString)
        self.proxy.setFilterKeyColumn(filterColumn)
Exemplo n.º 37
0
class FilterableTable(SQLTable):
    """a filterable Table Widget that displays content of an SQLite table;
    for individual widgets, subclass 
     and overwrite the create_model method;
    add_color_proxy should be an (INT allele_status-column, INT lab_status-column) tuple
    """
    def __init__(self, log, mydb = ": memory :", add_color_proxy = False, header_dic = None):
        super().__init__(log, mydb)
        self.add_color_proxy = add_color_proxy
        self.header_dic = header_dic
        self.create_model()
        self.fill_UI()
        self.create_filter_model()
        self.update_filterbox()
        
    def fill_UI(self):
        """sets up the layout
        """
        self.log.debug("\t- Setting up the table...")
        self.table = QTableView()
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.header = self.table.horizontalHeader() # table header
        self.header.setSectionResizeMode(QHeaderView.ResizeToContents)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setAlternatingRowColors(True)
#         self.header.sectionClicked.connect(self.on_header_sectionClicked)
        
        mode = QAbstractItemView.SingleSelection
        self.table.setSelectionMode(mode)
        
        self.grid.addWidget(self.table, 2, 0, 10, 10)

        self.filter_lbl = QLabel("Filter:", self)
        self.grid.addWidget(self.filter_lbl, 1, 2)
        
        self.filter_entry = QLineEdit(self)
        self.grid.addWidget(self.filter_entry, 1, 3)
        self.filter_entry.textChanged.connect(self.on_filter_entry_textChanged)
        self.filter_text = ""
        
        self.filter_cb = QComboBox(self)
        self.grid.addWidget(self.filter_cb, 1, 4)
        self.filter_cb.currentIndexChanged.connect(self.on_filter_cb_IndexChanged)
        
        self.filter_btn = QPushButton("Filter!", self)
        self.grid.addWidget(self.filter_btn, 1, 5)
        self.filter_btn.clicked.connect(self.on_filter_btn_clicked)
        
        self.unfilter_btn = QPushButton("Remove Filter", self)
        self.grid.addWidget(self.unfilter_btn, 1, 6)
        self.unfilter_btn.clicked.connect(self.on_actionAll_triggered)
        
        self.log.debug("\t=> Done!")
    
    def update_filterbox(self):
        """fills the filter-combobox with the header values 
        after the model has been created and set
        """
        column_num = self.model.columnCount()
        if self.header_dic:
            columns = [self.header_dic[i] for i in self.header_dic]
        else:
            columns = [self.proxy.headerData(i, Qt.Horizontal) for i in range(column_num)]
        self.filter_cb.addItems(columns)

    def create_filter_model(self):
        """creates the filter-proxy-model on top of self.model
        """
        self.log.debug("Creating filter model...")
        self.proxy = QSortFilterProxyModel(self)
        if self.add_color_proxy:
            (allele_status_column, lab_status_column) = self.add_color_proxy
            self.log.debug("adding color filter to columns {} and {}".format(allele_status_column, lab_status_column))
            self.color_proxy = ColorProxyModel(self, allele_status_column, lab_status_column)
            self.color_proxy.setSourceModel(self.model)
            self.proxy.setSourceModel(self.color_proxy)
        else:
            self.proxy.setSourceModel(self.model)
        self.table.setSortingEnabled(True)
        self.table.setModel(self.proxy)
        
    def on_filter_cb_IndexChanged(self, index):
        """restricts RegEx filter to selected column
        """
        self.log.debug("Combobox: colum {} selected".format(index))
        self.proxy.setFilterKeyColumn(index)
    
    def on_filter_entry_textChanged(self, text):
        """stores content of filter_entry as self.text 
        """
        self.log.debug("filter text: '{}'".format(text))
        self.filter_text = text
    
    def on_filter_btn_clicked(self):
        """activates RegEx filter to current content of filter_entry and filter_cb
        """
        column = self.filter_cb.currentIndex()
        self.log.debug("Filtering column {} for '{}'".format(column, self.filter_text))
        self.proxy.setFilterKeyColumn(column)
        search = QRegExp(self.filter_text, Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(search)
    
    def on_header_sectionClicked(self, logicalIndex):
        """opens a dialog to choose between all unique values for this column,
        or revert to 'All'
        """
        self.log.debug("Header clicked: column {}".format(logicalIndex))
        self.logicalIndex = logicalIndex
        menuValues = QMenu(self)
        self.signalMapper = QSignalMapper(self)  
  
        self.filter_cb.setCurrentIndex(self.logicalIndex)
        self.filter_cb.blockSignals(True)
        self.proxy.setFilterKeyColumn(self.logicalIndex)
        
        valuesUnique = [str(self.model.index(row, self.logicalIndex).data())
                        for row in range(self.model.rowCount())
                        ]
        
        actionAll = QAction("All", self)
        actionAll.triggered.connect(self.on_actionAll_triggered)
        menuValues.addAction(actionAll)
        menuValues.addSeparator()
        
        for actionNumber, actionName in enumerate(sorted(list(set(valuesUnique)))):              
            action = QAction(actionName, self)
            self.signalMapper.setMapping(action, actionNumber)  
            action.triggered.connect(self.signalMapper.map)  
            menuValues.addAction(action)
  
        self.signalMapper.mapped.connect(self.on_signalMapper_mapped)  
  
        headerPos = self.table.mapToGlobal(self.header.pos())        
        posY = headerPos.y() + self.header.height()
        posX = headerPos.x() + self.header.sectionViewportPosition(self.logicalIndex)
  
        menuValues.exec_(QPoint(posX, posY))
      
    def on_actionAll_triggered(self):
        """reverts table to unfiltered state
        """
        self.log.debug("Unfiltering...")
        filterString = QRegExp("", Qt.CaseInsensitive, QRegExp.RegExp)
        self.proxy.setFilterRegExp(filterString)
        self.filter_entry.setText("")
  
    def on_signalMapper_mapped(self, i):
        """filters current column to mapping text
        """
        text = self.signalMapper.mapping(i).text()
        self.log.debug("Filtering column {} to '{}'".format(self.logicalIndex, text))
        filterString = QRegExp(text, Qt.CaseSensitive, QRegExp.FixedString)
        self.proxy.setFilterRegExp(filterString)