class StampTableWidget(StampTableView):

    addStampSignal = pyqtSignal(str)
    # deleteStampSignal = pyqtSignal()
    surveyModeSignal = pyqtSignal(bool)

    def __init__(self):
        super().__init__()
        self.hasSelection = False  # todo
        self.surveyDatetime = None

        # init table model
        self.stampTableModel = QSqlRelationalTableModel()
        self.stampTableModel.setTable(R.tableName)
        self.stampTableModel.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.stampTableModel.setFilter("survey_datetime = None")
        self.stampTableModel.select()
        self.stampTableView.setModel(self.stampTableModel)
        self.stampTableSelectionModel = self.stampTableView.selectionModel()
        self.stampTableSelectionModel.selectionChanged.connect(
            self.onStampSelectionChange)

        # connect buttons
        self.addStampButton.clicked.connect(
            lambda ignore, key="-": self.addStampSignal.emit(key))
        self.deleteStampButton.clicked.connect(self.deleteButtonAction)
        self.hotkeyButton.clicked.connect(self.enableHotkeys)
        # self.recordButton.clicked.connect(self.surveyMode)

        # hotkeys
        self.hotkeys = self.initHotkeys()

        # copy selection to clipboard
        self.installEventFilter(self)

    def eventFilter(self, source, event):
        if (event.type() == QEvent.KeyPress
                and event.matches(QKeySequence.Copy)):
            self.copySelection()
            return True
        return super().eventFilter(source, event)

    def copySelection(self):
        selection = self.stampTableView.selectedIndexes()
        if selection:
            rows = sorted(index.row() for index in selection)
            columns = sorted(index.column() for index in selection)
            rowcount = rows[-1] - rows[0] + 1
            colcount = columns[-1] - columns[0] + 1
            table = [[''] * colcount for _ in range(rowcount)]
            for index in selection:
                row = index.row() - rows[0]
                column = index.column() - columns[0]
                table[row][column] = index.data()
            stream = io.StringIO()
            csv.writer(stream).writerows(table)
            QApplication.clipboard().setText(stream.getvalue())

    def initHotkeys(self):
        keyList = []

        shortcut = QShortcut(
            QKeySequence(Qt.Key_Space, QKeySequence.NativeText), self)
        keyList.append(shortcut)
        shortcut.activated.connect(
            lambda key="-": self.addStampSignal.emit(key))

        for i in range(0, 10):
            print(i)
            shortcut = QShortcut(QKeySequence(str(i), QKeySequence.NativeText),
                                 self)
            keyList.append(shortcut)
            shortcut.activated.connect(
                lambda key=str(i): self.addStampSignal.emit(key))
        return keyList

    def enableHotkeys(self, isClicked):
        for shortcut in self.hotkeys:
            shortcut.setEnabled(isClicked)

    def onDeselection(self):
        self.enableHotkeys(False)
        self.hotkeyButton.setChecked(False)

    # TODO delete
    def testHotKey(self, key):
        print("test")
        print(key)

    # TODO maybe repaint
    def loadSurveyStamps(self, keys):
        print("LSS")
        self.surveyDatetime = keys[0]
        filter = self.createFilter(keys)
        self.stampTableModel.setFilter(filter)
        self.stampTableModel.select()
        print("survey_datetime = " + self.surveyDatetime)
        QApplication.processEvents()
        self.repaint()

    def createFilter(self, keys):
        filter = "survey_datetime = \"" + self.surveyDatetime + "\""
        for i in range(1, len(keys)):
            filter = filter + " OR survey_datetime = \"" + keys[i] + "\""
        print(filter)
        return filter

    @pyqtSlot()
    def deleteButtonAction(self):
        for row in self.stampTableSelectionModel.selectedRows():
            self.stampTableModel.removeRow(row.row())
        self.stampTableSelectionModel.clearSelection()
        self.stampTableModel.select()
        QApplication.processEvents()

    def clearSurveyStamps(self):
        self.surveyDatetime = None
        # self.stampTableModel.setFilter("") # TODO will this work?
        self.stampTableModel.setFilter("survey_datetime = None")
        print("survey_datetime = None")

    def addStamp(self, stamp, key="-"):
        stampRecord = StampRecord(miliseconds=stamp,
                                  surveyDatetime=self.surveyDatetime,
                                  label=key,
                                  note="")
        sqlRecord = stampRecord.getQSQLRecord(self.stampTableModel.record())
        self.stampTableModel.insertRecord(0, sqlRecord)
        # self.surveyWidget.sortByKey()
        # self.surveyWidget.select(0)
        QApplication.processEvents()  # allow for selection highlight

    def addRecord(self, stampRecord):
        sqlRecord = stampRecord.getQSQLRecord(self.stampTableModel.record())
        print(self.stampTableModel.insertRowIntoTable(sqlRecord))

        # self.repaint() # TODO
        # self.surveyModeSignal.emit(modeOn)

    # @pyqtSlot(bool)
    # def enableSurvey(self, canSurvey):
    #     print(canSurvey)
    #     self.recordButton.setEnabled(canSurvey)

    @pyqtSlot()
    def testButtonAction(self):
        print("Test")

    @pyqtSlot(bool)
    def surveyMode(self, modeOn):
        self.addStampButton.setEnabled(modeOn)
        self.hotkeyButton.setEnabled(modeOn)
        self.enableHotkeys(self.hotkeyButton.isChecked())

    @pyqtSlot(QItemSelection)
    def onStampSelectionChange(self, selection):
        self.hasSelection = selection.count() > 0
        self.deleteStampButton.setEnabled(self.hasSelection)

    @pyqtSlot(bool)
    def enableStamps(self, modeOn):
        self.addStampButton.setEnabled(modeOn)
        self.hotkeyButton.setEnabled(modeOn)
        if not modeOn and self.hotkeyButton.isChecked():
            self.hotkeyButton.setChecked(False)
            self.enableHotkeys(False)
Пример #2
0
class MainForm(QDialog):
    def __init__(self):
        super(MainForm, self).__init__()

        self.assetModel = QSqlRelationalTableModel(self)
        self.assetModel.setTable("assets")
        self.assetModel.setRelation(CATEGORYID,
                                    QSqlRelation("categories", "id", "name"))
        self.assetModel.setSort(ROOM, Qt.AscendingOrder)
        self.assetModel.setHeaderData(ID, Qt.Horizontal, "ID")
        self.assetModel.setHeaderData(NAME, Qt.Horizontal, "Name")
        self.assetModel.setHeaderData(CATEGORYID, Qt.Horizontal, "Category")
        self.assetModel.setHeaderData(ROOM, Qt.Horizontal, "Room")
        self.assetModel.select()

        self.assetView = QTableView()
        self.assetView.setModel(self.assetModel)
        self.assetView.setItemDelegate(AssetDelegate(self))
        self.assetView.setSelectionMode(QTableView.SingleSelection)
        self.assetView.setSelectionBehavior(QTableView.SelectRows)
        self.assetView.setColumnHidden(ID, True)
        self.assetView.resizeColumnsToContents()
        assetLabel = QLabel("A&ssets")
        assetLabel.setBuddy(self.assetView)

        self.logModel = QSqlRelationalTableModel(self)
        self.logModel.setTable("logs")
        self.logModel.setRelation(ACTIONID,
                                  QSqlRelation("actions", "id", "name"))
        self.logModel.setSort(DATE, Qt.AscendingOrder)
        self.logModel.setHeaderData(DATE, Qt.Horizontal, "Date")
        self.logModel.setHeaderData(ACTIONID, Qt.Horizontal, "Action")
        self.logModel.select()

        self.logView = QTableView()
        self.logView.setModel(self.logModel)
        self.logView.setItemDelegate(LogDelegate(self))
        self.logView.setSelectionMode(QTableView.SingleSelection)
        self.logView.setSelectionBehavior(QTableView.SelectRows)
        self.logView.setColumnHidden(ID, True)
        self.logView.setColumnHidden(ASSETID, True)
        self.logView.resizeColumnsToContents()
        self.logView.horizontalHeader().setStretchLastSection(True)
        logLabel = QLabel("&Logs")
        logLabel.setBuddy(self.logView)

        addAssetButton = QPushButton("&Add Asset")
        deleteAssetButton = QPushButton("&Delete Asset")
        addActionButton = QPushButton("Add A&ction")
        deleteActionButton = QPushButton("Delete Ac&tion")
        editActionsButton = QPushButton("&Edit Actions...")
        editCategoriesButton = QPushButton("Ed&it Categories...")
        quitButton = QPushButton("&Quit")
        for button in (addAssetButton, deleteAssetButton, addActionButton,
                       deleteActionButton, editActionsButton,
                       editCategoriesButton, quitButton):
            if MAC:
                button.setDefault(False)
                button.setAutoDefault(False)
            else:
                button.setFocusPolicy(Qt.NoFocus)

        dataLayout = QVBoxLayout()
        dataLayout.addWidget(assetLabel)
        dataLayout.addWidget(self.assetView, 1)
        dataLayout.addWidget(logLabel)
        dataLayout.addWidget(self.logView)
        buttonLayout = QVBoxLayout()
        buttonLayout.addWidget(addAssetButton)
        buttonLayout.addWidget(deleteAssetButton)
        buttonLayout.addWidget(addActionButton)
        buttonLayout.addWidget(deleteActionButton)
        buttonLayout.addWidget(editActionsButton)
        buttonLayout.addWidget(editCategoriesButton)
        buttonLayout.addStretch()
        buttonLayout.addWidget(quitButton)
        layout = QHBoxLayout()
        layout.addLayout(dataLayout, 1)
        layout.addLayout(buttonLayout)
        self.setLayout(layout)

        #self.connect(self.assetView.selectionModel(),
        #SIGNAL(("currentRowChanged(QModelIndex,QModelIndex)")),
        #self.assetChanged)
        self.assetView.selectionModel().currentRowChanged.connect(
            self.assetChanged)
        addAssetButton.clicked.connect(self.addAsset)
        deleteAssetButton.clicked.connect(self.deleteAsset)
        addActionButton.clicked.connect(self.addAction)
        deleteActionButton.clicked.connect(self.deleteAction)
        editActionsButton.clicked.connect(self.editActions)
        editCategoriesButton.clicked.connect(self.editCategories)
        quitButton.clicked.connect(self.done)

        self.assetChanged(self.assetView.currentIndex())
        self.setMinimumWidth(650)
        self.setWindowTitle("Asset Manager")

    def done(self, result=1):
        query = QSqlQuery()
        query.exec_("DELETE FROM logs WHERE logs.assetid NOT IN"
                    "(SELECT id FROM assets)")
        QDialog.done(self, 1)

    def assetChanged(self, index):
        if index.isValid():
            record = self.assetModel.record(index.row())
            #print(index.row())
            id = record.value("id")
            self.logModel.setFilter("assetid = {0}".format(id))
        else:
            self.logModel.setFilter("assetid = -1")
        #self.logModel.reset() # workaround for Qt <= 4.3.3/SQLite bug
        #self.logModel.beginResetModel()
        self.logModel.select()
        self.logView.horizontalHeader().setVisible(
            self.logModel.rowCount() > 0)
        if PYQT_VERSION_STR < "4.1.0":
            self.logView.setColumnHidden(ID, True)
            self.logView.setColumnHidden(ASSETID, True)
        #self.logModel.endResetModel()

    def addAsset(self):
        row = (self.assetView.currentIndex().row()
               if self.assetView.currentIndex().isValid() else 0)

        QSqlDatabase.database().transaction()
        self.assetModel.insertRow(row)
        index = self.assetModel.index(row, NAME)
        self.assetView.setCurrentIndex(index)

        assetid = 1
        query = QSqlQuery()
        query.exec_("SELECT MAX(id) FROM assets")
        if query.next():
            assetid = query.value(0)
        query.prepare("INSERT INTO logs (assetid, date, actionid) "
                      "VALUES (:assetid, :date, :actionid)")
        query.bindValue(":assetid", assetid + 1)
        query.bindValue(":date", QDate.currentDate())
        query.bindValue(":actionid", ACQUIRED)
        query.exec_()
        QSqlDatabase.database().commit()
        #self.logModel.select()
        self.assetView.edit(index)

    def deleteAsset(self):
        index = self.assetView.currentIndex()
        if not index.isValid():
            return
        QSqlDatabase.database().transaction()
        record = self.assetModel.record(index.row())
        assetid = record.value(ID)
        logrecords = 1
        query = QSqlQuery(
            "SELECT COUNT(*) FROM logs WHERE assetid = {0}".format(assetid))
        if query.next():
            logrecords = query.value(0)
        msg = ("<font color=red>Delete</font><br><b>{0}</b>"
               "<br>from room {1}").format(record.value(NAME),
                                           record.value(ROOM))
        if logrecords > 1:
            msg += (", along with {0} log records".format(logrecords))
        msg += "?"
        if (QMessageBox.question(self, "Delete Asset", msg, QMessageBox.Yes
                                 | QMessageBox.No) == QMessageBox.No):
            QSqlDatabase.database().rollback()
            return
        #query.exec_("DELETE FROM logs WHERE assetid = {0}"
        #             .format(assetid))

        #use model API
        self.logModel.setFilter("assetid={0}".format(assetid))
        self.logModel.select()
        if self.logModel.rowCount() > 0:
            self.logModel.removeRows(0, self.logModel.rowCount())
            self.logModel.submitAll()

        self.assetModel.removeRow(index.row())
        self.assetModel.submitAll()
        QSqlDatabase.database().commit()
        self.assetModel.select()
        self.assetChanged(self.assetView.currentIndex())

    def addAction(self):
        index = self.assetView.currentIndex()
        if not index.isValid():
            return
        QSqlDatabase.database().transaction()
        record = self.assetModel.record(index.row())
        assetid = record.value(ID)

        row = self.logModel.rowCount()
        self.logModel.insertRow(row)
        self.logModel.setData(self.logModel.index(row, ASSETID), assetid)
        self.logModel.setData(self.logModel.index(row, DATE),
                              QDate.currentDate())
        QSqlDatabase.database().commit()
        index = self.logModel.index(row, ACTIONID)
        self.logView.setCurrentIndex(index)
        self.logView.edit(index)

    def deleteAction(self):
        index = self.logView.currentIndex()
        if not index.isValid():
            return
        record = self.logModel.record(index.row())
        action = record.value(ACTIONID)
        if action == "Acquired":
            QMessageBox.information(
                self, "Delete Log",
                "The 'Acquired' log record cannot be deleted.<br>"
                "You could delete the entire asset instead.")
            return
        when = str(record.value(DATE))
        if (QMessageBox.question(self, "Delete Log",
                                 "Delete log<br>{0} {1}?".format(when, action),
                                 QMessageBox.Yes
                                 | QMessageBox.No) == QMessageBox.No):
            return
        self.logModel.removeRow(index.row())
        self.logModel.submitAll()
        self.logModel.select()

    def editActions(self):
        form = ReferenceDataDlg("actions", "Action", self)
        form.exec_()

    def editCategories(self):
        form = ReferenceDataDlg("categories", "Category", self)
        form.exec_()
Пример #3
0
class QmyMainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)  #调用父类构造函数,创建窗体
        self.ui = Ui_MainWindow()  #创建UI对象
        self.ui.setupUi(self)  #构造UI界面

        self.setCentralWidget(self.ui.tableView)

        #   tableView显示属性设置
        self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectItems)
        self.ui.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.ui.tableView.setAlternatingRowColors(True)

        self.ui.tableView.verticalHeader().setDefaultSectionSize(22)
        self.ui.tableView.horizontalHeader().setDefaultSectionSize(100)

##  ==============自定义功能函数============

    def __getFieldNames(self):  ##获取所有字段名称
        emptyRec = self.tabModel.record()  #获取空记录,只有字段名
        self.fldNum = {}  #字段名与序号的字典
        for i in range(emptyRec.count()):
            fieldName = emptyRec.fieldName(i)
            self.fldNum.setdefault(fieldName)
            self.fldNum[fieldName] = i
        print(self.fldNum)

    def __openTable(self):  ##打开数据表
        self.tabModel = QSqlRelationalTableModel(self, self.DB)  #数据表

        self.tabModel.setTable("studInfo")  #设置数据表
        self.tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit
                                      )  #数据保存方式,OnManualSubmit , OnRowChange
        self.tabModel.setSort(self.tabModel.fieldIndex("studID"),
                              Qt.AscendingOrder)  #排序

        if (self.tabModel.select() == False):  #查询数据失败
            QMessageBox.critical(
                self, "错误信息",
                "打开数据表错误,错误信息\n" + self.tabModel.lastError().text())
            return

        self.__getFieldNames()  #获取字段名和序号

        ##字段显示名
        self.tabModel.setHeaderData(self.fldNum["studID"], Qt.Horizontal, "学号")
        self.tabModel.setHeaderData(self.fldNum["name"], Qt.Horizontal, "姓名")
        self.tabModel.setHeaderData(self.fldNum["gender"], Qt.Horizontal, "性别")
        self.tabModel.setHeaderData(self.fldNum["departID"], Qt.Horizontal,
                                    "学院")
        self.tabModel.setHeaderData(self.fldNum["majorID"], Qt.Horizontal,
                                    "专业")

        ##    设置代码字段的查询关系数据表
        self.tabModel.setRelation(self.fldNum["departID"],
                                  QSqlRelation("departments", "departID",
                                               "department"))  #学院
        self.tabModel.setRelation(self.fldNum["majorID"],
                                  QSqlRelation("majors", "majorID",
                                               "major"))  #专业

        self.selModel = QItemSelectionModel(self.tabModel)  #关联选择模型

        ##selModel当前项变化时触发currentChanged信号
        self.selModel.currentChanged.connect(self.do_currentChanged)
        ##选择行变化时
        ##      self.selModel.currentRowChanged.connect(self.do_currentRowChanged)

        self.ui.tableView.setModel(self.tabModel)  #设置数据模型
        self.ui.tableView.setSelectionModel(self.selModel)  #设置选择模型

        delgate = QSqlRelationalDelegate(self.ui.tableView)
        self.ui.tableView.setItemDelegate(delgate)  #为关系型字段设置缺省代理组件

        self.tabModel.select()  #必须重新查询数据
        ##更新actions和界面组件的使能状态
        self.ui.actOpenDB.setEnabled(False)

        self.ui.actRecAppend.setEnabled(True)
        self.ui.actRecInsert.setEnabled(True)
        self.ui.actRecDelete.setEnabled(True)
        self.ui.actFields.setEnabled(True)

##  ==========由connectSlotsByName() 自动连接的槽函数==================

    @pyqtSlot()
    def on_actOpenDB_triggered(self):
        dbFilename, flt = QFileDialog.getOpenFileName(
            self, "选择数据库文件", "", "SQL Lite数据库(*.db *.db3)")
        if (dbFilename == ''):
            return

        #打开数据库
        self.DB = QSqlDatabase.addDatabase("QSQLITE")  #添加 SQL LITE数据库驱动
        self.DB.setDatabaseName(dbFilename)  #设置数据库名称
        ##    DB.setHostName()
        ##    DB.setUserName()
        ##    DB.setPassword()
        if self.DB.open():  #打开数据库
            self.__openTable()  #打开数据表
        else:
            QMessageBox.warning(self, "错误", "打开数据库失败")

    @pyqtSlot()  ##保存修改
    def on_actSubmit_triggered(self):
        res = self.tabModel.submitAll()
        if (res == False):
            QMessageBox.information(
                self, "消息", "数据保存错误,错误信息\n" + self.tabModel.lastError().text())
        else:
            self.ui.actSubmit.setEnabled(False)
            self.ui.actRevert.setEnabled(False)

    @pyqtSlot()  ##取消修改
    def on_actRevert_triggered(self):
        self.tabModel.revertAll()
        self.ui.actSubmit.setEnabled(False)
        self.ui.actRevert.setEnabled(False)

    @pyqtSlot()  ##添加记录
    def on_actRecAppend_triggered(self):
        self.tabModel.insertRow(self.tabModel.rowCount(),
                                QModelIndex())  #在末尾添加一个记录
        curIndex = self.tabModel.index(self.tabModel.rowCount() - 1,
                                       1)  #创建最后一行的ModelIndex
        self.selModel.clearSelection()  #清空选择项
        self.selModel.setCurrentIndex(
            curIndex, QItemSelectionModel.Select)  #设置刚插入的行为当前选择行

    @pyqtSlot()  ##插入记录
    def on_actRecInsert_triggered(self):
        curIndex = self.ui.tableView.currentIndex()  #QModelIndex
        self.tabModel.insertRow(curIndex.row(), QModelIndex())
        self.selModel.clearSelection()  #清除已有选择
        self.selModel.setCurrentIndex(curIndex, QItemSelectionModel.Select)

    @pyqtSlot()  ##删除记录
    def on_actRecDelete_triggered(self):
        curIndex = self.selModel.currentIndex()  #获取当前选择单元格的模型索引
        self.tabModel.removeRow(curIndex.row())  #删除最后一行

    @pyqtSlot()  ##显示字段列表
    def on_actFields_triggered(self):
        emptyRec = self.tabModel.record()  #获取空记录,只有字段名
        str = ''
        for i in range(emptyRec.count()):
            str = str + emptyRec.fieldName(i) + '\n'
        QMessageBox.information(self, "所有字段名", str)

##  =============自定义槽函数===============================

    def do_currentChanged(self, current, previous):  ##更新actPost和actCancel 的状态
        self.ui.actSubmit.setEnabled(self.tabModel.isDirty())  #有未保存修改时可用
        self.ui.actRevert.setEnabled(self.tabModel.isDirty())
class SurveyTableWidget(SurveyTableView):

    combineSignal = pyqtSignal()
    addSurveySignal = pyqtSignal()
    editSurveySignal = pyqtSignal()
    loadSurveyAudioSignal = pyqtSignal()
    selectionChangeSignal = pyqtSignal()

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

        # init table model TODO: make vars private
        self.surveyTableModel = QSqlRelationalTableModel()
        self.surveyTableModel.setTable(R.tableName)
        self.surveyTableModel.setEditStrategy(QSqlTableModel.OnRowChange)
        self.surveyTableModel.select()
        self.surveyTableView.setModel(self.surveyTableModel)
        self.surveyTableSelectionModel = self.surveyTableView.selectionModel()
        self.surveyTableSelectionModel.selectionChanged.connect(
            self.onSurveySelectionChange)

        self.surveyTableView.horizontalHeader().sortIndicatorChanged.connect(
            self.onSurveySelectionChange)  # TODO

        # connect buttons
        self.addSurveyButton.clicked.connect(self.addSurveySignal.emit)
        self.editSurveyButton.clicked.connect(self.editSurveySignal.emit)
        self.deleteSurveyButton.clicked.connect(self.deleteSurveyButtonAction)
        self.loadAudioButton.clicked.connect(self.loadSurveyAudioSignal.emit)
        self.combineButton.clicked.connect(self.combineSignal.emit)

    # info to populate AddSurveyDialog
    def getDialogArgs(self):
        recorderIds = []
        query = QSqlQuery("SELECT DISTINCT recorder_id FROM survey")

        while query.next():
            print(query.value(0))

        kwargs = {"recorderIds": recorderIds}
        return kwargs

    def select(self, index):
        self.surveyTableView.selectRow(index)

    def sortByKey(self):
        self.surveyTableView.sortByColumn(0, Qt.DescendingOrder)

    # TODO: keep selection after sort
    def onSort(self):
        pass

    def getSelectedRows(self):
        return self.surveyTableSelectionModel.selectedRows()

    def onPlaylistMediaChange(self, hasMedia):
        self.addSurveyButton.setEnabled(hasMedia)
        self.selectionChangeSignal.emit()

    def getSelectedData(self, row=0, column=Column.SURVEY_DATETIME):
        key = self.getSelectedRows()[row]
        return self.surveyTableModel.data(key.sibling(key.row(), column.value))

    def getDataFromKey(self, keyIndex, column=Column.SURVEY_DATETIME):
        return self.surveyTableModel.data(
            keyIndex.sibling(keyIndex.row(), column.value))

    def getSelectedKeys(self):
        list = []
        for row in self.getSelectedRows():
            list.append(str(self.surveyTableModel.data(row)))
        return list

    def singlePathSelected(self):
        if len(self.getSelectedRows()) > 0:
            firstPath = self.getDataFromKey(self.getSelectedRows()[0],
                                            Column.FILE)
            for row in self.getSelectedRows():  # self.getSelectedRows():
                if self.getDataFromKey(row, Column.FILE) != firstPath:
                    return None
            return firstPath
        return None

    def addRecord(self, record):
        sqlRecord = record.getQSQLRecord(self.surveyTableModel.record())
        self.surveyTableModel.insertRecord(0, sqlRecord)
        self.sortByKey()
        self.select(0)
        QApplication.processEvents()  # allow for selection highlight

    def editRecord(self, record):
        index = self.getSelectedRows()[0]
        record.editData(model=self.surveyTableModel, index=index)
        QApplication.processEvents()  # TODO maybe remove

    @pyqtSlot()
    def deleteSurveyButtonAction(self):
        for row in self.getSelectedRows():
            self.surveyTableModel.removeRow(row.row())
        self.surveyTableSelectionModel.clearSelection()
        self.surveyTableModel.select()
        QApplication.processEvents()

    @pyqtSlot()
    def onSurveySelectionChange(self):
        # enable/disable buttons then signal MainWindow
        selectionCount = len(self.getSelectedRows())
        self.deleteSurveyButton.setEnabled(selectionCount > 0)
        self.loadAudioButton.setEnabled(selectionCount > 0)
        self.editSurveyButton.setEnabled(selectionCount == 1)
        self.combineButton.setEnabled(
            selectionCount > 1 and self.singlePathSelected() is not None)
        self.selectionChangeSignal.emit()
Пример #5
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1200, 800)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(0, 0, 1200, 800))
        self.tabWidget.setObjectName("tabWidget")

        # TAB 1
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.tabWidget.addTab(self.tab, "")

        # Admin site integration
        self.webView = QtWebEngineWidgets.QWebEngineView(self.tab)
        self.webView.setUrl(QtCore.QUrl("http://185.188.182.76:8000/admin"))
        self.webView.resize(1200, 800)
        self.webView.setObjectName("webView")

        # TAB 2
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")

        # Desktop Database integration
        self.devices_table = QtWidgets.QTableView(self.tab_2)
        self.devices_table.setGeometry(QtCore.QRect(0, 0, 1200, 800))
        self.devices_table.setObjectName("tableView")

        self.devices_table_UI()

        self.add_record()  # !!!

        last_month_day = calendar.monthrange(int(strftime("%Y", gmtime())),
                                             int(strftime("%m", gmtime())))[1]
        today = strftime("%d", gmtime())
        if last_month_day == today:
            self.add_record()

        self.tabWidget.addTab(self.tab_2, "")

        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        MainWindow.setWindowIcon(QtGui.QIcon('label.ico'))

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(1)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def devices_table_UI(self):
        conn = sqlite3.connect("database.db")
        c = conn.cursor()
        c.execute(
            "CREATE TABLE IF NOT EXISTS devices(id INTEGER PRIMARY KEY AUTOINCREMENT, mac_address TEXT, os_version TEXT, architecture TEXT, locale TEXT, timezone TEXT, last_update TEXT)"
        )
        c.close()

        self.devices_model = QSqlRelationalTableModel(db=createConnection())
        self.devices_model.setTable('devices')
        self.devices_model.select()

        # self.drivers_table.setEditTriggers(QAbstractItemView.CurrentChanged)
        self.devices_table.setModel(self.devices_model)
        self.devices_table.hideColumn(self.devices_model.fieldIndex('id'))

        # Делаем ресайз колонок по содержимому
        self.devices_table.resizeColumnsToContents()

    def add_record(self):
        rec = self.devices_model.record()
        data = [
            get_mac(),  # mac-address
            platform.platform(),
            platform.machine(),
            locale.getdefaultlocale()[0],
            str(timezone / 3600.0),
            strftime("%Y-%m-%d %H:%M:%S", gmtime())
        ]
        for i in range(len(data)):
            rec.setValue(rec.field(i + 1).name(), data[i])
        self.devices_model.insertRecord(-1, rec)
        self.devices_model.submit()
        self.devices_model.select()
        self.devices_table.resizeColumnsToContents()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow",
                                             "Polydroid Desktop"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),
                                  _translate("MainWindow", "AdminSite"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),
                                  _translate("MainWindow", "Desktop DB"))
Пример #6
0
class QmyMainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setCentralWidget(self.ui.tableView)

        self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectItems)
        self.ui.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.ui.tableView.setAlternatingRowColors(True)

        self.ui.tableView.verticalHeader().setDefaultSectionSize(22)
        self.ui.tableView.horizontalHeader().setDefaultSectionSize(100)

    def __getFieldNames(self):
        emptyRec = self.tabModel.record()
        self.fldNum = {}
        for i in range(emptyRec.count()):
            fieldName = emptyRec.fieldName(i)
            self.fldNum.setdefault(fieldName)
            self.fldNum[fieldName] = i
        print(self.fldNum)

    def __openTable(self):
        self.tabModel = QSqlRelationalTableModel(self, self.DB)
        self.tabModel.setTable("studInfo")
        self.tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.tabModel.setSort(self.tabModel.fieldIndex("studID"),
                              Qt.AscendingOrder)

        if (self.tabModel.select() == False):
            QMessageBox.critical(
                self, "错误信息",
                "打开数据表错误,错误信息\n" + self.tabModel.lastError().text())
            return

        self.__getFieldNames()
        self.tabModel.setHeaderData(self.fldNum["studID"], Qt.Horizontal, "学号")
        self.tabModel.setHeaderData(self.fldNum["name"], Qt.Horizontal, "姓名")
        self.tabModel.setHeaderData(self.fldNum["gender"], Qt.Horizontal, "性别")
        self.tabModel.setHeaderData(self.fldNum["departID"], Qt.Horizontal,
                                    "学院")
        self.tabModel.setHeaderData(self.fldNum["majorID"], Qt.Horizontal,
                                    "专业")

        self.tabModel.setRelation(
            self.fldNum["departID"],
            QSqlRelation("departments", "departID", "department"))
        self.tabModel.setRelation(self.fldNum["majorID"],
                                  QSqlRelation("majors", "majorID", "major"))

        self.selModel = QItemSelectionModel(self.tabModel)
        self.selModel.currentChanged.connect(self.do_currentChanged)

        self.ui.tableView.setModel(self.tabModel)
        self.ui.tableView.setSelectionModel(self.selModel)

        delgate = QSqlRelationalDelegate(self.ui.tableView)
        self.ui.tableView.setItemDelegate(delgate)

        self.tabModel.select()

        self.ui.actOpenDB.setEnabled(False)
        self.ui.actRecAppend.setEnabled(True)
        self.ui.actRecInsert.setEnabled(True)
        self.ui.actRecDelete.setEnabled(True)
        self.ui.actFields.setEnabled(True)

    @pyqtSlot()
    def on_actOpenDB_triggered(self):
        dbFilename, flt = QFileDialog.getOpenFileName(
            self, "选择数据库文件", "", "SQL Lite数据库(*.db *.db3)")
        if (dbFilename == ''):
            return
        self.DB = QSqlDatabase.addDatabase("QSQLITE")
        self.DB.setDatabaseName(dbFilename)
        if self.DB.open():
            self.__openTable()
        else:
            QMessageBox.warning(self, "错误", "打开数据库失败了")

    @pyqtSlot()
    def on_actSubmit_triggered(self):
        res = self.tabModel.submitAll()
        if (res == False):
            QMessageBox.information(
                self, "消息", "数据保存错误,错误信息\n" + self.tabModel.lastError().text())
        else:
            self.ui.actSubmit.setEnabled(False)
            self.ui.actRevert.setEnabled(False)

    @pyqtSlot()
    def on_actRevert_triggered(self):
        self.tabModel.revertAll()
        self.ui.actSubmit.setEnabled(False)
        self.ui.actRevert.setEnabled(False)

    @pyqtSlot()
    def on_actRecInsert_triggered(self):
        curIndex = self.ui.tableView.currentIndex()
        self.tabModel.insertRow(curIndex.row(), QModelIndex())
        self.selModel.clearSelection()
        self.selModel.setCurrentIndex(curIndex, QItemSelectionModel.Select)

    @pyqtSlot()
    def on_actRecDelete_triggered(self):
        curIndex = self.selModel.currentIndex()
        self.tabModel.removeRow(curIndex.row())

    @pyqtSlot()
    def on_actFields_triggered(self):
        emptyRec = self.tabModel.record()
        str = ''
        for i in range(emptyRec.count()):
            str = str + emptyRec.fieldName(i) + '\n'
        QMessageBox.information(self, "所有字段名", str)

    def do_currentChanged(self, current, previous):
        self.ui.actSubmit.setEnabled(self.tabModel.isDirty())
        self.ui.actRevert.setEnabled(self.tabModel.isDirty())
class APISSystemTableEditor(QDialog, FORM_CLASS):
    def __init__(self, dbm, parent=None):
        """Constructor."""
        self.dbm = dbm
        super(APISSystemTableEditor, self).__init__(parent)

        self.table = None
        self.model = None
        self.insertQuery = None
        self.updateQuery = None
        self.deleteQuery = None
        self.inputDialog = None

        self.setupUi(self)

        self.uiEditBtn.setEnabled(False)
        self.uiRemoveBtn.setEnabled(False)

        self.rejected.connect(self.onClose)

        self.setupTable()

    def setupTable(self):
        self.uiSystemTableV.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.uiSystemTableV.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.uiSystemTableV.resizeColumnsToContents()
        self.uiSystemTableV.resizeRowsToContents()
        self.uiSystemTableV.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)

    def onSelectionChanged(self):
        if self.uiSystemTableV.selectionModel().hasSelection():
            self.uiEditBtn.setEnabled(True)
            self.uiRemoveBtn.setEnabled(True)
        else:
            self.uiEditBtn.setEnabled(False)
            self.uiRemoveBtn.setEnabled(False)

    def loadTable(self, table):
        # check if table in db
        if not DbHasTable(self.dbm.db, table):
            return False

        self.table = table
        self.dbm.createTriggerForSystemTable(table)
        # TODO: if returns FALSE then deactivate editing Capabilites + Wanring

        self.uiSysTableLbl.setText(self.table)

        self.model = QSqlRelationalTableModel(self, self.dbm.db)
        self.model.setTable(table)
        self.model.select()
        #rc = self.model.rowCount()
        while (self.model.canFetchMore()):
            self.model.fetchMore()
            #rc = self.model.rowCount()

        self.uiSystemTableV.setModel(self.model)
        self.uiSystemTableV.selectionModel().selectionChanged.connect(
            self.onSelectionChanged)
        self.onSelectionChanged()

        # dummyRecord holds field structure!
        dummyRecord = self.model.record()
        editors = []
        for fIdx in range(dummyRecord.count()):
            field = dummyRecord.field(fIdx)
            if field.name() != "ogc_fid":
                editors.append({
                    'name': field.name(),
                    'type': field.type(),
                    'lineEdit': QLineEdit(),
                    'default': None
                })

        # init input dialog
        self.inputDialog = APISInputDialog(editors, dummyRecord, parent=self)
        self.uiAddBtn.clicked.connect(self.addRecord)
        self.uiEditBtn.clicked.connect(
            self.editRecord
        )  # in EditMode: load current Value; try to update (but with trigger: only possible to update if not in use!!!)
        self.uiRemoveBtn.clicked.connect(self.removeRecord)
        return True

    def addRecord(self):
        if self.inputDialog.exec_():
            rec = self.inputDialog.getRecord()
            if not rec.isEmpty():
                res = self.model.insertRowIntoTable(rec)
                if res:
                    self.model.select()
                    self.dbm.dbRequiresUpdate = True
                else:
                    QMessageBox.warning(
                        self, "DB Fehler",
                        "Der folgende Fehler ist aufgetreten: {}".format(
                            self.model.lastError().text()))
        else:
            pass
        self.inputDialog.resetEditors()

    def editRecord(self):
        recIdx = self.uiSystemTableV.selectionModel().currentIndex().row()
        # Get current Record for index
        currRec = self.model.record(recIdx)
        # Set current Record in Dialog
        self.inputDialog.setEditors(currRec)
        if self.inputDialog.exec_():
            data = self.inputDialog.getData()
            # QMessageBox.information(None, "edited record", f"{data}")
            for key in data:
                currRec.setValue(key, data[key])
            if not currRec.isEmpty():
                res = self.model.updateRowInTable(recIdx, currRec)
                if res:
                    self.model.select()
                    self.dbm.dbRequiresUpdate = True
                else:
                    QMessageBox.warning(
                        self, "DB Fehler",
                        "Der folgende Fehler ist aufgetreten: {}".format(
                            self.model.lastError().text()))
        self.inputDialog.resetEditors()

    def removeRecord(self):
        #Check if one really wants to remove the entry!
        # Abfrage wirklich löschen
        header = u"Eintrag löschen"
        question = u"Möchten Sie den Eintrag wirklich aus der Datenbank löschen?"
        result = QMessageBox.question(self, header, question,
                                      QMessageBox.Yes | QMessageBox.No,
                                      QMessageBox.Yes)
        if result == QMessageBox.Yes:
            recIdx = self.uiSystemTableV.selectionModel().currentIndex().row()
            # QMessageBox.information(self, "Information", f"Current Idx {recIdx}")
            res = self.model.removeRow(recIdx)
            if res:
                self.model.select()
                self.dbm.dbRequiresUpdate = True
            else:
                QMessageBox.warning(
                    self, "DB Fehler",
                    "Der folgende Fehler ist aufgetreten: {}".format(
                        self.model.lastError().text()))

    def onClose(self):
        '''
        Run some actions when
        the user closes the dialog
        '''
        self.uiAddBtn.clicked.disconnect(self.addRecord)
        self.uiEditBtn.clicked.disconnect(self.editRecord)
        self.uiRemoveBtn.clicked.disconnect(self.removeRecord)
        self.inputDialog.deleteLater()
class APISAdvancedInputDialog(QDialog):
    def __init__(self,
                 dbm,
                 tableName,
                 showEntriesCombo,
                 modelColumnName=None,
                 excludeEntries=None,
                 parent=None):
        super(APISAdvancedInputDialog, self).__init__(parent)

        self.dbm = dbm
        self.tableName = tableName
        self.modelColumnName = modelColumnName
        self.showEntriesCombo = showEntriesCombo
        self.excludeEntries = excludeEntries

        self.valueToBeAdded = None
        self.editors = None
        self.record = None
        self.tableExists = False

        if self.prepairEditorsAndRecord():
            self.setupForm()
        else:
            pass
            # something went wrong preping

    def prepairEditorsAndRecord(self):
        if not DbHasTable(self.dbm.db, self.tableName):
            return False

        self.tableExists = True

        self.model = QSqlRelationalTableModel(self, self.dbm.db)
        self.model.setTable(self.tableName)
        self.model.select()
        while (self.model.canFetchMore()):
            self.model.fetchMore()

        self.record = self.model.record()
        self.editors = []
        for fIdx in range(self.record.count()):
            field = self.record.field(fIdx)
            if field.name() != "ogc_fid":
                self.editors.append({
                    'name': field.name(),
                    'type': field.type(),
                    'lineEdit': QLineEdit()
                })

        return True

    def setupForm(self):
        layout = QFormLayout()

        if self.showEntriesCombo:
            self.uiAvailableEntriesCombo = QComboBox()
            # populate (but exlude if exclude has elements)

            if self.excludeEntries and len(self.excludeEntries) > 0:
                self.model.setFilter("{0} NOT IN ({1})".format(
                    self.modelColumnName,
                    ",".join("'{0}'".format(i) for i in self.excludeEntries)))
                # QMessageBox.information(self, "info", "{0} NOT IN ({1})".format(self.modelColumnName, ",".join("'{0}'".format(i) for i in self.excludeEntries)))
                # self.model.select()
            self.model.removeColumn(0)
            self.setupComboBox(self.uiAvailableEntriesCombo,
                               self.model.fieldIndex(self.modelColumnName))
            layout.addRow(self.uiAvailableEntriesCombo)

            self.uiAddBtn = QPushButton("Hinzufügen")
            if self.uiAvailableEntriesCombo.count() < 1:
                self.uiAddBtn.setEnabled(False)
            self.uiAddBtn.clicked.connect(self.addInputToSelection)
            layout.addRow(self.uiAddBtn)

        for editor in self.editors:
            # QMessageBox.information(self, "info", "{}".format((editor["name"])))
            if editor["name"] != "ogc_fid":
                label = QLabel(editor["name"])
                # QMessageBox.information(None, "info", "{}".format(editor["type"]))
                if editor["type"] == QVariant.Int:
                    intVal = QIntValidator()
                    intVal.setBottom(0)
                    editor['lineEdit'].setValidator(intVal)
                layout.addRow(label, editor['lineEdit'])
                editor['lineEdit'].textEdited.connect(self.onTextEdited)

        self.uiSubmitBtn = QPushButton("Speichern")
        self.uiSubmitBtn.setEnabled(False)
        self.uiSubmitBtn.clicked.connect(self.saveInputAsQSqlRecord)
        layout.addRow(self.uiSubmitBtn)
        self.setLayout(layout)
        self.setWindowTitle("APIS Input Dialog")
        self.adjustSize()

    def onTextEdited(self, text):
        for editor in self.editors:
            if len(editor['lineEdit'].text().replace(" ", "")) == 0:
                self.uiSubmitBtn.setEnabled(False)
                return
        self.uiSubmitBtn.setEnabled(True)

    def addInputToSelection(self):
        self.setValueToBeAdded(self.uiAvailableEntriesCombo.currentText())
        self.accept()

    def setValueToBeAdded(self, value):
        self.valueToBeAdded = value

    def getValueToBeAdded(self):
        return self.valueToBeAdded

    def saveInputAsQSqlRecord(self):
        for editor in self.editors:
            self.record.setValue(editor["name"], editor['lineEdit'].text())
        if not self.record.isEmpty():
            result = self.model.insertRowIntoTable(self.record)
            if result:
                self.setValueToBeAdded(
                    self.record.field(self.modelColumnName).value())
                self.accept()
            else:
                QMessageBox.warning(
                    self, "DB Fehler",
                    "Der folgende Feheler ist aufgetreten: {}".format(
                        self.model.lastError().text()))
                self.reject()
        else:
            self.reject()

    def setupComboBox(self, editor, modelColumn):
        tv = QTableView()
        editor.setView(tv)

        tv.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        tv.setSelectionMode(QAbstractItemView.SingleSelection)
        tv.setSelectionBehavior(QAbstractItemView.SelectRows)
        tv.setAutoScroll(False)

        editor.setModel(self.model)

        editor.setModelColumn(modelColumn)
        editor.setInsertPolicy(QComboBox.NoInsert)

        tv.resizeColumnsToContents()
        tv.resizeRowsToContents()
        tv.verticalHeader().setVisible(False)
        tv.horizontalHeader().setVisible(True)
        #tv.setMinimumWidth(tv.horizontalHeader().length())
        tv.horizontalHeader().setStretchLastSection(True)
        #tv.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
        tv.resizeColumnsToContents()
        scroll = 0 if editor.count() <= editor.maxVisibleItems(
        ) else QApplication.style().pixelMetric(QStyle.PM_ScrollBarExtent)
        tv.setMinimumWidth(tv.horizontalHeader().length() + scroll)