コード例 #1
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.splitter)
        self.__buildStatusBar()

        self.COL_COUNT = 6  #常数,列数=6
        self.itemModel = QStandardItemModel(5, self.COL_COUNT,
                                            self)  # 数据模型,10行6列

        ##      headerList=["测深(m)","垂深(m)","方位(°)","总位移(m)","固井质量","测井取样"]
        ##      self.itemModel.setHorizontalHeaderLabels(headerList) #设置表头文字

        self.selectionModel = QItemSelectionModel(self.itemModel)  #Item选择模型
        self.selectionModel.currentChanged.connect(self.do_currentChanged)
        self.__lastColumnFlags = (Qt.ItemIsSelectable | Qt.ItemIsUserCheckable
                                  | Qt.ItemIsEnabled)
        self.__lastColumnTitle = "测井取样"

        #为tableView设置数据模型
        self.ui.tableView.setModel(self.itemModel)  #设置数据模型
        self.ui.tableView.setSelectionModel(self.selectionModel)  #设置选择模型

        oneOrMore = QAbstractItemView.ExtendedSelection
        self.ui.tableView.setSelectionMode(oneOrMore)  #可多选

        itemOrRow = QAbstractItemView.SelectItems
        self.ui.tableView.setSelectionBehavior(itemOrRow)  #单元格选择

        self.ui.tableView.verticalHeader().setDefaultSectionSize(22)  #缺省行高
        self.ui.tableView.setEnabled(False)  #先禁用tableView
        ##      self.__resetTable(5)

        #创建自定义代理组件并设置
        self.spinCeShen = QmyFloatSpinDelegate(0, 10000, 0, self)  #用于 测深
        self.spinLength = QmyFloatSpinDelegate(0, 6000, 2, self)  #垂深,总位移
        self.spinDegree = QmyFloatSpinDelegate(0, 360, 1, self)  #用于 方位

        self.ui.tableView.setItemDelegateForColumn(0, self.spinCeShen)  #测深
        self.ui.tableView.setItemDelegateForColumn(1, self.spinLength)  #垂深
        self.ui.tableView.setItemDelegateForColumn(3, self.spinLength)  #总位移
        self.ui.tableView.setItemDelegateForColumn(2, self.spinDegree)  #方位角

        qualities = ["优", "良", "合格", "不合格"]
        self.comboDelegate = QmyComboBoxDelegate(self)
        self.comboDelegate.setItems(qualities, False)  #不可编辑
        self.ui.tableView.setItemDelegateForColumn(4,
                                                   self.comboDelegate)  #固井质量

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

    def __buildStatusBar(self):  ##构建状态栏
        self.LabCellPos = QLabel("当前单元格:", self)
        self.LabCellPos.setMinimumWidth(180)
        self.ui.statusBar.addWidget(self.LabCellPos)

        self.LabCellText = QLabel("单元格内容:", self)
        self.LabCellText.setMinimumWidth(150)
        self.ui.statusBar.addWidget(self.LabCellText)

        self.LabCurFile = QLabel("当前文件:", self)
        self.ui.statusBar.addPermanentWidget(self.LabCurFile)

##   def __resetTable(self,tableRowCount):  #复位数据表,必须为数值设置0,否则代理组件出错
##      self.itemModel.removeRows(0,self.itemModel.rowCount()) #删除所有行
##      self.itemModel.setRowCount(tableRowCount)     #设置新的行数
##
##      for i in range(tableRowCount):  #设置最后一列
##         for j in range(self.COL_COUNT-1):
##            index=self.itemModel.index(i,j) #获取模型索引
##            item=self.itemModel.itemFromIndex(index) #获取item
##            item.setData(0,Qt.DisplayRole) #数值必须初始化为0
##            item.setTextAlignment(Qt.AlignHCenter)
##
##         index=self.itemModel.index(i,self.COL_COUNT-1) #获取模型索引
##         item=self.itemModel.itemFromIndex(index) #获取item
##         item.setCheckable(True)
##         item.setData(self.__lastColumnTitle,Qt.DisplayRole)
##         item.setEditable(False) #不可编辑

    def __iniModelFromStringList(self, allLines):  ##从字符串列表构建模型
        rowCnt = len(allLines)  #文本行数,第1行是标题
        self.itemModel.setRowCount(rowCnt - 1)  #实际数据行数

        headerText = allLines[0].strip()  #第1行是表头,去掉末尾的换行符 "\n"
        headerList = headerText.split("\t")
        self.itemModel.setHorizontalHeaderLabels(headerList)

        self.__lastColumnTitle = headerList[len(headerList) -
                                            1]  # 最后一列表头的标题,即“测井取样”

        lastColNo = self.COL_COUNT - 1  #最后一列的列号
        for i in range(rowCnt - 1):
            lineText = allLines[i + 1].strip()  #一行的文字,\t分隔
            strList = lineText.split("\t")
            for j in range(self.COL_COUNT - 1):  #不含最后一列
                item = QStandardItem(strList[j])
                self.itemModel.setItem(i, j, item)

            item = QStandardItem(self.__lastColumnTitle)  #最后一列
            item.setFlags(self.__lastColumnFlags)
            item.setCheckable(True)
            if (strList[lastColNo] == "0"):
                item.setCheckState(Qt.Unchecked)
            else:
                item.setCheckState(Qt.Checked)

            self.itemModel.setItem(i, lastColNo, item)  #设置最后一列的item

    def __setCellAlignment(self, align=Qt.AlignHCenter):
        if (not self.selectionModel.hasSelection()):  #没有选择的项
            return
        selectedIndex = self.selectionModel.selectedIndexes()  #列表类型
        count = len(selectedIndex)
        for i in range(count):
            index = selectedIndex[i]  #获取其中的一个模型索引
            item = self.itemModel.itemFromIndex(index)  #获取一个单元格的项数据对象
            item.setTextAlignment(align)  #设置文字对齐方式

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

    @pyqtSlot()  ##“打开文件”
    def on_actOpen_triggered(self):
        curPath = os.getcwd()  #获取当前路径
        filename, flt = QFileDialog.getOpenFileName(
            self, "打开一个文件", curPath, "井斜数据文件(*.txt);;所有文件(*.*)")
        if (filename == ""):
            return

        self.LabCurFile.setText("当前文件:" + filename)
        self.ui.plainTextEdit.clear()

        aFile = open(filename, 'r')
        allLines = aFile.readlines()  #读取所有行,list类型,每行末尾带有 \n
        ##        for eachLine in aFile:  #每次读取一行
        ##            self.ui.plainTextEdit.appendPlainText(eachLine)
        aFile.close()

        for strLine in allLines:
            self.ui.plainTextEdit.appendPlainText(strLine.strip())

        self.__iniModelFromStringList(allLines)
        self.ui.actAppend.setEnabled(True)  #更新Actions的enable属性
        self.ui.actInsert.setEnabled(True)
        self.ui.actDelete.setEnabled(True)
        self.ui.actSave.setEnabled(True)
        self.ui.actModelData.setEnabled(True)

        self.ui.tableView.setEnabled(True)  #启用tableView

    @pyqtSlot()  ##保存文件
    def on_actSave_triggered(self):
        curPath = os.getcwd()  #获取当前路径
        filename, flt = QFileDialog.getSaveFileName(
            self, "保存文件", curPath, "井斜数据文件(*.txt);;所有文件(*.*)")
        if (filename == ""):
            return

        self.on_actModelData_triggered()  #更新数据到plainTextEdit

        aFile = open(filename, 'w')  #以写方式打开
        aFile.write(self.ui.plainTextEdit.toPlainText())
        aFile.close()

    @pyqtSlot()
    def on_actAppend_triggered(self):  #在最后添加一行
        itemlist = []  # 列表
        for i in range(self.COL_COUNT - 1):
            item = QStandardItem("0")
            itemlist.append(item)

        item = QStandardItem(self.__lastColumnTitle)  #最后一列
        item.setCheckable(True)
        item.setFlags(self.__lastColumnFlags)
        itemlist.append(item)

        self.itemModel.appendRow(itemlist)
        curIndex = self.itemModel.index(self.itemModel.rowCount() - 1, 0)
        self.selectionModel.clearSelection()
        self.selectionModel.setCurrentIndex(curIndex,
                                            QItemSelectionModel.Select)

    @pyqtSlot()  ##插入一行
    def on_actInsert_triggered(self):
        itemlist = []  # 列表
        for i in range(self.COL_COUNT - 1):
            item = QStandardItem("0")
            itemlist.append(item)

        item = QStandardItem(self.__lastColumnTitle)  #最后一列
        item.setFlags(self.__lastColumnFlags)
        item.setCheckable(True)
        item.setCheckState(Qt.Checked)
        itemlist.append(item)

        curIndex = self.selectionModel.currentIndex()
        #获取当前选中项的模型索引
        self.itemModel.insertRow(curIndex.row(), itemlist)
        #在当前行的前面插入一行
        self.selectionModel.clearSelection()
        self.selectionModel.setCurrentIndex(curIndex,
                                            QItemSelectionModel.Select)

    @pyqtSlot()  ##删除当前行
    def on_actDelete_triggered(self):
        curIndex = self.selectionModel.currentIndex()  #获取当前选择单元格的模型索引
        self.itemModel.removeRow(curIndex.row())  # //删除当前行

    @pyqtSlot()  ##左对齐
    def on_actAlignLeft_triggered(self):
        self.__setCellAlignment(Qt.AlignLeft | Qt.AlignVCenter)

    @pyqtSlot()  ##中间对齐
    def on_actAlignCenter_triggered(self):
        self.__setCellAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

    @pyqtSlot()  ##右对齐
    def on_actAlignRight_triggered(self):
        self.__setCellAlignment(Qt.AlignRight | Qt.AlignVCenter)

    @pyqtSlot(bool)  ##字体Bold
    def on_actFontBold_triggered(self, checked):
        if (not self.selectionModel.hasSelection()):  #没有选择的项
            return

        selectedIndex = self.selectionModel.selectedIndexes()  #列表类型
        count = len(selectedIndex)
        for i in range(count):
            index = selectedIndex[i]  #获取其中的一个模型索引
            item = self.itemModel.itemFromIndex(index)  #获取一个单元格的项数据对象
            font = item.font()
            font.setBold(checked)
            item.setFont(font)

    @pyqtSlot()  ##模型数据显示到plainTextEdit里
    def on_actModelData_triggered(self):
        self.ui.plainTextEdit.clear()
        lineStr = ""
        for i in range(self.itemModel.columnCount() - 1):  #表头
            item = self.itemModel.horizontalHeaderItem(i)
            lineStr = lineStr + item.text() + "\t"
        item = self.itemModel.horizontalHeaderItem(self.COL_COUNT - 1)  #最后一列
        lineStr = lineStr + item.text()
        self.ui.plainTextEdit.appendPlainText(lineStr)

        for i in range(self.itemModel.rowCount()):
            lineStr = ""
            for j in range(self.itemModel.columnCount() - 1):  #不包括最后一列
                item = self.itemModel.item(i, j)
                lineStr = lineStr + item.text() + "\t"

            item = self.itemModel.item(i, self.COL_COUNT - 1)  #最后一列
            if (item.checkState() == Qt.Checked):
                lineStr = lineStr + "1"
            else:
                lineStr = lineStr + "0"
            self.ui.plainTextEdit.appendPlainText(lineStr)

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

    def do_currentChanged(self, current, previous):
        if (current != None):  #当前模型索引有效
            self.LabCellPos.setText(
                "当前单元格:%d行,%d列" %
                (current.row(), current.column()))  #显示模型索引的行和列号
            item = self.itemModel.itemFromIndex(current)  #从模型索引获得Item
            self.LabCellText.setText("单元格内容:" + item.text())  #显示item的文字内容

            font = item.font()  #获取item的字体
            self.ui.actFontBold.setChecked(font.bold())  #更新actFontBold的check状态
コード例 #2
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.qSplitter)
        self.__ColCount = 6
        self.itemModel = QStandardItemModel(5, self.__ColCount, self)
        self.selectionModel = QItemSelectionModel(self.itemModel)
        self.selectionModel.currentChanged.connect(self.do_curChanged)

        self.__lastColumnTitle = "测井取样"
        self.__lastColumnFlags = (Qt.ItemIsSelectable | Qt.ItemIsUserCheckable
                                  | Qt.ItemIsEnabled)

        self.ui.qTableView.setModel(self.itemModel)
        self.ui.qTableView.setSelectionModel(self.selectionModel)

        oneOrMore = QAbstractItemView.ExtendedSelection
        self.ui.qTableView.setSelectionMode(oneOrMore)

        itemOrRow = QAbstractItemView.SelectItems
        self.ui.qTableView.setSelectionBehavior(itemOrRow)

        self.ui.qTableView.verticalHeader().setDefaultSectionSize(22)
        self.ui.qTableView.setAlternatingRowColors(True)

        self.ui.qTableView.setEnabled(False)

        self.qLabel1 = QLabel("当前单元格:", self)
        self.qLabel1.setMinimumWidth(180)
        self.qLabel2 = QLabel("单元格内容:", self)
        self.qLabel2.setMinimumWidth(150)
        self.qLabel3 = QLabel("当前文件:", self)
        self.ui.qStatusBar.addWidget(self.qLabel1)
        self.ui.qStatusBar.addWidget(self.qLabel2)
        self.ui.qStatusBar.addPermanentWidget(self.qLabel3)

    def __iniModelFromStringList(self, allLines):
        rowCnt = len(allLines)
        self.itemModel.setRowCount(rowCnt - 1)
        headerText = allLines[0].strip()
        headerList = headerText.split("\t")
        self.itemModel.setHorizontalHeaderLabels(headerList)
        self.__lastColumnTitle = headerList[len(headerList) - 1]
        lastColNo = self.__ColCount - 1
        for i in range(rowCnt - 1):
            lineText = allLines[i + 1].strip()
            strList = lineText.split("\t")
            for j in range(self.__ColCount - 1):
                item = QStandardItem(strList[j])
                self.itemModel.setItem(i, j, item)

            item = QStandardItem(self.__lastColumnTitle)
            item.setFlags(self.__lastColumnFlags)
            item.setCheckable(True)
            if (strList[lastColNo] == "0"):
                item.setCheckState(Qt.Unchecked)
            else:
                item.setCheckState(Qt.Checked)
            self.itemModel.setItem(i, lastColNo, item)

    def __setCellAlignment(self, align=Qt.AlignHCenter):
        if (not self.selectionModel.hasSelection()):
            return
        selectedIndex = self.selectionModel.selectedIndexes()
        count = len(selectedIndex)
        for i in range(count):
            index = selectedIndex[i]
            item = self.itemModel.itemFromIndex(index)
            item.setTextAlignment(align)

    @pyqtSlot()
    def on_qAction1_triggered(self):  # 打开文件
        curPath = os.getcwd()
        filename, flt = QFileDialog.getOpenFileName(
            self, "打开一个文件", curPath, "井斜数据文件(*.txt);;所有文件(*.*)")
        if (filename == ""):
            return
        self.qLabel3.setText("当前文件:" + filename)
        self.ui.qPlainTextEdit.clear()
        aFile = open(filename, 'r')
        allLines = aFile.readlines()
        aFile.close()

        for strLine in allLines:
            self.ui.qPlainTextEdit.appendPlainText(strLine.strip())

        self.__iniModelFromStringList(allLines)
        self.ui.qTableView.setEnabled(True)
        self.ui.qAction2.setEnabled(True)
        self.ui.qAction3.setEnabled(True)
        self.ui.qAction4.setEnabled(True)
        self.ui.qAction5.setEnabled(True)
        self.ui.qAction6.setEnabled(True)

    @pyqtSlot()
    def on_qAction2_triggered(self):  # 另存文件
        curPath = os.getcwd()
        filename, flt = QFileDialog.getSaveFileName(
            self, "保存文件", curPath, "井斜数据文件(*.txt);;所有文件(*.*)")
        if (filename == ""):
            return
        self.on_qAction3_triggered()
        aFile = open(filename, "w")
        aFile.write(self.ui.qPlainTextEdit.toPlainText())
        aFile.close()

    @pyqtSlot()
    def on_qAction4_triggered(self):  # 添加行
        itemList = []
        for i in range(self.__ColCount - 1):
            item = QStandardItem("0")
            itemList.append(item)

        item = QStandardItem(self.__lastColumnTitle)
        item.setCheckable(True)
        item.setFlags(self.__lastColumnFlags)
        itemList.append(item)

        self.itemModel.appendRow(itemList)
        curIndex = self.itemModel.index(self.itemModel.rowCount() - 1, 0)
        self.selectionModel.clearSelection()
        self.selectionModel.setCurrentIndex(curIndex,
                                            QItemSelectionModel.Select)

    @pyqtSlot()
    def on_qAction5_triggered(self):  # 插入行
        itemlist = []
        for i in range(self.__ColCount - 1):
            item = QStandardItem("0")
            itemlist.append(item)

        item = QStandardItem(self.__lastColumnTitle)
        item.setFlags(self.__lastColumnFlags)
        item.setCheckable(True)
        item.setCheckState(Qt.Checked)
        itemlist.append(item)

        curIndex = self.selectionModel.currentIndex()
        self.itemModel.insertRow(curIndex.row(), itemlist)
        self.selectionModel.clearSelection()
        self.selectionModel.setCurrentIndex(curIndex,
                                            QItemSelectionModel.Select)

    @pyqtSlot()
    def on_qAction6_triggered(self):  # 删除行
        curIndex = self.selectionModel.currentIndex()
        self.itemModel.removeRow(curIndex.row())

    @pyqtSlot()
    def on_qAction7_triggered(self):  # 居左
        self.__setCellAlignment(Qt.AlignLeft | Qt.AlignVCenter)

    @pyqtSlot()
    def on_qAction8_triggered(self):  # 居中
        self.__setCellAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

    @pyqtSlot()
    def on_qAction9_triggered(self):  # 居右
        self.__setCellAlignment(Qt.AlignRight | Qt.AlignVCenter)

    @pyqtSlot(bool)
    def on_qAction10_triggered(self, checked):  # 粗体
        if (not self.selectionModel.hasSelection()):
            return
        selectedIndex = self.selectionModel.selectedIndexes()
        count = len(selectedIndex)
        for i in range(count):
            index = selectedIndex[i]
            item = self.itemModel.itemFromIndex(index)
            font = item.font()
            font.setBold(checked)
            item.setFont(font)

    @pyqtSlot()
    def on_qAction3_triggered(self):  # 模型数据
        self.ui.qPlainTextEdit.clear()
        lineStr = ""
        for i in range(self.itemModel.columnCount() - 1):
            item = self.itemModel.horizontalHeaderItem(i)
            lineStr = lineStr + item.text() + "\t"
        item = self.itemModel.horizontalHeaderItem(self.__ColCount - 1)
        lineStr = lineStr + item.text()
        self.ui.qPlainTextEdit.appendPlainText(lineStr)

        for i in range(self.itemModel.rowCount()):
            lineStr = ""
            for j in range(self.itemModel.columnCount() - 1):
                item = self.itemModel.item(i, j)
                lineStr = lineStr + item.text() + "\t"
            item = self.itemModel.item(i, self.__ColCount - 1)
            if (item.checkState() == Qt.Checked):
                lineStr = lineStr + "1"
            else:
                lineStr = lineStr + "0"
            self.ui.qPlainTextEdit.appendPlainText(lineStr)

    def do_curChanged(self, current, previous):
        if (current != None):
            text = "当前单元格:%d行,%d列" % (current.row(), current.column())
            self.qLabel1.setText(text)
            item = self.itemModel.itemFromIndex(current)
            self.qLabel2.setText("单元格内容:" + item.text())
            font = item.font()
            self.ui.qAction10.setChecked(font.bold())
コード例 #3
0
class QmyMainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)  #调用父类构造函数,创建窗体
        self.ui = Ui_MainWindow()  #创建Ui对象
        self.ui.setupUi(self)  #构造UI

        self.__ColCount = 6  #列数
        self.itemModel = QStandardItemModel(
            10, self.__ColCount, self)  #创建QStandardItemModel类型的数据模型,指定行列值
        '''
		setSelectionBehavior()
		此属性保存视图使用的选择行为。
		此属性保存选择是根据单个项目,行还是列进行的

		#QItemSelectionModel()
		此属性保存视图在哪种选择模式下运行。
		#此属性控制用户是否可以选择一个或多个项目,并且在多个项目选择中控制选择是否必须是连续范围的项目
		'''
        self.selectionModel = QItemSelectionModel(self.itemModel)

        self.selectionModel.currentChanged.connect(
            self.do_curChanged)  #单元格选择发生变化时会发射此信号
        self.__lastColumnTitle = ""  #设置最后一列的标题,可以是空
        self.__lastColumnFlags = (Qt.ItemIsSelectable | Qt.ItemIsUserCheckable
                                  | Qt.ItemIsEnabled)
        #设置tableView属性
        self.ui.tableView.setModel(self.itemModel)  #数据模型
        self.ui.tableView.setSelectionModel(self.selectionModel)  #选择模型
        oneOrMore = QAbstractItemView.ExtendedSelection  #选择模式->多选模式
        self.ui.tableView.setSelectionMode(oneOrMore)  #多选模式
        itemOrRow = QAbstractItemView.SelectItems  #项选择模式->单元格选择
        self.ui.tableView.setSelectionBehavior(itemOrRow)  #单元格选择
        self.ui.tableView.verticalHeader().setDefaultSectionSize(22)
        self.ui.tableView.setAlternatingRowColors(True)  #交替行颜色
        self.ui.tableView.setEnabled(False)  #设置默认禁用tabelView
        self.ui.actFontBold.setCheckable(False)
        self.setCentralWidget(self.ui.splitter)  #设置中心组件
        # self.setCentralWidget(self.ui.tableView)
        self.__buildStatusBar()

        self.spinCeshen = QmyFloatSpinDelegate(0, 10000, 0, self)
        self.spinLength = QmyFloatSpinDelegate(0, 6000, 2, self)
        self.spinDegree = QmyFloatSpinDelegate(0, 360, 1, self)
        self.ui.tableView.setItemDelegateForColumn(0, self.spinCeshen)
        self.ui.tableView.setItemDelegateForColumn(1, self.spinLength)
        self.ui.tableView.setItemDelegateForColumn(3, self.spinLength)
        self.ui.tableView.setItemDelegateForColumn(2, self.spinDegree)

        qualities = ["优", "良", "合格", "不合格"]

        self.comboDelegate = QmyComboBoxDelegate(self)
        self.comboDelegate.setItems(qualities, False)
        self.ui.tableView.setItemDelegateForColumn(4, self.comboDelegate)

    ##==========自定义功能函数==========
    def __buildStatusBar(self):
        '''
		设置状态栏ui组件
		:return:
		'''
        self.LabCellPos = QLabel("当前单元格:", self)
        self.LabCellPos.setMinimumWidth(180)
        self.ui.statusBar.addWidget(self.LabCellPos)

        self.LabCellText = QLabel("单元格内容:", self)
        self.LabCellText.setMinimumWidth(150)
        self.ui.statusBar.addWidget(self.LabCellText)

        self.LabCurFile = QLabel("当前文件:", self)
        self.ui.statusBar.addWidget(self.LabCurFile)

    def __iniModelFromStringList(self, allLines):
        rowCnt = len(allLines)  #获取总行数
        self.itemModel.setRowCount(rowCnt - 1)  #除去表头的数据行数
        headerText = allLines[0].strip()  #表头去除换行符,文件呢的空格使用Tab代替
        headerList = headerText.split("\t")  #按照制表符转化为列表
        self.itemModel.setHorizontalHeaderLabels(headerList)  #设置表头标题
        # print(headerList)
        self.__lastColumnTitle = headerList[len(headerList) - 1]  #最后一列的标题
        lastColNo = self.__ColCount - 1  #最后一列的列号

        for i in range(rowCnt - 1):  #除去表头的数据行数
            # print(i)
            lineText = allLines[i + 1].strip()  #去除换行符,不包括表头
            strList = lineText.split("\t")  #按制表符生成列表
            for j in range(self.__ColCount - 1):  #不包括最后一列
                '''
				QStandardItem是一个数据结构,他可以存储一个cell的各种信息,比如文本、图标、是否可选、字体、别景色、前景色等等。
				并且QStandardItem可以有孩子和兄弟,他是为model提供数据存储的节点。
				QTableView:作为表格cell时,有一个作为根节点的QStandardItem,其他节点都是QStandardItem节点的孩子节点,并且都是兄弟节点(这里暂时不考虑多列的情况)。
				QTreeView:作为树节点cell时,有一个作为根节点的QStandardItem,其他节点都是他的孩子节点,但是其他节点也可以作为父节点存在(这里暂时不考虑多列的情况)。
				'''
                item = QStandardItem(strList[j])
                self.itemModel.setItem(i, j, item)
            #设置最后一行
            # print(self.__lastColumnTitle)
            item = QStandardItem(self.__lastColumnTitle)  #将最后一行的表头
            item.setFlags(self.__lastColumnFlags)
            item.setCheckable(True)
            # print(strList[lastColNo])
            if strList[lastColNo] == '0':  #对比文本内的数值进行设定,类型是字符串
                item.setCheckState(Qt.Unchecked)
            else:
                item.setCheckState(Qt.Checked)
            self.itemModel.setItem(i, lastColNo, item)

    def __setCellAlignment(self, align=Qt.AlignHCenter):
        if not self.selectionModel.hasSelection():
            return
        '''
		selectedIndexes()返回一个元素为QModelIndex类型的列表,包括所有被选中的单元格的模型索引
		'''
        selectdIndex = self.selectionModel.selectedIndexes()
        # print(selectdIndex)
        count = len(selectdIndex)
        for i in range(count):
            index = selectdIndex[i]
            '''
			itemFromIndex(index)返回的是模型索引为index的QStandardItem对象
			'''
            item = self.itemModel.itemFromIndex(index)
            item.setTextAlignment(align)

    ##==========事件处理函数===========

    ##==========由connectSlotsByName()自动关联的槽函数====
    @pyqtSlot()
    def on_actOpenFile_triggered(self):

        curPath = os.getcwd()  #获取当前路径
        # print(curPath)?
        #flt是文件过滤器
        filename, flt = QFileDialog.getOpenFileName(
            self, "打开一个文件", curPath, "井斜数据文件(*.txt);;所有文件(*.*)")
        if filename == "":
            return
        self.LabCurFile.setText(("当前文件: " + filename))  #设置状态栏文本
        self.ui.plainTextEdit.clear()
        aFile = open(filename, "r")
        allLines = aFile.readlines()
        aFile.close()
        for strLine in allLines:
            self.ui.plainTextEdit.appendPlainText(
                strLine.strip())  #按照行添加到plainTextEdit中
        self.__iniModelFromStringList(allLines)
        #设置激活状态
        self.ui.tableView.setEnabled(True)
        self.ui.actAppend.setEnabled(True)
        self.ui.actInsert.setEnabled(True)
        self.ui.actDel.setEnabled(True)
        self.ui.actSaveFile.setEnabled(True)
        self.ui.actModelData.setEnabled(True)
        self.ui.actFontBold.setCheckable(True)  #设置加粗可用

    @pyqtSlot()
    def on_actAppend_triggered(self):
        itemlist = []
        for i in range(self.__ColCount - 1):  #循环一行中的各个列,不包括最后一列
            item = QStandardItem("0")  #添加0到数据结构中
            itemlist.append(item)

        item = QStandardItem(self.__lastColumnTitle)  #将最后一行的表头添加入数据结构
        item.setCheckable(True)  #可选
        item.setFlags(self.__lastColumnFlags)
        itemlist.append(item)  #添加到itemlist内(添加到最后一个)

        self.itemModel.appendRow(itemlist)

        curIndex = self.itemModel.index(self.itemModel.rowCount() - 1,
                                        0)  #获取最后一行第一个单元格的模型索引
        self.selectionModel.clearSelection()  #清除选择
        self.selectionModel.setCurrentIndex(
            curIndex,
            QItemSelectionModel.Select)  #设置在添加后自动选择添加行的第一个单元格(可从状态栏确认)

    @pyqtSlot()
    def on_actInsert_triggered(self):
        '''
		插入行
		:return:
		'''
        itemlist = []
        for i in range(self.__ColCount - 1):
            item = QStandardItem("0")
            itemlist.append(item)

        item = QStandardItem(self.__lastColumnTitle)
        item.setFlags(self.__lastColumnFlags)
        item.setCheckable(False)  #是否可以修改选择
        item.setCheckState(Qt.Checked)  #是否选中
        itemlist.append(item)

        curIndex = self.selectionModel.currentIndex()  #选中项的模型索引,包括行列等其他信息
        self.itemModel.insertRow(curIndex.row(), itemlist)

        self.selectionModel.clearSelection()
        self.selectionModel.setCurrentIndex(curIndex,
                                            QItemSelectionModel.Select)

    @pyqtSlot()
    def on_actDel_triggered(self):
        '''
		删除行
		:return:
		'''
        curIndex = self.selectionModel.currentIndex()
        self.itemModel.removeRow(curIndex.row())

    @pyqtSlot()
    def on_actAlignLeft_triggered(self):
        self.__setCellAlignment(Qt.AlignLeft | Qt.AlignVCenter)

    @pyqtSlot()
    def on_actAlignCenter_triggered(self):
        self.__setCellAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

    @pyqtSlot()
    def on_actAlignRight_triggered(self):
        self.__setCellAlignment(Qt.AlignRight | Qt.AlignVCenter)

    @pyqtSlot(bool)
    def on_actFontBold_triggered(self, checked):
        print("1,checked", checked)
        if not self.selectionModel.hasSelection():
            return
        selectIndex = self.selectionModel.selectedIndexes()
        for i in range(len(selectIndex)):
            index = selectIndex[i]
            item = self.itemModel.itemFromIndex(index)
            font = item.font()
            font.setBold(checked)
            item.setFont(font)

    @pyqtSlot()
    def on_actModelData_triggered(self):
        self.ui.plainTextEdit.clear()
        lineStr = ""
        for i in range(self.itemModel.columnCount() - 1):  #不包括最后一列的表头遍历
            item = self.itemModel.horizontalHeaderItem(i)  #返回行标题的一个数据项对象,i是列号
            lineStr = lineStr + item.text() + "\t"  #给每个项对象的文本添加Tab制表符
        item = self.itemModel.horizontalHeaderItem(self.__ColCount -
                                                   1)  #最后一列的表头
        lineStr = lineStr + item.text()
        self.ui.plainTextEdit.appendPlainText(lineStr)

        for i in range(self.itemModel.rowCount()):  #获取行总数,不包括表头行
            lineStr = ""
            for j in range(self.itemModel.columnCount() - 1):  #不包括最后一列的遍历
                item = self.itemModel.item(i, j)  #按照行列号获取工作区内项对象
                lineStr = lineStr + item.text() + "\t"  #项对象文本添加制表符
            item = self.itemModel.item(i, self.__ColCount - 1)  #按照行号获取最后一列的项对象
            if item.checkState() == Qt.Checked:  #匹配状态是否为选中
                lineStr = lineStr + "1"
            else:
                lineStr = lineStr + "0"
            self.ui.plainTextEdit.appendPlainText(lineStr)

    @pyqtSlot()
    def on_actSaveFile_triggered(self):
        '''
		保存文件
		:return:
		'''
        curPath = os.getcwd()
        filename, flt = QFileDialog.getSaveFileName(
            self, "保存文件", curPath, "井斜数据文件(*.txt);;所有文件(*.*)")
        if filename == "":
            return
        self.on_actModelData_triggered()
        aFile = open(filename, "w")
        aFile.write(self.ui.plainTextEdit.toPlainText())
        aFile.close()

    ##=========自定义槽函数============
    def do_curChanged(self, current, previous):
        '''
		设置状态栏组件显示内容
		:param current:
		:param previous:
		:return:
		'''
        if current != None:
            text = " 当前单元格: %d行,%d列" % (current.row() + 1,
                                        current.column() + 1)
            self.LabCellPos.setText(text)
            item = self.itemModel.itemFromIndex(current)
            self.LabCellText.setText("单元格内容:" + item.text())

            font = item.font()
            self.ui.actFontBold.setChecked(
                font.bold())  #设置按钮按下,当font.Bold的值大于50式font.blod()会为True
コード例 #4
0
class ManagerMainui(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(ManagerMainui, self).__init__()
        self.setupUi(self)
        self.opendb()
        self.show()
        self.lianjie()
        self.setCentralWidget(self.splitter)

        self.table_view.setSelectionBehavior(QAbstractItemView.SelectItems)
        self.table_view.setSelectionMode(
            QAbstractItemView.SingleSelection)  # 一次选择单行还是多行
        self.table_view.setAlternatingRowColors(True)  # 隔行自动改变颜色
        self.table_view.verticalHeader().setDefaultSectionSize(22)
        self.table_view.horizontalHeader().setDefaultSectionSize(60)

        # 为菜单添加动作

        self.filemenu.addAction(self.exit_Act)
        self.Updata_Menu.addAction(self.Updata_Act)

        # 当前页
        self.currentPage = 0
        # 总页数
        self.totalPage = 0
        # 总记录数
        self.totalRecord = 0
        # 每页数据数
        self.pageRecord = 10

    def opendb(self):
        db = QSqlDatabase.addDatabase('QSQLITE')
        db.setDatabaseName('F:/pycharm项目/图书管理系统NEW/AllDataBase/book.db')
        if db.open():
            self._biaocaozuo()
        else:
            QMessageBox.information(self, 'warning', '无法建立与数据库的连接')
            return False

    def _biaocaozuo(self):
        self.model = QtSql.QSqlTableModel()
        self.model.setTable('BookData')

        self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)  # 设置保存策略

        self.table_view.setModel(self.model)
        self.model.select()
        self.model.setHeaderData(0, Qt.Horizontal, 'ISBN')
        self.model.setHeaderData(1, Qt.Horizontal, '书名')
        self.model.setHeaderData(2, Qt.Horizontal, '作者')
        self.model.setHeaderData(3, Qt.Horizontal, '出版社')
        self.model.setHeaderData(4, Qt.Horizontal, '出版日期')
        self.model.setHeaderData(5, Qt.Horizontal, '评分')
        self.model.setHeaderData(6, Qt.Horizontal, '照片')
        self.table_view.setColumnHidden(6, True)

        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.model)
        self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit)

        self.mapper.addMapping(self.lineEdit_ISBN, 0)
        self.mapper.addMapping(self.lineEdit_shuming, 1)
        self.mapper.addMapping(self.lineEdit_zuozhe, 2)
        self.mapper.addMapping(self.lineEdit_chubanshe, 3)
        self.mapper.addMapping(self.lineEdit_chubanriqi, 4)
        self.mapper.addMapping(self.lineEdit_pingfen, 5)
        self.mapper.toFirst()

        self.selModel = QItemSelectionModel(self.model)  # 选择模型
        self.table_view.setSelectionModel(self.selModel)
        self.selModel.currentChanged.connect(
            self.do_currentChanged)  # 当前项变化时触发
        self.selModel.currentRowChanged.connect(
            self.do_currentRowChanged)  # 选择行变化时

        # @pyqtSlot()  ##保存修改

    def on_p_baocun_triggered(self):
        result = QMessageBox.question(self, 'warning', '你要保存你的修改吗?',
                                      QMessageBox.Yes | QMessageBox.No,
                                      QMessageBox.No)
        if result == QMessageBox.Yes:
            res = self.model.submitAll()
            if (res == False):
                QMessageBox.information(
                    self, "消息",
                    "数据保存错误,错误信息\n" + self.model.lastError().text())
            else:
                QMessageBox.information(self, "message", "保存成功\n")
                self.p_baocun.setEnabled(False)
                self.p_quxiao.setEnabled(False)
        else:
            QMessageBox.information(self, 'message', 'Thanks')

    # @pyqtSlot()  ##取消修改

    def on_p_quxiao_triggered(self):
        # self.model.revertAll()
        result = QMessageBox.question(self, 'warning', '确认取消之前所有的的操作吗?',
                                      QMessageBox.Yes | QMessageBox.No,
                                      QMessageBox.No)
        if result == QMessageBox.Yes:
            self.model.revertAll()
            self.p_baocun.setEnabled(False)
            self.p_quxiao.setEnabled(False)
        else:
            self.p_baocun.setEnabled(True)
            self.p_quxiao.setEnabled(True)

    # @pyqtSlot()  ##添加记录
    def on_p_zengjia_triggered(self):
        #self.model.insertRows(self.model.rowCount(), 1)
        self.model.insertRow(self.model.rowCount(), QModelIndex())  # 在末尾添加一个记录

        curIndex = self.model.index(self.model.rowCount() - 1,
                                    1)  # 创建最后一行的ModelIndex
        self.selModel.clearSelection()  # 清空选择项
        self.selModel.setCurrentIndex(
            curIndex, QItemSelectionModel.Select)  # 设置刚插入的行为当前选择行

    # 删除记录

    def on_p_sanchu_triggered(self):
        # if self.p_baocun.isEnabled():
        result = QMessageBox.question(self, 'warning', '确认删除该记录吗?',
                                      QMessageBox.Yes | QMessageBox.No,
                                      QMessageBox.No)
        if result == QMessageBox.Yes:
            self.model.removeRow(self.table_view.currentIndex().row())
            self.p_baocun.setEnabled(True)
            self.p_quxiao.setEnabled(True)
        else:
            self.p_baocun.setEnabled(False)
            self.p_quxiao.setEnabled(False)

    # 插入记录

    def on_p_charu_triggered(self):
        curIndex = self.table_view.currentIndex()  # QModelIndex
        self.model.insertRow(curIndex.row(), QModelIndex())
        self.selModel.clearSelection()  # 清除已有选择
        self.selModel.setCurrentIndex(curIndex, QItemSelectionModel.Select)

    # 对当前行设置图片
    def on_p_photo_triggered(self):
        fileName, filt = QFileDialog.getOpenFileName(self, "选择图片文件", "",
                                                     "照片(*.jpg)")
        if (fileName == ''):
            return

        file = QFile(fileName)  # fileName为图片文件名
        file.open(QIODevice.ReadOnly)
        try:
            data = file.readAll()  # QByteArray
        finally:
            file.close()

        curRecNo = self.selModel.currentIndex().row()
        curRec = self.model.record(curRecNo)  # 获取当前记录QSqlRecord
        curRec.setValue("Photo", data)  # 设置字段数据
        self.model.setRecord(curRecNo, curRec)

        pic = QPixmap()
        pic.loadFromData(data)
        W = self.dbLabPhoto.width()
        self.dbLabPhoto.setPixmap(pic.scaledToWidth(W))  # 在界面上显示

    def closeEvent(self, event):
        """
        提示保存
        """
        if self.p_baocun.isEnabled():
            r = QMessageBox.warning(self, "注意", "你还没有保存,现在保存下?",
                                    QMessageBox.Yes | QMessageBox.No,
                                    QMessageBox.Yes)
            if r == QMessageBox.No:
                event.accept()
            else:
                event.ignore()

    def chaxun_ISBN(self):
        text1 = self.lineEdit_chaxun.text()
        self.model.setFilter(("ISBN='%s'" % (text1)))

    def chaxun_zuozhe(self):
        text2 = self.lineEdit_chaxun.text()
        self.model.setFilter(("author='%s'" % (text2)))

    def chaxun_shumin(self):
        text3 = self.lineEdit_chaxun.text()
        self.model.setFilter(("title='%s'" % (text3)))

    def chaxun_(self):
        """
        查找图书
        """
        searchtext = self.lineEdit_chaxun.text()
        if searchtext:
            if self.comboBox_chaxun.currentText() == "ISBN":
                self.chaxun_ISBN()
            elif self.comboBox_chaxun.currentText() == "书名":
                self.chaxun_shumin()
            elif self.comboBox_chaxun.currentText() == "作者":
                self.chaxun_zuozhe()
        else:
            QMessageBox.information(self, "提示", "请输入搜索关键词!")

    def on_p_quxiaoCX_triggered(self):
        self.lineEdit_chaxun.clear()
        self.model.setFilter("")

    def do_currentChanged(self, current, previous):  # 更新actPost和actCancel 的状态
        self.p_baocun.setEnabled(self.model.isDirty())  # 有未保存修改时可用
        self.p_quxiao.setEnabled(self.model.isDirty())

    def do_currentRowChanged(self, current, previous):  # 行切换时的状态控制
        self.mapper.setCurrentIndex(current.row())

        if (current.isValid() == False):
            self.dbLabPhoto.clear()  # 清除图片显示
            return

        self.mapper.setCurrentIndex(current.row())  # 更新数据映射的行号

        curRec = self.model.record(current.row())  # 获取当前记录,QSqlRecord类型
        if (curRec.isNull("Photo")):  # 图片字段内容为空
            self.dbLabPhoto.clear()
        else:
            # data=bytearray(curRec.value("Photo"))   #可以工作
            data = curRec.value("Photo")  # 也可以工作
            pic = QPixmap()
            pic.loadFromData(data)
            W = self.dbLabPhoto.size().width()
            self.dbLabPhoto.setPixmap(pic.scaledToWidth(W))

    def scrapy(self):
        """启动爬虫,在线更新功能"""

        # cmdline.execute(" scrapy ".split())
        self.hide()
        try:
            run = ScrapyRun()
        finally:
            pass

    def lianjie(self):
        self.p_zengjia.clicked.connect(self.on_p_zengjia_triggered)
        self.p_baocun.clicked.connect(self.on_p_baocun_triggered)
        self.p_quxiao.clicked.connect(self.on_p_quxiao_triggered)
        self.p_sanchu.clicked.connect(self.on_p_sanchu_triggered)
        self.p_charu.clicked.connect(self.on_p_charu_triggered)
        self.p_photo.clicked.connect(self.on_p_photo_triggered)
        self.p_chaxun.clicked.connect(self.chaxun_)
        self.p_quxiaoCX.clicked.connect(self.on_p_quxiaoCX_triggered)
        self.p_tuichu.clicked.connect(self.close)

        self.exit_Act.triggered.connect(self.close)
        self.Updata_Act.triggered.connect(self.scrapy)
コード例 #5
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.splitter)

        ##   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(60)

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

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

    def __openTable(self):  ##打开数据表
        self.tabModel = QSqlTableModel(self, self.DB)  #数据模型
        self.tabModel.setTable("employee")  #设置数据表
        self.tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit
                                      )  #数据保存方式,OnManualSubmit , OnRowChange
        self.tabModel.setSort(self.tabModel.fieldIndex("empNo"),
                              Qt.AscendingOrder)  #排序
        if (self.tabModel.select() == False):  #查询数据失败
            QMessageBox.critical(
                self, "错误信息",
                "打开数据表错误,错误信息\n" + self.tabModel.lastError().text())
            return

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

        ##字段显示名
        self.tabModel.setHeaderData(self.fldNum["empNo"], Qt.Horizontal, "工号")
        self.tabModel.setHeaderData(self.fldNum["Name"], Qt.Horizontal, "姓名")
        self.tabModel.setHeaderData(self.fldNum["Gender"], Qt.Horizontal, "性别")
        self.tabModel.setHeaderData(self.fldNum["Birthday"], Qt.Horizontal,
                                    "出生日期")
        self.tabModel.setHeaderData(self.fldNum["Province"], Qt.Horizontal,
                                    "省份")
        self.tabModel.setHeaderData(self.fldNum["Department"], Qt.Horizontal,
                                    "部门")
        self.tabModel.setHeaderData(self.fldNum["Salary"], Qt.Horizontal, "工资")

        self.tabModel.setHeaderData(self.fldNum["Memo"], Qt.Horizontal,
                                    "备注")  #这两个字段不在tableView中显示
        self.tabModel.setHeaderData(self.fldNum["Photo"], Qt.Horizontal, "照片")

        ##      self.tabModel.setHeaderData(self.tabModel.fieldIndex("empNo"),  Qt.Horizontal, "工号")
        ##      self.tabModel.setHeaderData(self.tabModel.fieldIndex("Name"),   Qt.Horizontal, "姓名")
        ##      self.tabModel.setHeaderData(self.tabModel.fieldIndex("Gender"), Qt.Horizontal, "性别")
        ##      self.tabModel.setHeaderData(self.tabModel.fieldIndex("Birthday"),  Qt.Horizontal, "出生日期")
        ##      self.tabModel.setHeaderData(self.tabModel.fieldIndex("Province"),  Qt.Horizontal, "省份")
        ##      self.tabModel.setHeaderData(self.tabModel.fieldIndex("Department"),Qt.Horizontal, "部门")
        ##      self.tabModel.setHeaderData(self.tabModel.fieldIndex("Salary"), Qt.Horizontal, "工资")
        ##      self.tabModel.setHeaderData(self.tabModel.fieldIndex("Memo"),   Qt.Horizontal, "备注")   #这两个字段不在tableView中显示
        ##      self.tabModel.setHeaderData(self.tabModel.fieldIndex("Photo"),  Qt.Horizontal, "照片")

        ##创建界面组件与数据模型的字段之间的数据映射
        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.tabModel)  #设置数据模型
        self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit)

        ##界面组件与tabModel的具体字段之间的联系
        self.mapper.addMapping(self.ui.dbSpinEmpNo, self.fldNum["empNo"])
        self.mapper.addMapping(self.ui.dbEditName, self.fldNum["Name"])
        self.mapper.addMapping(self.ui.dbComboSex, self.fldNum["Gender"])
        self.mapper.addMapping(self.ui.dbEditBirth, self.fldNum["Birthday"])
        self.mapper.addMapping(self.ui.dbComboProvince,
                               self.fldNum["Province"])
        self.mapper.addMapping(self.ui.dbComboDep, self.fldNum["Department"])
        self.mapper.addMapping(self.ui.dbSpinSalary, self.fldNum["Salary"])
        self.mapper.addMapping(self.ui.dbEditMemo, self.fldNum["Memo"])
        self.mapper.toFirst()  #移动到首记录

        self.selModel = QItemSelectionModel(self.tabModel)  #选择模型
        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)  #设置选择模型

        self.ui.tableView.setColumnHidden(self.fldNum["Memo"], True)  #隐藏列
        self.ui.tableView.setColumnHidden(self.fldNum["Photo"], True)  #隐藏列

        ##tableView上为“性别”和“部门”两个字段设置自定义代理组件
        strList = ("男", "女")
        self.__delegateSex = QmyComboBoxDelegate()
        self.__delegateSex.setItems(strList, False)
        self.ui.tableView.setItemDelegateForColumn(
            self.fldNum["Gender"], self.__delegateSex)  #Combbox选择型

        strList = ("销售部", "技术部", "生产部", "行政部")
        self.__delegateDepart = QmyComboBoxDelegate()
        self.__delegateDepart.setItems(strList, True)
        self.ui.tableView.setItemDelegateForColumn(self.fldNum["Department"],
                                                   self.__delegateDepart)

        ##更新actions和界面组件的使能状态
        self.ui.actOpenDB.setEnabled(False)

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

        self.ui.groupBoxSort.setEnabled(True)
        self.ui.groupBoxFilter.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")  #添加 SQLITE数据库驱动
        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)  #设置刚插入的行为当前选择行

        currow = curIndex.row()  #获得当前行
        self.tabModel.setData(self.tabModel.index(currow,
                                                  self.fldNum["empNo"]),
                              2000 + self.tabModel.rowCount())  #自动生成编号
        self.tabModel.setData(
            self.tabModel.index(currow, self.fldNum["Gender"]), "男")

    @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_actPhotoClear_triggered(self):
        curRecNo = self.selModel.currentIndex().row()
        curRec = self.tabModel.record(curRecNo)  #获取当前记录,QSqlRecord
        curRec.setNull("Photo")  #设置为空值
        self.tabModel.setRecord(curRecNo, curRec)
        self.ui.dbLabPhoto.clear()  #清除界面上的图片显示

    @pyqtSlot()  ##设置照片
    def on_actPhoto_triggered(self):
        fileName, filt = QFileDialog.getOpenFileName(self, "选择图片文件", "",
                                                     "照片(*.jpg)")
        if (fileName == ''):
            return

        file = QFile(fileName)  #fileName为图片文件名
        file.open(QIODevice.ReadOnly)
        try:
            data = file.readAll()  #QByteArray
        finally:
            file.close()

        curRecNo = self.selModel.currentIndex().row()
        curRec = self.tabModel.record(curRecNo)  #获取当前记录QSqlRecord
        curRec.setValue("Photo", data)  #设置字段数据
        self.tabModel.setRecord(curRecNo, curRec)

        pic = QPixmap()
        pic.loadFromData(data)
        W = self.ui.dbLabPhoto.width()
        self.ui.dbLabPhoto.setPixmap(pic.scaledToWidth(W))  #在界面上显示

    @pyqtSlot()  ##涨工资,遍历数据表所有记录
    def on_actScan_triggered(self):
        if (self.tabModel.rowCount() == 0):
            return

        for i in range(self.tabModel.rowCount()):
            aRec = self.tabModel.record(i)  #获取当前记录
            ##         salary=aRec.value("Salary").toFloat()      #错误,无需再使用toFloat()函数
            salary = aRec.value("Salary")
            salary = salary * 1.1
            aRec.setValue("Salary", salary)
            self.tabModel.setRecord(i, aRec)

        if (self.tabModel.submitAll()):
            QMessageBox.information(self, "消息", "涨工资计算完毕")

    @pyqtSlot(int)  ##排序字段变化
    def on_comboFields_currentIndexChanged(self, index):
        if self.ui.radioBtnAscend.isChecked():
            self.tabModel.setSort(index, Qt.AscendingOrder)
        else:
            self.tabModel.setSort(index, Qt.DescendingOrder)
        self.tabModel.select()

    @pyqtSlot()  ##升序
    def on_radioBtnAscend_clicked(self):
        self.tabModel.setSort(self.ui.comboFields.currentIndex(),
                              Qt.AscendingOrder)
        self.tabModel.select()

    @pyqtSlot()  ##降序
    def on_radioBtnDescend_clicked(self):
        self.tabModel.setSort(self.ui.comboFields.currentIndex(),
                              Qt.DescendingOrder)
        self.tabModel.select()

    @pyqtSlot()  ##过滤,男
    def on_radioBtnMan_clicked(self):
        self.tabModel.setFilter("Gender='男'")

    ##      print(self.tabModel.filter())
    ##      self.tabModel.select()

    @pyqtSlot()  ##数据过滤,女
    def on_radioBtnWoman_clicked(self):
        self.tabModel.setFilter("Gender='女' ")

    ##      print(self.tabModel.filter())
    ##      self.tabModel.select()

    @pyqtSlot()  ##取消数据过滤
    def on_radioBtnBoth_clicked(self):
        self.tabModel.setFilter("")

    ##      print(self.tabModel.filter())
    ##      self.tabModel.select()

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

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

    def do_currentRowChanged(self, current, previous):  #行切换时的状态控制
        self.ui.actRecDelete.setEnabled(current.isValid())
        self.ui.actPhoto.setEnabled(current.isValid())
        self.ui.actPhotoClear.setEnabled(current.isValid())

        if (current.isValid() == False):
            self.ui.dbLabPhoto.clear()  #清除图片显示
            return

        self.mapper.setCurrentIndex(current.row())  #更新数据映射的行号
        curRec = self.tabModel.record(current.row())  #获取当前记录,QSqlRecord类型

        if (curRec.isNull("Photo")):  #图片字段内容为空
            self.ui.dbLabPhoto.clear()
        else:
            ##         data=bytearray(curRec.value("Photo"))   #可以工作
            data = curRec.value("Photo")  # 也可以工作
            pic = QPixmap()
            pic.loadFromData(data)
            W = self.ui.dbLabPhoto.size().width()
            self.ui.dbLabPhoto.setPixmap(pic.scaledToWidth(W))
コード例 #6
0
ファイル: myMainWindow.py プロジェクト: likeke201/qt_code
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())
コード例 #7
0
class QmyMainWindow(QMainWindow):
    def __init__(self, parent=None, dbFilename='None'):
        super().__init__(parent)  # Call the parent class. Create window.
        self.ui = Ui_MainWindow()  # Create UI object
        self.ui.setupUi(self)  # Create UI interface

        self.ui.tabWidget.setVisible(True)
        self.setCentralWidget(self.ui.tabWidget)

        # tableView setting
        self.ui.tableView.setSelectionBehavior(QAbstractItemView.SelectItems)
        self.ui.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.ui.tableView.setAlternatingRowColors(True)
        self.ui.tableView.verticalHeader().setDefaultSectionSize(44)
        self.ui.tableView.horizontalHeader().setDefaultSectionSize(70)
        self.ui.tableView.setSortingEnabled(True)

        # Initialize chart
        self.__iniPieChart()  # Initialize pie chart
        self.__iniStackedBar()  # Stacked bar

        mpl.rcParams['font.sans-serif'] = ['Calibri']
        mpl.rcParams['font.size'] = 8

        # Choose the SQLITE database drive
        self.DB = QSqlDatabase.addDatabase("QSQLITE")
        self.DB.setDatabaseName(dbFilename)  # Set the name of database
        if self.DB.open():  # Open database
            self.__openTable()  # Open tables
        else:
            QMessageBox.warning(self, "Warning",
                                "Failed to open the database.")

# ==============Self-defined Fuctions============

    def __getFieldNames(self):  # Get names of all fields.
        # Get empty records, only field name.
        emptyRec = self.tabModel.record()
        self.fldNum = {}  # Dictionary of field name and index.
        for i in range(emptyRec.count()):
            fieldName = emptyRec.fieldName(i)
            self.fldNum.setdefault(fieldName)
            self.fldNum[fieldName] = i

    def __openTable(self):  # Open the table of database
        self.tabModel = QSqlTableModel(self, self.DB)  # Data model
        # Set the table of database TODO: Can user insert their own tables from
        # the database?
        self.tabModel.setTable("battery")
        # Data storage,OnManualSubmit , OnRowChange
        self.tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        # self.tabModel.setSort(
        #     self.tabModel.fieldIndex("RANDOM"),
        #     Qt.DescendingOrder)  # Sorting
        if (self.tabModel.select() == False):  # Failed to query the data
            QMessageBox.critical(
                self, "Wrong",
                "Something wrong. Failed to open the database\n" +
                self.tabModel.lastError().text())
            return
        # self.tabModel.setFilter("NUM_RECORDS LIKE 'NONE'")
        self.__getFieldNames()  # Get the field name and index

        # Field name shown
        for i in self.fldNum:
            self.tabModel.setHeaderData(self.fldNum[i], Qt.Horizontal,
                                        i.capitalize())

# Create mappings between interface widget and the field name of data model
        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.tabModel)  # Setting data model
        self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit)

        # The relations between interface widget and field name of tabModel
        self.mapper.addMapping(self.ui.dbEditValue, self.fldNum["Value"])
        self.mapper.addMapping(self.ui.dbEditRunit, self.fldNum["Raw_unit"])
        self.mapper.addMapping(self.ui.dbComboProperty,
                               self.fldNum["Property"])
        self.mapper.addMapping(self.ui.dbEditUnit, self.fldNum["Unit"])
        self.mapper.addMapping(self.ui.dbEditName, self.fldNum["Name"])
        self.mapper.addMapping(self.ui.dbEditEname,
                               self.fldNum["Extracted_name"])
        self.mapper.addMapping(self.ui.dbEditRvalue, self.fldNum["Raw_value"])
        self.mapper.addMapping(self.ui.dbEditDOI_2, self.fldNum["DOI"])
        self.mapper.addMapping(self.ui.dbEditDOI_4, self.fldNum["Date"])
        self.mapper.addMapping(self.ui.dbEditDOI_3, self.fldNum["Title"])
        self.mapper.addMapping(self.ui.dbEditDOI, self.fldNum["Journal"])
        self.mapper.addMapping(self.ui.dbEditTag, self.fldNum["Tag"])
        self.mapper.addMapping(self.ui.dbEditInfo, self.fldNum["Info"])
        self.mapper.addMapping(self.ui.dbEditType, self.fldNum["Type"])
        self.mapper.addMapping(self.ui.dbEditWarning, self.fldNum["Warning"])
        self.mapper.addMapping(self.ui.dbEditSpecifier,
                               self.fldNum["Specifier"])
        self.mapper.toFirst()  # Move to the first record

        self.selModel = QItemSelectionModel(self.tabModel)  # Select model
        self.selModel.currentChanged.connect(
            self.do_currentChanged)  # Trigger when the current changed
        self.selModel.currentRowChanged.connect(
            self.do_currentRowChanged)  # Trigger when the current row changed

        self.ui.tableView.setModel(self.tabModel)  # Setting the data model
        self.ui.tableView.setSelectionModel(
            self.selModel)  # Setting the selection model

        #      self.ui.tableView.setColumnHidden(self.fldNum["TAG"],   True)  #Hide columns
        # self.ui.tableView.setColumnHidden(self.fldNum["INFO"],  True)  #Hide
        # columns
        self.ui.tableView.setColumnHidden(self.fldNum["Extracted_name"],
                                          True)  # Hide columns
        self.ui.tableView.setColumnHidden(self.fldNum["Unit"],
                                          True)  # Hide columns
        self.ui.tableView.setColumnHidden(self.fldNum["Num_records"],
                                          True)  # Hide columns
        # self.ui.tableView.setColumnHidden(
        #     self.fldNum["RAW_VALUE"], True)  # Hide columns

        # Update the conditions of actions of interface widget
        self.ui.actRecAppend.setEnabled(True)
        self.ui.actRecInsert.setEnabled(True)
        self.ui.actRecDelete.setEnabled(True)

        self.ui.btnDrawPieChart.setEnabled(True)  # Pie Chart
        self.ui.spinPieSize.setEnabled(True)
        self.ui.spinHoleSize.setEnabled(True)
        self.ui.chkBox_PieLegend.setEnabled(True)

        self.ui.generateButton_3.setEnabled(True)
        self.ui.searchButton_3.setEnabled(True)
        self.ui.clearButton_3.setEnabled(True)

        self.ui.frame_4.setEnabled(True)
        self.ui.frame_3.setEnabled(True)

        self.ui.searchInput.returnPressed.connect(self.ui.searchButton.click)
        self.ui.searchInput_3.returnPressed.connect(
            self.ui.searchButton_3.click)

    def __iniPieChart(self):  # Initialize pie chart
        chart = QChart()
        # chart.setTitle("Piechart")
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.setTheme(QChart.ChartTheme(0))
        self.ui.chartViewPie.setChart(chart)  # Setting chart for chart view
        self.ui.chartViewPie.setRenderHint(QPainter.Antialiasing)
        self.ui.chartViewPie.setCursor(Qt.CrossCursor)  # Setting cross cursor

    def __iniStackedBar(self):  # Initialize stacked bar chart
        chart = QChart()
        # chart.setTitle("Number of property records for each chemical")
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.setTheme(QChart.ChartTheme(0))
        self.ui.chartViewStackedBar.setChart(chart)  # Set chart
        self.ui.chartViewStackedBar.setRenderHint(QPainter.Antialiasing)
        self.ui.chartViewStackedBar.setCursor(Qt.CrossCursor)  # Set mouse

# ==========Table tab slot function==================

    @pyqtSlot()  # Save changes
    def on_actSubmit_triggered(self):
        res = self.tabModel.submitAll()
        if (res == False):
            QMessageBox.information(
                self, "Information",
                "Failed to store the changes. Wrong information. \n" +
                self.tabModel.lastError().text())
        else:
            self.ui.actSubmit.setEnabled(False)
            self.ui.actRevert.setEnabled(False)

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

    @pyqtSlot()  # Add records
    def on_actRecAppend_triggered(self):
        self.tabModel.insertRow(
            self.tabModel.rowCount(),
            QModelIndex())  # Add one record in the last row
        curIndex = self.tabModel.index(self.tabModel.rowCount() - 1,
                                       1)  # Create ModelIndex of the last row
        self.selModel.clearSelection()  # Clear selections
        # Choosing the current row when selection.
        self.selModel.setCurrentIndex(curIndex, QItemSelectionModel.Select)

        currow = curIndex.row()  # Get current row

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

    @pyqtSlot()  # Delete records
    def on_actRecDelete_triggered(self):
        # Get the current index of current model
        curIndex = self.selModel.currentIndex()
        self.tabModel.removeRow(curIndex.row(),
                                QModelIndex())  # Delete the current row
        self.tabModel.submit()

    @pyqtSlot()  # Help message box
    def on_actHelp_triggered(self):
        msg = QMessageBox()
        msg.about(
            self, "Help", '<div>'
            '<h3>Table:&nbsp;Query&nbsp;the&nbsp;database&nbsp;according&nbsp;to&nbsp;data&nbsp;types&nbsp;and&nbsp;name&nbsp;or&nbsp;DOI.</h3>'
            '<ul>'
            '<li>Search&nbsp;the&nbsp;exact&nbsp;compound&nbsp;name&nbsp;in&nbsp;"<em>Exact&nbsp;Match</em>". Search&nbsp;the&nbsp;element&nbsp;or&nbsp;part&nbsp;of&nbsp;compound&nbsp;name&nbsp;in&nbsp;"<em>Generic&nbsp;Match</em>".&nbsp;</li>'
            '<li>Click the "<em>Home</em>" or "<em>All</em>" button to view the full database</li>'
            '<li>Refer&nbsp;to&nbsp;"<em>Correctness</em>"&nbsp;column&nbsp;for&nbsp;database&nbsp;evaluation&nbsp;details.&nbsp;</li>'
            '<li>You can add your own database entries using the "<em>Insert</em>" tab; click "<em>Save</em>" to save the changes.</li>'
            '</ul>'
            '<h3>Figure:&nbsp;Statistical&nbsp;analysis&nbsp;of&nbsp;the&nbsp;database.</h3>'
            '<ul>'
            '<li><em>Pie&nbsp;chart</em>&nbsp;shows&nbsp;the&nbsp;proportion&nbsp;of&nbsp;data&nbsp;records.</li>'
            '<li><em>Stacked&nbsp;bar&nbsp;chart</em>&nbsp;shows&nbsp;the&nbsp;data&nbsp;types&nbsp;for&nbsp;each&nbsp;compound. First&nbsp;input&nbsp;the&nbsp;compound&nbsp;name,&nbsp;click&nbsp;"<em>Add</em>"&nbsp;and&nbsp;then&nbsp;"<em>Generate</em>"&nbsp;data&nbsp;for&nbsp;overview.&nbsp;</li>'
            '<li><em>Histogram&nbsp;</em>shows&nbsp;the&nbsp;distribution&nbsp;of&nbsp;each&nbsp;data&nbsp;type.</li>'
            '<li><em>Venn&nbsp;diagram</em>&nbsp;shows&nbsp;the&nbsp;correlation&nbsp;of&nbsp;each&nbsp;data&nbsp;type.</li>'
            '</ul>'
            '</div>')

    @pyqtSlot()  # Filtering
    def on_radioBtnVoltage_clicked(self):
        flag, sqlmerge = self.merged_or_not()
        print(sqlmerge)
        self.tabModel.setFilter("PROPERTY LIKE 'Voltage' AND %s" % sqlmerge)

    @pyqtSlot()  # Filtering
    def on_radioBtnCoulombic_clicked(self):
        flag, sqlmerge = self.merged_or_not()
        self.tabModel.setFilter("PROPERTY LIKE 'Coulombic Efficiency' AND %s" %
                                sqlmerge)

    @pyqtSlot()  # Filtering
    def on_radioBtnConductivity_clicked(self):
        flag, sqlmerge = self.merged_or_not()
        self.tabModel.setFilter("PROPERTY LIKE 'Conductivity' AND %s" %
                                sqlmerge)

    @pyqtSlot()  # Filetering
    def on_radioBtnCapacity_clicked(self):
        flag, sqlmerge = self.merged_or_not()
        self.tabModel.setFilter("PROPERTY LIKE 'Capacity' AND %s" % sqlmerge)

    @pyqtSlot()  # Filtering
    def on_radioBtnEnergy_clicked(self):
        flag, sqlmerge = self.merged_or_not()
        self.tabModel.setFilter("PROPERTY LIKE 'Energy' AND %s" % sqlmerge)

    @pyqtSlot()  # Cancel Filetering
    def on_radioBtnAll_clicked(self):
        flag, sqlmerge = self.merged_or_not()
        self.tabModel.setFilter("%s" % sqlmerge)

    # print(self.tabModel.filter())
    # self.tabModel.select()

    def get_elements(self):
        element_dic = {
            "Hydrogen": "H",
            "Helium": "He",
            "Lithium": "Li",
            "Beryllium": "Be",
            "Boron": "B",
            "Carbon": "C",
            "Nitrogen": "N",
            "Oxygen": "O",
            "Fluorine": "F",
            "Neon": "Ne",
            "Sodium": "Na",
            "Magnesium": "Mg",
            "Aluminum": "Al",
            "Silicon": "Si",
            "Phosphorus": "P",
            "Sulfur": "S",
            "Chlorine": "Cl",
            "Argon": "Ar",
            "Potassium": "K",
            "Calcium": "Ca",
            "Scandium": "Sc",
            "Titanium": "Ti",
            "Vanadium": "V",
            "Chromium": "Cr",
            "Manganese": "Mn",
            "Iron": "Fe",
            "Cobalt": "Co",
            "Nickel": "Ni",
            "Copper": "Cu",
            "Zinc": "Zn",
            "Gallium": "Ga",
            "Germanium": "Ge",
            "Arsenic": "As",
            "Selenium": "Se",
            "Bromine": "Br",
            "Krypton": "Kr",
            "Rubidium": "Rb",
            "Strontium": "Sr",
            "Yttrium": "Y",
            "Zirconium": "Zr",
            "Niobium": "Nb",
            "Molybdenum": "Mo",
            "Technetium": "Tc",
            "Ruthenium": "Ru",
            "Rhodium": "Rh",
            "Palladium": "Pd",
            "Silver": "Ag",
            "Cadmium": "Cd",
            "Indium": "In",
            "Tin": "Sn",
            "Antimony": "Sb",
            "Tellurium": "Te",
            "Iodine": "I",
            "Xenon": "Xe",
            "Cesium": "Cs",
            "Barium": "Ba",
            "Lanthanum": "La",
            "Cerium": "Ce",
            "Praseodymium": "Pr",
            "Neodymium": "Nd",
            "Promethium": "Pm",
            "Samarium": "Sm",
            "Europium": "Eu",
            "Gadolinium": "Gd",
            "Terbium": "Tb",
            "Dysprosium": "Dy",
            "Holmium": "Ho",
            "Erbium": "Er",
            "Thulium": "Tm",
            "Ytterbium": "Yb",
            "Lutetium": "Lu",
            "Hafnium": "Hf",
            "Tantalum": "Ta",
            "Tungsten": "W",
            "Rhenium": "Re",
            "Osmium": "Os",
            "Iridium": "Ir",
            "Platinum": "Pt",
            "Gold": "Au",
            "Mercury": "Hg",
            "Thallium": "Tl",
            "Lead": "Pb",
            "Bismuth": "Bi",
            "Polonium": "Po",
            "Astatine": "At",
            "Radon": "Rn",
            "Francium": "Fr",
            "Radium": "Ra",
            "Actinium": "Ac",
            "Thorium": "Th",
            "Protactinium": "Pa",
            "Uranium": "U",
            "Neptunium": "Np",
            "Plutonium": "Pu",
            "Americium": "Am",
            "Curium": "Cm",
            "Berkelium": "Bk",
            "Californium": "Cf",
            "Einsteinium": "Es",
            "Fermium": "Fm",
            "Mendelevium": "Md",
            "Nobelium": "No",
            "Lawrencium": "Lr",
            "Rutherfordium": "Rf",
            "Dubnium": "Db",
            "Seaborgium": "Sg",
            "Bohrium": "Bh",
            "Hassium": "Hs",
            "Meitnerium": "Mt",
            "Darmstadtium": "Ds",
            "Roentgenium": "Rg",
            "Copernicium": "Cn",
            "Nihonium": "Nh",
            "Flerovium": "Fl",
            "Moscovium": "Mc",
            "Livermorium": "Lv",
            "Tennessine": "Ts",
            "Oganesson": "Og"
        }
        return element_dic

    def merged_or_not(self):
        flag = self.ui.mergeBox.isChecked()
        if flag:
            sqlmerge = "NUM_RECORDS NOT LIKE 'NONE'"
        else:
            sqlmerge = "NUM_RECORDS LIKE 'NONE'"
        return flag, sqlmerge

    @pyqtSlot()
    def on_homeButton_clicked(self):
        self.tabModel.setFilter("NUM_RECORDS LIKE 'NONE'")
        self.ui.mergeBox.setChecked(False)

    @pyqtSlot()
    def on_mergeButton_clicked(self):
        self.tabModel.setFilter("NUM_RECORDS NOT LIKE 'NONE'")
        self.ui.mergeBox.setChecked(True)

    @pyqtSlot()
    def on_searchButton_clicked(self):
        searchtext = self.ui.searchInput.text()
        searchclass = self.ui.searchClass.currentText()
        matchtype = self.ui.matchType.currentText()
        flag, sqlmerge = self.merged_or_not()

        if searchclass == "DOI":
            if matchtype == "Exact Match":
                self.tabModel.setFilter("DOI LIKE '%s' AND %s" %
                                        (searchtext, sqlmerge))
            elif matchtype == "Generic Match":
                self.tabModel.setFilter("DOI LIKE '%%%s%%' AND %s" %
                                        (searchtext, sqlmerge))

            if self.tabModel.rowCount() == 0:
                self.tabModel.setFilter("")
                QMessageBox.warning(
                    self, "Warning",
                    "No such DOIs in the database. Please search new DOI.")

        elif searchclass == "Warning":
            if matchtype == "Exact Match":
                self.tabModel.setFilter("WARNING LIKE '%s' AND %s" %
                                        (searchtext, sqlmerge))
            elif matchtype == "Generic Match":
                self.tabModel.setFilter("WARNING LIKE '%%%s%%' AND %s" %
                                        (searchtext, sqlmerge))

            if self.tabModel.rowCount() == 0:
                self.tabModel.setFilter("")
                QMessageBox.warning(
                    self, "Warning",
                    "No such DOIs in the database. Please search new DOI.")

        elif searchclass == 'Name':
            try:
                searchtext = self.get_elements()[searchtext.capitalize()]
            except BaseException:
                pass
            if matchtype == "Exact Match":
                if self.ui.radioBtnAll.isChecked():
                    self.tabModel.setFilter("%s LIKE '%s' " %
                                            (searchclass, searchtext))
                elif self.ui.radioBtnVoltage.isChecked():
                    self.tabModel.setFilter(
                        "%s LIKE '%s' AND PROPERTY LIKE 'VOLTAGE' AND %s" %
                        (searchclass, searchtext, sqlmerge))
                elif self.ui.radioBtnCapacity.isChecked():
                    self.tabModel.setFilter(
                        "%s LIKE '%s' AND PROPERTY LIKE 'CAPACITY' AND %s" %
                        (searchclass, searchtext, sqlmerge))
                elif self.ui.radioBtnConductivity.isChecked():
                    self.tabModel.setFilter(
                        "%s LIKE '%s' AND PROPERTY LIKE 'CONDUCTIVITY' AND %s"
                        % (searchclass, searchtext, sqlmerge))
                elif self.ui.radioBtnCoulombic.isChecked():
                    self.tabModel.setFilter(
                        "%s LIKE '%s' AND PROPERTY LIKE 'COULOMBIC EFFICIENCY' AND %s "
                        % (searchclass, searchtext, sqlmerge))
                elif self.ui.radioBtnEnergy.isChecked():
                    self.tabModel.setFilter(
                        "%s LIKE '%s' AND PROPERTY LIKE 'ENERGY'AND %s " %
                        (searchclass, searchtext, sqlmerge))

            elif matchtype == "Generic Match":
                if self.ui.radioBtnAll.isChecked():
                    self.tabModel.setFilter(
                        "(EXTRACTED_NAME LIKE '%%''%s''%%' OR NAME LIKE '%s') AND %s"
                        % (searchtext, searchtext, sqlmerge))
                elif self.ui.radioBtnVoltage.isChecked():
                    self.tabModel.setFilter(
                        "EXTRACTED_NAME LIKE '%%''%s''%%' OR NAME LIKE '%s' AND %s"
                        % (searchtext, searchtext, sqlmerge))
                elif self.ui.radioBtnCapacity.isChecked():
                    self.tabModel.setFilter(
                        "EXTRACTED_NAME LIKE '%%''%s''%%' OR NAME LIKE '%s' AND %s"
                        % (searchtext, searchtext, sqlmerge))
                elif self.ui.radioBtnConductivity.isChecked():
                    self.tabModel.setFilter(
                        "EXTRACTED_NAME LIKE '%%''%s''%%' OR NAME LIKE '%s' AND %s"
                        % (searchtext, searchtext, sqlmerge))
                elif self.ui.radioBtnCoulombic.isChecked():
                    self.tabModel.setFilter(
                        "EXTRACTED_NAME LIKE '%%''%s''%%' OR NAME LIKE '%s' AND %s"
                        % (searchtext, searchtext, sqlmerge))
                elif self.ui.radioBtnEnergy.isChecked():
                    self.tabModel.setFilter(
                        "EXTRACTED_NAME LIKE '%%''%s''%%' OR NAME LIKE '%s' AND %s"
                        % (searchtext, searchtext, sqlmerge))

            if self.tabModel.rowCount() == 0:
                self.tabModel.setFilter("")
                QMessageBox.warning(
                    self, "Warning",
                    "No such compounds in the database. Please search new compounds."
                )

# ============Picture Tab 1, Pie Chart=====================

    @pyqtSlot()  # Draw the pie chart
    def on_btnDrawPieChart_clicked(self):
        self.draw_pieChart()

    @pyqtSlot(float)  # Set holeSize
    def on_spinHoleSize_valueChanged(self, arg1):
        seriesPie = self.ui.chartViewPie.chart().series()[0]
        seriesPie.setHoleSize(arg1)

    @pyqtSlot(float)  # Set pieSize
    def on_spinPieSize_valueChanged(self, arg1):
        seriesPie = self.ui.chartViewPie.chart().series()[0]
        seriesPie.setPieSize(arg1)

    @pyqtSlot(bool)  # Set legend checkbox
    def on_chkBox_PieLegend_clicked(self, checked):
        self.ui.chartViewPie.chart().legend().setVisible(checked)

    def pie_data(
            self):  # Return a list of property name and the number of property
        num_list = []
        pro_list = [
            "CAPACITY", "CONDUCTIVITY", "COULOMBIC EFFICIENCY", "ENERGY",
            "VOLTAGE"
        ]
        for i in range(len(pro_list)):
            query = QSqlQuery(
                db=self.DB,
                query=
                "SELECT COUNT(NAME) FROM BATTERY WHERE PROPERTY LIKE '%s' AND NUM_RECORDS LIKE 'NONE'"
                % pro_list[i])  # Query database
            while query.next():
                num_value = query.value(0)  # Returned value for each query

                item = self.ui.treeWidget_2.topLevelItem(i)  # The ith row
                # The 2nd column
                item.setText(1, str(num_value))
                item.setTextAlignment(1, Qt.AlignHCenter)

                num_list.append(num_value)
        return pro_list, num_list

    def draw_pieChart(self):  # Draw the pie chart
        chart = self.ui.chartViewPie.chart()

        chart.legend().setAlignment(Qt.AlignRight)  # AlignRight,AlignBottom
        chart.removeAllSeries()  # Delete all series

        seriesPie = QPieSeries()  # Pie chart series
        seriesPie.setHoleSize(self.ui.spinHoleSize.value())  # Hole size
        seriesPie.setPieSize(self.ui.spinPieSize.value())  # Pie size
        sec_count = 5  # Number of properties
        seriesPie.setLabelsVisible(True)  # Label

        pro, num = self.pie_data()
        for i in range(sec_count):
            seriesPie.append(pro[i], num[i])

        seriesPie.setLabelsVisible(True)  # Label

        # Pie hoverd when mouse selected
        seriesPie.hovered.connect(self.do_pieHovered)
        chart.addSeries(seriesPie)
        chart.setTitle("Proportion of data records for each property")
        font = QFont()
        font.setPointSize(12)
        font.setWeight(75)
        chart.setTitleFont(font)

        font = QFont()
        font.setPointSize(12)
        font.setBold(False)
        font.setWeight(35)
        legend = chart.legend()
        legend.setFont(font)

# =========Picture tab 2. StackedBar=========

    @pyqtSlot()  # Draw StackedBar
    def on_btnStackedBar_clicked(self):
        self.draw_stackedBar()

    @pyqtSlot()  # Draw horizontal StackedBar
    def on_btnStackedBarH_clicked(self):
        self.draw_stackedBar(False)

    # Search button in the Stacked bar chart tab. Add name to the first column
    # of the table.
    @pyqtSlot()
    def on_searchButton_3_clicked(self):
        searchtext = self.ui.searchInput_3.text()

        current_index = self.ui.stackedWidget.topLevelItemCount()
        item_0 = QtWidgets.QTreeWidgetItem(self.ui.stackedWidget)
        item_0.setText(0, searchtext)

    @pyqtSlot()  # Generate data using the input chemical names
    def on_generateButton_3_clicked(self):
        self.ui.zoominButton.setEnabled(True)
        self.ui.zoomoutButton.setEnabled(True)
        self.ui.originalButton.setEnabled(True)
        self.ui.btnStackedBar.setEnabled(True)  # Stacked bar chart
        self.ui.btnStackedBarH.setEnabled(True)

        current_index = self.ui.stackedWidget.topLevelItemCount()
        chemical_list = [
            self.ui.stackedWidget.topLevelItem(index).text(0)
            for index in range(current_index)
        ]  # Get a list of the inputed chemical name
        pro_list = [
            "CAPACITY", "CONDUCTIVITY", "COULOMBIC EFFICIENCY", "ENERGY",
            "VOLTAGE"
        ]
        for row, chemical in enumerate(chemical_list):
            for index, pro in enumerate(pro_list):
                query = QSqlQuery(
                    db=self.DB,
                    query=
                    "SELECT SUM(NUM_RECORDS) FROM BATTERY WHERE PROPERTY LIKE '%s' AND NAME LIKE '%s' "
                    % (pro, chemical))
                while query.next():
                    num_value = query.value(0)
                    print(num_value)
                    if num_value == "":
                        num_value = 0
                    item = self.ui.stackedWidget.topLevelItem(
                        row)  # The row'th row
                    item.setText(index + 1, str(num_value))
                    item.setTextAlignment(index + 1, Qt.AlignHCenter)

    @pyqtSlot()  # Clear button
    def on_clearButton_3_clicked(self):
        self.ui.stackedWidget.clear()

    @pyqtSlot()  # Zoom in
    def on_zoominButton_clicked(self):
        self.ui.chartViewStackedBar.chart().zoom(1.2)

    @pyqtSlot()  # Zoom out
    def on_zoomoutButton_clicked(self):
        self.ui.chartViewStackedBar.chart().zoom(0.8)

    @pyqtSlot()  # Reset original size
    def on_originalButton_clicked(self):
        self.ui.chartViewStackedBar.chart().zoomReset()

    def draw_stackedBar(self, isVertical=True):  # Stacked bar chart
        chart = self.ui.chartViewStackedBar.chart()
        chart.removeAllSeries()  # Remove all series
        chart.removeAxis(chart.axisX())  # remove axis
        chart.removeAxis(chart.axisY())
        if isVertical:  # Vertical
            chart.setTitle("Number of property records for each chemical ")
            chart.legend().setAlignment(Qt.AlignBottom)
        else:  # Horizontal
            chart.setTitle("Number of property records for each chemical")
            chart.legend().setAlignment(Qt.AlignRight)

        # Create data sets
        setCapacity = QBarSet("Capacity")
        setConductivity = QBarSet("Conductivity")
        setCoulombic = QBarSet("Coulombic")
        setEnergy = QBarSet("Energy")
        setVoltage = QBarSet("Voltage")

        chemical_Count = self.ui.stackedWidget.topLevelItemCount()
        nameList = []  # Chemical lists
        for i in range(chemical_Count):
            item = self.ui.stackedWidget.topLevelItem(i)
            # print(item.text(1))
            nameList.append(item.text(0))
            setCapacity.append(float(item.text(1)))
            setConductivity.append(float(item.text(2)))
            setCoulombic.append(float(item.text(3)))
            setEnergy.append(float(item.text(4)))
            setVoltage.append(float(item.text(5)))

        # Create series
        if isVertical:
            seriesBar = QStackedBarSeries()
        else:
            seriesBar = QHorizontalStackedBarSeries()

        seriesBar.append(setCapacity)
        seriesBar.append(setConductivity)
        seriesBar.append(setCoulombic)
        seriesBar.append(setEnergy)
        seriesBar.append(setVoltage)

        seriesBar.setLabelsVisible(True)  # Show labels for each bar
        seriesBar.setLabelsFormat("@value")
        seriesBar.setLabelsPosition(QAbstractBarSeries.LabelsCenter)

        seriesBar.setBarWidth(0.3)

        chart.addSeries(seriesBar)

        axisStud = QBarCategoryAxis()  # Category axis
        axisStud.append(nameList)
        axisStud.setRange(nameList[0], nameList[chemical_Count - 1])

        axisValue = QValueAxis()  # Value axis
        # axisValue.setRange(0, 300)
        axisValue.setTitleText("Number of records")
        # axisValue.setTickCount(6)
        axisValue.applyNiceNumbers()

        if isVertical:
            chart.setAxisX(axisStud, seriesBar)
            chart.setAxisY(axisValue, seriesBar)
        else:
            chart.setAxisY(axisStud, seriesBar)
            chart.setAxisX(axisValue, seriesBar)

        for marker in chart.legend().markers():  # QLegendMarker lists
            marker.clicked.connect(self.do_LegendMarkerClicked)

# =========Picture tab 3. Histogram=========

    @pyqtSlot(bool)  # Show toolbar
    def on_gBoxHist_toolbar_2_clicked(self, checked):
        self.ui.widgetHist_2.setToolbarVisible(checked)

    @pyqtSlot()  # Draw
    def on_histButton_clicked(self):
        self.__drawHist()

    def hist_data(self, pro):
        query = QSqlQuery(
            db=self.DB,
            query=
            "SELECT VALUE FROM BATTERY WHERE PROPERTY LIKE '%s' AND NUM_RECORDS LIKE 'NONE'"
            % pro)
        data = []
        while query.next():
            num_value = query.value(0)
            data.append(num_value)
        return data

    def __drawHist(self):  # Histogram
        pro = self.ui.propertycomboBox_2.currentText()
        data = self.hist_data(pro)
        self.ui.widgetHist_2.figure.clear()  # Clear figure

        ax = self.ui.widgetHist_2.figure.add_subplot(1, 1, 1)

        if pro == 'Capacity':
            M, bins, patches = ax.hist(
                [5000 if float(i) > 4999 else float(i) for i in data],
                bins='auto',
                color='darkgreen',
                alpha=0.5,
                rwidth=1)
            ax.set_xlim(0, 5001)
            # ax.set_ylim(0,15000)
            ax.tick_params(labelsize=12)
            ax.set_xticklabels(['0', '1000', '2000', '3000', '4000', '5000+'])
            ax.set_xlabel('Capacity (mAh/g)', fontsize=14)
            ax.set_ylabel('Frequency', fontsize=14)
            ax.set_title('Battery Capacity Distrbution', fontsize=14)
            ax.figure.canvas.draw()

        elif pro == "Voltage":
            count1 = []
            for i in data:
                count1.append(float(i))

            n, bins, patches = ax.hist(x=count1,
                                       bins='auto',
                                       range=(0, 8),
                                       color='r',
                                       alpha=0.5,
                                       rwidth=1)
            ax.set_xticklabels(['0', '1', '2', '3', '4', '5', '6', '7', '8+'])

            ax.set_xlim(0, 8)
            ax.tick_params(labelsize=12)
            ax.set_xlabel('Voltage (V)', fontsize=14)
            ax.set_ylabel('Frequency', fontsize=14)
            ax.set_title('Battery Voltage Distrbution', fontsize=14)
            ax.figure.canvas.draw()

        elif pro == "Energy":
            n, bins, patches = ax.hist(
                [3000 if float(i) > 2999 else float(i) for i in data],
                bins='auto',
                color='y',
                alpha=0.5,
                rwidth=1)
            ax.set_xticklabels(
                ['0', '500', '1000', '1500', '2000', '2500', '3000+'])
            ax.set_xlim(0, 3001)
            ax.tick_params(labelsize=12)
            ax.set_xlabel('Energy (Wh/kg)', fontsize=14)
            ax.set_ylabel('Frequency', fontsize=14)
            ax.set_title('Battery Energy Distrbution', fontsize=14)
            ax.figure.canvas.draw()

        elif pro == "Coulombic Efficiency":
            dataplot = [float(i) for i in data]
            n, bins, patches = ax.hist(x=dataplot,
                                       bins='auto',
                                       color='c',
                                       alpha=0.5,
                                       rwidth=1)
            ax.set_xlim(0, 100)
            ax.tick_params(labelsize=12)
            ax.set_xlabel('Coulombic Effciency (%)', fontsize=14)
            ax.set_ylabel('Frequency', fontsize=14)
            ax.set_title('Battery Coulombic Effciency Distrbution',
                         fontsize=14)
            ax.figure.canvas.draw()

        elif pro == "Conductivity":
            dataplot = [float(i) for i in data]
            n, bins, patches = ax.hist(x=dataplot,
                                       bins=np.logspace(
                                           np.log10(1e-15), np.log10(1)),
                                       color='k',
                                       alpha=0.5,
                                       rwidth=1)
            ax.set_xlim(1e-20, 10)
            ax.set_xscale('log')
            ax.tick_params(labelsize=12)
            ax.set_xlabel('log10 (Conductivity (S/cm))', fontsize=14)
            ax.set_ylabel('Frequency', fontsize=14)
            ax.set_title('Battery Conductivity Distrbution', fontsize=14)
            ax.figure.canvas.draw()

# =========Picture tab 4. Venn diagram=========

    @pyqtSlot()  # Draw
    def on_btnVenn_clicked(self):
        self.__drawVenn()

    @pyqtSlot(bool)  # Show toolbar
    def on_gBoxHist_toolbar_3_clicked(self, checked):
        self.ui.widgetVenn.setToolbarVisible(checked)

    def __drawVenn(self):
        self.ui.widgetVenn.figure.clear()  # Clear figure

        pro_list = [
            "Capacity", "Conductivity", "Coulombic Efficiency", "Energy",
            "Voltage"
        ]
        data_dic = {}
        color_dic = dict(zip(pro_list, ['C0', 'C2', 'C6', 'C8', 'C9']))

        for i in pro_list:
            query = QSqlQuery(
                db=self.DB,
                query=
                "SELECT COUNT(DISTINCT NAME) FROM BATTERY WHERE PROPERTY LIKE '%s' AND NUM_RECORDS LIKE 'NONE'"
                % i)
            while query.next():
                num_value = query.value(0)
                data_dic[i] = num_value

        for i, combo in enumerate(itertools.combinations(pro_list, 2)):

            query = QSqlQuery(
                db=self.DB,
                query=
                "SELECT COUNT() FROM (SELECT DISTINCT NAME AS PRO1 FROM BATTERY WHERE PROPERTY LIKE '%s'AND NUM_RECORDS LIKE 'NONE') INNER JOIN (SELECT DISTINCT NAME AS PRO2 FROM BATTERY WHERE PROPERTY LIKE '%s'AND NUM_RECORDS LIKE 'NONE') ON PRO1 = PRO2"
                % combo)
            while query.next():
                num = query.value(0)
            x3 = num
            x1 = data_dic[combo[0]] - x3
            x2 = data_dic[combo[1]] - x3

            hf = self.ui.widgetVenn.figure
            # hf.set_figheight(30)
            # hf.set_figwidth(30)
            # print(dir(hf))

            hf.set_size_inches((10, 10))
            ax1 = hf.add_subplot(5, 2, i + 1)
            v = venn2(subsets=(x1, x2, x3),
                      set_labels=(combo[0], combo[1]),
                      ax=ax1)

            v.get_patch_by_id('A').set_alpha(1)
            v.get_patch_by_id('A').set_color(color_dic[combo[0]])
            v.get_patch_by_id('B').set_color(color_dic[combo[1]])

            ax1.figure.canvas.draw()

# =============Self-defined slot function===============================

# Update the conditions of actPost and actCancel

    def do_currentChanged(self, current, previous):
        self.ui.actSubmit.setEnabled(
            self.tabModel.isDirty())  # Use when not saving changes
        self.ui.actRevert.setEnabled(self.tabModel.isDirty())

    def do_currentRowChanged(self, current,
                             previous):  # Control during row changes
        self.ui.actRecDelete.setEnabled(current.isValid())

        # Update current row index of mapping
        self.mapper.setCurrentIndex(current.row())
        # Get current record,QSqlRecord
        curRec = self.tabModel.record(current.row())

    def do_pieHovered(self, pieSlice,
                      state):  # Mouse move in and out in the pie chart
        pieSlice.setExploded(state)  # Pop-up animation
        if state:  # Show the tab of percentages
            self.__oldLabel = pieSlice.label()  # Save original labels
            pieSlice.setLabel(self.__oldLabel + ": %.1f%%" %
                              (pieSlice.percentage() * 100))
            font = QFont()
            font.setPointSize(10)
            font.setBold(False)
            font.setWeight(25)
            pieSlice.setLabelFont(font)
        else:  # show original labels
            pieSlice.setLabel(self.__oldLabel)
            font = QFont()
            font.setPointSize(10)
            font.setBold(False)
            font.setWeight(25)
            pieSlice.setLabelFont(font)

    def do_LegendMarkerClicked(self):  # Click legend marker
        marker = self.sender()  # QLegendMarker

        marker.series().setVisible(not marker.series().isVisible())
        marker.setVisible(True)
        alpha = 1.0
        if not marker.series().isVisible():
            alpha = 0.5

        brush = marker.labelBrush()  # QBrush
        color = brush.color()  # QColor
        color.setAlphaF(alpha)
        brush.setColor(color)
        marker.setLabelBrush(brush)

        brush = marker.brush()
        color = brush.color()
        color.setAlphaF(alpha)
        brush.setColor(color)
        marker.setBrush(brush)

        pen = marker.pen()  # QPen
        color = pen.color()
        color.setAlphaF(alpha)
        pen.setColor(color)
        marker.setPen(pen)
コード例 #8
0
ファイル: 0701.py プロジェクト: falomsc/pyqtStudy
class QmyMainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setCentralWidget(self.ui.splitter)

        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(60)

    def __openTable(self):
        self.tabModel = QSqlTableModel(self, self.DB)
        self.tabModel.setTable("employee")
        self.tabModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.tabModel.setSort(self.tabModel.fieldIndex("empNo"), Qt.AscendingOrder)
        if(self.tabModel.select()==False):
            QMessageBox.critical(self, "错误信息", "打开数据表错误,错误信息\n"+self.tabModel.lastError().text())
            return
        self.__getFieldNames()

        self.tabModel.setHeaderData(self.fldNum["empNo"], Qt.Horizontal, "工号")
        self.tabModel.setHeaderData(self.fldNum["Name"], Qt.Horizontal, "姓名")
        self.tabModel.setHeaderData(self.fldNum["Gender"], Qt.Horizontal, "性别")
        self.tabModel.setHeaderData(self.fldNum["Birthday"], Qt.Horizontal, "出生日期")
        self.tabModel.setHeaderData(self.fldNum["Province"], Qt.Horizontal, "省份")
        self.tabModel.setHeaderData(self.fldNum["Department"], Qt.Horizontal, "部门")
        self.tabModel.setHeaderData(self.fldNum["Salary"], Qt.Horizontal, "工资")
        self.tabModel.setHeaderData(self.fldNum["Memo"], Qt.Horizontal, "备注")
        self.tabModel.setHeaderData(self.fldNum["Photo"], Qt.Horizontal, "照片")

        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.tabModel)
        self.mapper.setSubmitPolicy(QDataWidgetMapper.AutoSubmit)
        self.mapper.addMapping(self.ui.dbSpinEmpNo, self.fldNum["empNo"])
        self.mapper.addMapping(self.ui.dbEditName, self.fldNum["Name"])
        self.mapper.addMapping(self.ui.dbComboSex, self.fldNum["Gender"])
        self.mapper.addMapping(self.ui.dbEditBirth, self.fldNum["Birthday"])
        self.mapper.addMapping(self.ui.dbComboProvince, self.fldNum["Province"])
        self.mapper.addMapping(self.ui.dbComboDep, self.fldNum["Department"])
        self.mapper.addMapping(self.ui.dbSpinSalary, self.fldNum["Salary"])
        self.mapper.addMapping(self.ui.dbEditMemo, self.fldNum["Memo"])
        self.mapper.toFirst()

        self.selModel = QItemSelectionModel(self.tabModel)
        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)

        self.ui.tableView.setColumnHidden(self.fldNum["Memo"], True)
        self.ui.tableView.setColumnHidden(self.fldNum["Photo"], True)


        strList = ("男", "女")
        self.__delegatesex = QmyComboBoxDelegate()
        self.__delegatesex.setItems(strList, False)
        self.ui.tableView.setItemDelegateForColumn(self.fldNum["Gender"], self.__delegatesex)

        strList = ("销售部", "技术部", "生产部", "行政部")
        self.__delegateDepart = QmyComboBoxDelegate()
        self.__delegateDepart.setItems(strList, True)
        self.ui.tableView.setItemDelegateForColumn(self.fldNum["Department"], self.__delegateDepart)

        self.ui.actOpenDB.setEnabled(False)
        self.ui.actOpenDB.setEnabled(False)

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

        self.ui.groupBoxSort.setEnabled(True)
        self.ui.groupBoxFilter.setEnabled(True)


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

    def do_currentChanged(self, current, previous):
        self.ui.actSubmit.setEnabled(self.tabModel.isDirty())
        self.ui.actRevert.setEnabled(self.tabModel.isDirty())

    def do_currentRowChanged(self, current, previous):
        self.ui.actRecDelete.setEnabled(current.isValid())
        self.ui.actPhoto.setEnabled(current.isValid())
        self.ui.actPhotoClear.setEnabled(current.isValid())

        if(current.isValid() == False):
            self.ui.dbLabPhoto.clear()
            return

        self.mapper.setCurrentIndex(current.row())
        curRec = self.tabModel.record(current.row())

        if(curRec.isNull("Photo")):
            self.ui.dbLabPhoto.clear()
        else:
            data = curRec.value("Photo")
            pic = QPixmap()
            pic.loadFromData(data)
            w = self.ui.dbLabPhoto.size().width()
            self.ui.dbLabPhoto.setPixmap(pic.scaledToWidth(w))

    @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_actRecAppend_triggered(self):
        self.tabModel.insertRow(self.tabModel.rowCount(), QModelIndex())
        curIndex = self.tabModel.index(self.tabModel.rowCount()-1, 1)
        self.selModel.clearSelection()
        self.selModel.setCurrentIndex(curIndex, QItemSelectionModel.Select)
        currow = curIndex.row()
        self.tabModel.setData(self.tabModel.index(currow, self.fldNum["empNo"]), 2000+self.tabModel.rowCount())
        self.tabModel.setData(self.tabModel.index(currow, self.fldNum["Gender"]), "男")

    @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_actPhotoClear_triggered(self):
        curRecNo = self.selModel.currentIndex().row()
        curRec = self.tabModel.record(curRecNo)
        curRec.setNull("Photo")
        self.tabModel.setRecord(curRecNo, curRec)
        self.ui.dbLabPhoto.clear()

    @pyqtSlot()
    def on_actPhoto_triggered(self):
        fileName, filt = QFileDialog.getOpenFileName(self, "选择图片文件", "", "照片(*.jpg")
        if(fileName==''):
            return
        file=QFile(fileName)
        file.open(QIODevice.ReadOnly)
        try:
            data = file.readAll()
        finally:
            file.close()

        curRecNo = self.selModel.currentIndex().row()
        curRec = self.tabModel.record(curRecNo)
        curRec.setValue("Photo", data)
        self.tabModel.setRecord(curRecNo, curRec)

        pic = QPixmap()
        pic.loadFromData(data)
        w = self.ui.dbLabPhoto.width()
        self.ui.dbLabPhoto.setPixmap(pic.scaledToWidth(w))

    @pyqtSlot()
    def on_actScan_triggered(self):
        if(self.tabModel.rowCount()==0):
            return
        for i in range(self.tabModel.rowCount()):
            aRec = self.tabModel.record(i)
            salary = aRec.value("Salary")
            salary = salary*1.1
            aRec.setValue("Salary", salary)
            self.tabModel.setRecord(i, aRec)

        if(self.tabModel.submitAll()):
            QMessageBox.information(self, "消息", "涨工资计算完毕了")

    @pyqtSlot()
    def on_comboFields_currentIndexChanged(self, index):
        if self.ui.radioBtnAscend.isChecked():
            self.tabModel.setSort(index, Qt.AscendingOrder)
        else:
            self.tabModel.setSort(index, Qt.DescendingOrder)
        self.tabModel.select()

    @pyqtSlot()
    def on_radioBtnAscend_clicked(self):
        self.tabModel.setSort(self.ui.comboFields.currentIndex(), Qt.AscendingOrder)
        self.tabModel.select()

    @pyqtSlot()
    def on_radioBtnDescend_clicked(self):
        self.tabModel.setSort(self.ui.comboFields.currentIndex(), Qt.DescendingOrder)
        self.tabModel.select()

    @pyqtSlot()
    def on_radioBtnMan_clicked(self):
        self.tabModel.setFilter("Gender='男'")

    @pyqtSlot()
    def on_radioBtnWoman_clicked(self):
        self.tabModel.setFilter("Gender='女'")

    @pyqtSlot()
    def on_radioBtnBoth_clicked(self):
        self.tabModel.setFilter("")
コード例 #9
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.setAlternatingRowColors(True)
        self.ui.tableView.verticalHeader().setDefaultSectionSize(22)
        self.ui.tableView.horizontalHeader().setDefaultSectionSize(60)

    def __getFieldNames(self):
        emptyRec = self.qryModel.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.qryModel = QSqlQueryModel(self)
        self.qryModel.setQuery(
            '''SELECT empNo, Name, Gender, Birthday, Province, Department, Salary FROM employee ORDER BY empNo'''
        )
        if self.qryModel.lastError().isValid():
            QMessageBox.critical(
                self, "错误",
                "数据表查询错误,错误信息\n" + self.qryModel.lastError().text())
            return
        self.__getFieldNames()
        self.qryModel.setHeaderData(0, Qt.Horizontal, "工号")
        self.qryModel.setHeaderData(1, Qt.Horizontal, "姓名")
        self.qryModel.setHeaderData(2, Qt.Horizontal, "性别")
        self.qryModel.setHeaderData(3, Qt.Horizontal, "出生日期")
        self.qryModel.setHeaderData(4, Qt.Horizontal, "省份")
        self.qryModel.setHeaderData(5, Qt.Horizontal, "部门")
        self.qryModel.setHeaderData(6, Qt.Horizontal, "工资")

        self.selModel = QItemSelectionModel(self.qryModel)
        self.selModel.currentRowChanged.connect(self.do_currentRowChanged)
        self.ui.tableView.setModel(self.qryModel)
        self.ui.tableView.setSelectionModel(self.selModel)
        self.ui.actOpenDB.setEnabled(False)
        self.ui.actRecInsert.setEnabled(True)
        self.ui.actRecDelete.setEnabled(True)
        self.ui.actRecEdit.setEnabled(True)
        self.ui.actScan.setEnabled(True)
        self.ui.actTestSQL.setEnabled(True)

    def __updateRecord(self, recNo):
        curRec = self.qryModel.record(recNo)
        empNo = curRec.value("EmpNo")
        query = QSqlQuery(self.DB)
        query.prepare("SELECT * FROM employee WHERE EmpNo = :ID")
        query.bindValue(":ID", empNo)
        query.exec()
        query.first()
        if (not query.isValid()):
            return

        curRec = query.record()
        dlgData = QmyDialogData(self)
        dlgData.setUpdateRecord(curRec)
        ret = dlgData.exec()
        if (ret != QDialog.Accepted):
            return

        recData = dlgData.getRecordData()
        query.prepare('''UPDATE employee SET Name=:Name, Gender=:Gender,
                      Birthday=:Birthday, Province=:Province,
                      Department=:Department, Salary=:Salary,
                      Memo=:Memo, Photo=:Photo WHERE EmpNo = :ID''')

        query.bindValue(":Name", recData.value("Name"))
        query.bindValue(":Gender", recData.value("Gender"))
        query.bindValue(":Birthday", recData.value("Birthday"))
        query.bindValue(":Province", recData.value("Province"))
        query.bindValue(":Department", recData.value("Department"))
        query.bindValue(":Salary", recData.value("Salary"))
        query.bindValue(":Memo", recData.value("Memo"))
        query.bindValue(":Photo", recData.value("Photo"))
        query.bindValue(":ID", empNo)

        if (not query.exec()):
            QMessageBox.critical(self, "错误",
                                 "记录更新错误\n" + query.lastError().text())
        else:
            self.qryModel.query().exec()

    @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_actRecInsert_triggered(self):
        query = QSqlQuery(self.DB)
        query.exec("select * from employee where EmpNo = -1")
        curRec = query.record()
        curRec.setValue("EmpNo", self.qryModel.rowCount() + 3000)
        dlgData = QmyDialogData(self)
        dlgData.setInsertRecord(curRec)

        ret = dlgData.exec()
        if (ret != QDialog.Accepted):
            return

        recData = dlgData.getRecordData()

        query.prepare('''INSERT INTO employee (EmpNo,Name,Gender,Birthday,
                    Province,Department,Salary,Memo,Photo)
                    VALUES(:EmpNo,:Name, :Gender,:Birthday,:Province,
                    :Department,:Salary,:Memo,:Photo)''')
        query.bindValue(":EmpNo", recData.value("EmpNo"))
        query.bindValue(":Name", recData.value("Name"))
        query.bindValue(":Gender", recData.value("Gender"))
        query.bindValue(":Birthday", recData.value("Birthday"))

        query.bindValue(":Province", recData.value("Province"))
        query.bindValue(":Department", recData.value("Department"))

        query.bindValue(":Salary", recData.value("Salary"))
        query.bindValue(":Memo", recData.value("Memo"))
        query.bindValue(":Photo", recData.value("Photo"))

        res = query.exec()
        if (res == False):
            QMessageBox.critical(self, "错误",
                                 "插入记录错误\n" + query.lastError().text())
        else:
            sqlStr = self.qryModel.query().executedQuery()
            self.qryModel.setQuery(sqlStr)

    @pyqtSlot()
    def on_actRecDelete_triggered(self):
        curRecNo = self.selModel.currentIndex().row()
        curRec = self.qryModel.record(curRecNo)
        if (curRec.isEmpty()):
            return
        empNo = curRec.value("EmpNo")
        query = QSqlQuery(self.DB)
        query.prepare("DELETE  FROM employee WHERE EmpNo = :ID")
        query.bindValue(":ID", empNo)
        if (query.exec() == False):
            QMessageBox.critical(self, "错误",
                                 "删除记录出现错误\n" + query.lastError().text())
        else:
            sqlStr = self.qryModel.query().executedQuery()
            self.qryModel.setQuery(sqlStr)

    @pyqtSlot()
    def on_actRecEdit_triggered(self):
        curRecNo = self.selModel.currentIndex().row()
        self.__updateRecord(curRecNo)

    def on_tableView_doubleClicked(self, index):
        curRecNo = index.row()
        self.__updateRecord(curRecNo)

    @pyqtSlot()
    def on_actScan_triggered(self):
        qryEmpList = QSqlQuery(self.DB)
        qryEmpList.exec("SELECT empNo,Salary FROM employee ORDER BY empNo")
        qryUpdate = QSqlQuery(self.DB)
        qryUpdate.prepare(
            '''UPDATE employee SET Salary=:Salary WHERE EmpNo = :ID''')

        qryEmpList.first()
        while (qryEmpList.isValid()):
            empID = qryEmpList.value("empNo")
            salary = qryEmpList.value("Salary")
            salary = salary + 500

            qryUpdate.bindValue(":ID", empID)
            qryUpdate.bindValue(":Salary", salary)
            qryUpdate.exec()

            if not qryEmpList.next():
                break
        self.qryModel.query().exec()
        QMessageBox.information(self, "提示", "涨工资计算完毕")

    @pyqtSlot()
    def on_actTestSQL_triggered(self):
        query = QSqlQuery(self.DB)
        query.exec('''UPDATE employee SET Salary=500+Salary''')
        sqlStr = self.qryModel.query().executedQuery()
        self.qryModel.setQuery(sqlStr)
        print("SQL OK")

    def do_currentRowChanged(self, current, previous):
        if (current.isValid() == False):
            return
        curRec = self.qryModel.record(current.row())
        empNo = curRec.value("EmpNo")
        self.ui.statusBar.showMessage("当前记录:工号 = %d" % empNo)
コード例 #10
0
ファイル: myMainWindow.py プロジェクト: likeke201/qt_code
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.splitter)

        self.__ColCount = 6  #列数=6
        self.itemModel = QStandardItemModel(5, self.__ColCount,
                                            self)  # 数据模型,10行6列

        self.selectionModel = QItemSelectionModel(self.itemModel)  #Item选择模型
        self.selectionModel.currentChanged.connect(self.do_curChanged)

        self.__lastColumnTitle = "测井取样"
        self.__lastColumnFlags = (Qt.ItemIsSelectable
                                  | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)

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

        oneOrMore = QAbstractItemView.ExtendedSelection
        self.ui.tableView.setSelectionMode(oneOrMore)  #可多选

        itemOrRow = QAbstractItemView.SelectItems
        self.ui.tableView.setSelectionBehavior(itemOrRow)  #单元格选择

        self.ui.tableView.verticalHeader().setDefaultSectionSize(22)  #缺省行高
        self.ui.tableView.setAlternatingRowColors(True)  #交替行颜色

        self.ui.tableView.setEnabled(False)  #先禁用tableView
        self.__buildStatusBar()

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

    def __buildStatusBar(self):  ##构建状态栏
        self.LabCellPos = QLabel("当前单元格:", self)
        self.LabCellPos.setMinimumWidth(180)
        self.ui.statusBar.addWidget(self.LabCellPos)

        self.LabCellText = QLabel("单元格内容:", self)
        self.LabCellText.setMinimumWidth(150)
        self.ui.statusBar.addWidget(self.LabCellText)

        self.LabCurFile = QLabel("当前文件:", self)
        self.ui.statusBar.addPermanentWidget(self.LabCurFile)

    def __iniModelFromStringList(self, allLines):  ##从字符串列表构建模型
        rowCnt = len(allLines)  #文本行数,第1行是标题
        self.itemModel.setRowCount(rowCnt - 1)  #实际数据行数

        headerText = allLines[0].strip()  #第1行是表头,去掉末尾的换行符 "\n"
        headerList = headerText.split("\t")  #转换为字符串列表
        self.itemModel.setHorizontalHeaderLabels(headerList)  #设置表头标题

        self.__lastColumnTitle = headerList[len(headerList) -
                                            1]  # 最后一列表头的标题,即“测井取样”

        lastColNo = self.__ColCount - 1  #最后一列的列号
        for i in range(rowCnt - 1):
            lineText = allLines[i + 1].strip()  #一行的文字,\t分隔
            strList = lineText.split("\t")  #分割为字符串列表
            for j in range(self.__ColCount - 1):  #不含最后一列
                item = QStandardItem(strList[j])
                self.itemModel.setItem(i, j, item)  #设置模型的item

            item = QStandardItem(self.__lastColumnTitle)  #最后一列
            item.setFlags(self.__lastColumnFlags)
            item.setCheckable(True)
            if (strList[lastColNo] == "0"):
                item.setCheckState(Qt.Unchecked)
            else:
                item.setCheckState(Qt.Checked)

            self.itemModel.setItem(i, lastColNo, item)  #设置最后一列的item

    def __setCellAlignment(self, align=Qt.AlignHCenter):
        if (not self.selectionModel.hasSelection()):  #没有选择的项
            return
        selectedIndex = self.selectionModel.selectedIndexes()  #模型索引列表
        count = len(selectedIndex)
        for i in range(count):
            index = selectedIndex[i]  #获取其中的一个模型索引
            item = self.itemModel.itemFromIndex(index)  #获取一个单元格的项数据对象
            item.setTextAlignment(align)  #设置文字对齐方式

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

    @pyqtSlot()  ##“打开文件”
    def on_actOpen_triggered(self):
        ##        curPath=QDir.currentPath() #获取当前路径
        curPath = os.getcwd()  #获取当前路径

        filename, flt = QFileDialog.getOpenFileName(
            self, "打开一个文件", curPath, "井斜数据文件(*.txt);;所有文件(*.*)")
        if (filename == ""):
            return

        self.LabCurFile.setText("当前文件:" + filename)
        self.ui.plainTextEdit.clear()

        aFile = open(filename, 'r')
        allLines = aFile.readlines()  #读取所有行,list类型,每行末尾带有 \n
        aFile.close()

        for strLine in allLines:
            self.ui.plainTextEdit.appendPlainText(strLine.strip())

        self.__iniModelFromStringList(allLines)
        self.ui.tableView.setEnabled(True)  #tableView可用
        self.ui.actAppend.setEnabled(True)  #更新Actions的enable属性
        self.ui.actInsert.setEnabled(True)
        self.ui.actDelete.setEnabled(True)
        self.ui.actSave.setEnabled(True)
        self.ui.actModelData.setEnabled(True)

    @pyqtSlot()  ##保存文件
    def on_actSave_triggered(self):
        ##      curPath=QDir.currentPath() #获取当前路径
        curPath = os.getcwd()  #获取当前路径
        filename, flt = QFileDialog.getSaveFileName(
            self, "保存文件", curPath, "井斜数据文件(*.txt);;所有文件(*.*)")
        if (filename == ""):
            return

        self.on_actModelData_triggered()  #更新数据到plainTextEdit

        aFile = open(filename, 'w')  #以写方式打开
        aFile.write(self.ui.plainTextEdit.toPlainText())
        aFile.close()

    @pyqtSlot()  ##在最后添加一行
    def on_actAppend_triggered(self):
        itemlist = []  # QStandardItem 对象列表
        for i in range(self.__ColCount - 1):  #不包括最后一列
            item = QStandardItem("0")
            itemlist.append(item)

        item = QStandardItem(self.__lastColumnTitle)  #最后一列
        item.setCheckable(True)
        item.setFlags(self.__lastColumnFlags)
        itemlist.append(item)

        self.itemModel.appendRow(itemlist)  #添加一行
        curIndex = self.itemModel.index(self.itemModel.rowCount() - 1, 0)
        self.selectionModel.clearSelection()
        self.selectionModel.setCurrentIndex(curIndex,
                                            QItemSelectionModel.Select)

    @pyqtSlot()  ##插入一行
    def on_actInsert_triggered(self):
        itemlist = []  #  QStandardItem 对象列表
        for i in range(self.__ColCount - 1):  #不包括最后一列
            item = QStandardItem("0")
            itemlist.append(item)

        item = QStandardItem(self.__lastColumnTitle)  #最后一列
        item.setFlags(self.__lastColumnFlags)
        item.setCheckable(True)
        item.setCheckState(Qt.Checked)
        itemlist.append(item)

        curIndex = self.selectionModel.currentIndex()
        #获取当前选中项的模型索引
        self.itemModel.insertRow(curIndex.row(), itemlist)
        #在当前行的前面插入一行
        self.selectionModel.clearSelection()
        self.selectionModel.setCurrentIndex(curIndex,
                                            QItemSelectionModel.Select)

    @pyqtSlot()  ##删除当前行
    def on_actDelete_triggered(self):
        curIndex = self.selectionModel.currentIndex()  #获取当前选择单元格的模型索引
        self.itemModel.removeRow(curIndex.row())  #删除当前行

    @pyqtSlot()  ##左对齐
    def on_actAlignLeft_triggered(self):
        self.__setCellAlignment(Qt.AlignLeft | Qt.AlignVCenter)

    @pyqtSlot()  ##中间对齐
    def on_actAlignCenter_triggered(self):
        self.__setCellAlignment(Qt.AlignHCenter | Qt.AlignVCenter)

    @pyqtSlot()  ##右对齐
    def on_actAlignRight_triggered(self):
        self.__setCellAlignment(Qt.AlignRight | Qt.AlignVCenter)

    @pyqtSlot(bool)  ##字体Bold
    def on_actFontBold_triggered(self, checked):
        if (not self.selectionModel.hasSelection()):  #没有选择的项
            return
        selectedIndex = self.selectionModel.selectedIndexes()  #模型索引列表
        count = len(selectedIndex)
        for i in range(count):
            index = selectedIndex[i]  #获取其中的一个模型索引
            item = self.itemModel.itemFromIndex(index)  #获取一个单元格的项数据对象
            font = item.font()
            font.setBold(checked)
            item.setFont(font)

    @pyqtSlot()  ##模型数据显示到plainTextEdit里
    def on_actModelData_triggered(self):
        self.ui.plainTextEdit.clear()
        lineStr = ""
        for i in range(self.itemModel.columnCount() - 1):  #表头,不含最后一列
            item = self.itemModel.horizontalHeaderItem(i)
            lineStr = lineStr + item.text() + "\t"
        item = self.itemModel.horizontalHeaderItem(self.__ColCount - 1)  #最后一列
        lineStr = lineStr + item.text()  #表头文字字符串
        self.ui.plainTextEdit.appendPlainText(lineStr)

        for i in range(self.itemModel.rowCount()):
            lineStr = ""
            for j in range(self.itemModel.columnCount() - 1):  #不包括最后一列
                item = self.itemModel.item(i, j)
                lineStr = lineStr + item.text() + "\t"
            item = self.itemModel.item(i, self.__ColCount - 1)  #最后一列
            if (item.checkState() == Qt.Checked):
                lineStr = lineStr + "1"
            else:
                lineStr = lineStr + "0"
            self.ui.plainTextEdit.appendPlainText(lineStr)

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

    def do_curChanged(self, current, previous):
        if (current != None):  #当前模型索引有效
            text = "当前单元格:%d行,%d列" % (current.row(), current.column())
            self.LabCellPos.setText(text)
            item = self.itemModel.itemFromIndex(current)  #从模型索引获得Item
            self.LabCellText.setText("单元格内容:" + item.text())  #显示item的文字内容

            font = item.font()  #获取item的字体
            self.ui.actFontBold.setChecked(font.bold())  #更新actFontBold的check状态
コード例 #11
0
ファイル: myMainWindow.py プロジェクト: bingonline/QTPrj2
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.SelectRows)
        ##      self.ui.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.ui.tableView.setAlternatingRowColors(True)
        self.ui.tableView.verticalHeader().setDefaultSectionSize(22)
        self.ui.tableView.horizontalHeader().setDefaultSectionSize(60)
##      self.ui.tableView.resizeColumnsToContents()

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

    def __getFieldNames(self):  ##获取所有字段名称
        emptyRec = self.qryModel.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.qryModel = QSqlQueryModel(self)
        self.qryModel.setQuery(
            '''SELECT empNo, Name, Gender,  Birthday,  Province,
                             Department, Salary FROM employee ORDER BY empNo'''
        )

        if self.qryModel.lastError().isValid():
            QMessageBox.critical(
                self, "错误",
                "数据表查询错误,错误信息\n" + self.qryModel.lastError().text())
            return

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

        ##字段显示名
        self.qryModel.setHeaderData(0, Qt.Horizontal, "工号")
        self.qryModel.setHeaderData(1, Qt.Horizontal, "姓名")
        self.qryModel.setHeaderData(2, Qt.Horizontal, "性别")
        self.qryModel.setHeaderData(3, Qt.Horizontal, "出生日期")
        self.qryModel.setHeaderData(4, Qt.Horizontal, "省份")
        self.qryModel.setHeaderData(5, Qt.Horizontal, "部门")
        self.qryModel.setHeaderData(6, Qt.Horizontal, "工资")

        ##      self.qryModel.setHeaderData(self.fldNum["empNo"],  Qt.Horizontal,"工号")
        ##      self.qryModel.setHeaderData(self.fldNum["Name"],   Qt.Horizontal,"姓名")
        ##      self.qryModel.setHeaderData(self.fldNum["Gender"], Qt.Horizontal,"性别")
        ##      self.qryModel.setHeaderData(self.fldNum["Birthday"],  Qt.Horizontal,"出生日期")
        ##      self.qryModel.setHeaderData(self.fldNum["Province"],  Qt.Horizontal,"省份")
        ##      self.qryModel.setHeaderData(self.fldNum["Department"],Qt.Horizontal,"部门")
        ##      self.qryModel.setHeaderData(self.fldNum["Salary"], Qt.Horizontal,"工资")

        self.selModel = QItemSelectionModel(self.qryModel)  #关联选择模型
        ##选择行变化时
        self.selModel.currentRowChanged.connect(self.do_currentRowChanged)

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

        self.ui.actOpenDB.setEnabled(False)

        self.ui.actRecInsert.setEnabled(True)
        self.ui.actRecDelete.setEnabled(True)
        self.ui.actRecEdit.setEnabled(True)
        self.ui.actScan.setEnabled(True)
        self.ui.actTestSQL.setEnabled(True)

    def __updateRecord(self, recNo):  ##更新一条记录
        curRec = self.qryModel.record(recNo)  #获取当前记录
        empNo = curRec.value("EmpNo")  #获取EmpNo

        query = QSqlQuery(self.DB)  #查询出当前记录的所有字段
        query.prepare("SELECT * FROM employee WHERE EmpNo = :ID")
        query.bindValue(":ID", empNo)
        query.exec()  #
        query.first()

        if (not query.isValid()):  #是否为有效记录
            return

        curRec = query.record()  #获取当前记录的数据,QSqlRecord类型
        dlgData = QmyDialogData(self)  #创建对话框

        dlgData.setUpdateRecord(curRec)  #调用对话框函数更新数据和界面
        ret = dlgData.exec()  # 以模态方式显示对话框
        if (ret != QDialog.Accepted):
            return

        recData = dlgData.getRecordData()  #获得对话框返回的记录
        query.prepare('''UPDATE employee SET Name=:Name, Gender=:Gender,
                    Birthday=:Birthday, Province=:Province,
                    Department=:Department, Salary=:Salary,
                    Memo=:Memo, Photo=:Photo WHERE EmpNo = :ID''')

        query.bindValue(":Name", recData.value("Name"))
        query.bindValue(":Gender", recData.value("Gender"))
        query.bindValue(":Birthday", recData.value("Birthday"))
        query.bindValue(":Province", recData.value("Province"))
        query.bindValue(":Department", recData.value("Department"))
        query.bindValue(":Salary", recData.value("Salary"))
        query.bindValue(":Memo", recData.value("Memo"))
        query.bindValue(":Photo", recData.value("Photo"))

        query.bindValue(":ID", empNo)

        ##      if (not query.exec_()):
        if (not query.exec()):  #PyQt 5.11.2以前应该使用exec_()函数
            QMessageBox.critical(self, "错误",
                                 "记录更新错误\n" + query.lastError().text())
        else:
            self.qryModel.query().exec()  #数据模型重新查询数据,更新tableView显示

##  ==========由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_actRecInsert_triggered(self):
        query = QSqlQuery(self.DB)
        query.exec("select * from employee where EmpNo =-1")  #实际不查询出记录,只查询字段信息

        curRec = query.record()  #获取当前记录,实际为空记录,但有字段信息
        curRec.setValue("EmpNo", self.qryModel.rowCount() + 3000)

        dlgData = QmyDialogData(self)
        dlgData.setInsertRecord(curRec)  #插入记录

        ret = dlgData.exec()  #以模态方式显示对话框
        if (ret != QDialog.Accepted):
            return

        recData = dlgData.getRecordData()

        query.prepare('''INSERT INTO employee (EmpNo,Name,Gender,Birthday,
                    Province,Department,Salary,Memo,Photo) 
                    VALUES(:EmpNo,:Name, :Gender,:Birthday,:Province,
                    :Department,:Salary,:Memo,:Photo)''')

        query.bindValue(":EmpNo", recData.value("EmpNo"))
        query.bindValue(":Name", recData.value("Name"))
        query.bindValue(":Gender", recData.value("Gender"))
        query.bindValue(":Birthday", recData.value("Birthday"))

        query.bindValue(":Province", recData.value("Province"))
        query.bindValue(":Department", recData.value("Department"))

        query.bindValue(":Salary", recData.value("Salary"))
        query.bindValue(":Memo", recData.value("Memo"))
        query.bindValue(":Photo", recData.value("Photo"))

        res = query.exec()  #执行SQL语句
        if (res == False):
            QMessageBox.critical(self, "错误",
                                 "插入记录错误\n" + query.lastError().text())
        else:  #插入,删除记录后需要重新设置SQL语句查询
            sqlStr = self.qryModel.query().executedQuery()  #执行过的SELECT语句
            self.qryModel.setQuery(sqlStr)  #reset 重新查询数据

    @pyqtSlot()  ##删除记录
    def on_actRecDelete_triggered(self):
        curRecNo = self.selModel.currentIndex().row()
        curRec = self.qryModel.record(curRecNo)  #获取当前记录
        if (curRec.isEmpty()):  #当前为空记录
            return

        empNo = curRec.value("EmpNo")  #获取员工编号
        query = QSqlQuery(self.DB)
        query.prepare("DELETE  FROM employee WHERE EmpNo = :ID")
        query.bindValue(":ID", empNo)

        if (query.exec() == False):
            QMessageBox.critical(self, "错误",
                                 "删除记录出现错误\n" + query.lastError().text())
        else:  #插入,删除记录后需要重新设置SQL语句查询
            sqlStr = self.qryModel.query().executedQuery()  #执行过的SELECT语句
            self.qryModel.setQuery(sqlStr)  #reset 重新查询数据

    @pyqtSlot()  ##编辑记录
    def on_actRecEdit_triggered(self):
        curRecNo = self.selModel.currentIndex().row()
        self.__updateRecord(curRecNo)

    ##   @pyqtSlot()  ##双击编辑记录
    def on_tableView_doubleClicked(self, index):
        curRecNo = index.row()
        self.__updateRecord(curRecNo)

    @pyqtSlot()  ##遍历记录,涨工资
    def on_actScan_triggered(self):
        qryEmpList = QSqlQuery(self.DB)  #员工工资信息列表
        qryEmpList.exec("SELECT empNo,Salary FROM employee ORDER BY empNo")

        qryUpdate = QSqlQuery(self.DB)  #临时 QSqlQuery
        qryUpdate.prepare(
            '''UPDATE employee SET Salary=:Salary WHERE EmpNo = :ID''')

        qryEmpList.first()
        while (qryEmpList.isValid()):  #当前记录有效
            empID = qryEmpList.value("empNo")  #获取empNo
            salary = qryEmpList.value("Salary")  #获取Salary
            salary = salary + 500  #涨工资

            qryUpdate.bindValue(":ID", empID)
            qryUpdate.bindValue(":Salary", salary)  #设置SQL语句参数
            qryUpdate.exec()  #执行update语句

            if not qryEmpList.next():  #移动到下一条记录,并判断是否到末尾了
                break

        self.qryModel.query().exec()  #数据模型重新查询数据,更新tableView的显示
        QMessageBox.information(self, "提示", "涨工资计算完毕")

    @pyqtSlot()  ##SQL语句测试
    def on_actTestSQL_triggered(self):
        query = QSqlQuery(self.DB)

        ##   # SQL语句测试1,  exec_() 和exec()都可以直接执行不带参数的SQL语句
        ##      query.exec('''UPDATE employee SET Salary=3000 where Gender="女" ''')
        ##      query.exec_('''UPDATE employee SET Salary=4500 where Gender="女" ''')

        # SQL语句测试2,执行带参数的SQL语句,只能用 exec_(),不能用exec()
        ##      query.prepare('''UPDATE employee SET Salary=9000 where Gender=:Gender ''')
        ##      query.bindValue(":Gender","男")
        ##      query.exec()

        query.exec('''UPDATE employee SET Salary=500+Salary ''')
        ##      query.bindValue(":Gender","男")
        ##      query.exec()

        ##      query.prepare("UPDATE employee SET Department=?, Salary=?  where Name=?")
        ##      query.bindValue(0, "技术部")
        ##      query.bindValue(1, 5500)
        ##      query.bindValue(2, "张三")
        ##      query.exec_()  #只能用exec_(),而不能用exec()函数

        ##      self.qryModel.query().exec()  #不增减记录时更新显示

        ##    增减记录后的更新显示
        sqlStr = self.qryModel.query().executedQuery()  #执行过的SELECT语句
        self.qryModel.setQuery(sqlStr)  #reset 重新查询数据

        print("SQL OK")

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

    def do_currentRowChanged(self, current, previous):  ##行切换时触发
        if (current.isValid() == False):
            return
        curRec = self.qryModel.record(current.row())  #获取当前记录,QSqlRecord类型
        empNo = curRec.value("EmpNo")  #不需要加 toInt()函数
        self.ui.statusBar.showMessage("当前记录:工号=%d" % empNo)
コード例 #12
0
ファイル: 0704.py プロジェクト: falomsc/pyqtStudy
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())
コード例 #13
0
class Attributes():
    def __init__(self, treeManipulate, tabnumber):
        self.treeManipulate = treeManipulate
        self.tabnumber = tabnumber
        self.tvattributesview = None
        self.lenameattributes = None
        self.levalueattributes = None
        self.battributesinsert = None
        self.battributesdelete = None
        self.battributeshelp = None
        self.setUiInit()
        self.helptext = self.treeManipulate.main.attribhelp
        #build empty model for data and the selection
        self.attribmodel = AttribStandardItemModel(self.tvattributesview)
        self.attribmodel.setHorizontalHeaderLabels(["Name", "Value", "var/fun", "comment"])
        self.attribselectionmodel = QItemSelectionModel(self.attribmodel)
        #set model to tableview
        self.tvattributesview.setModel(self.attribmodel)
        self.tvattributesview.setSelectionModel(self.attribselectionmodel)
        #signals
        self.battributesinsert.clicked.connect(self.addAttrib)
        self.battributesdelete.clicked.connect(self.deleteAttrib)
        self.battributeshelp.clicked.connect(self.help)
        self.attribmodel.itemChanged.connect(self.changeAttrib)
        #resize
        self.resz()
        #variables
        self.changeOnce = True  #prevent the changeAttrib() function from being executed twice (the second time by the model change)

    def setUiInit(self):
        if self.tabnumber == 0:
            self.tvattributesview = self.treeManipulate.main.attributefieldst1[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst1[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst1[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst1[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst1[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst1[5]
        if self.tabnumber == 1:
            self.tvattributesview = self.treeManipulate.main.attributefieldst2[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst2[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst2[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst2[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst2[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst2[5]
        if self.tabnumber == 2:
            self.tvattributesview = self.treeManipulate.main.attributefieldst3[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst3[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst3[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst3[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst3[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst3[5]
        if self.tabnumber == 3:
            self.tvattributesview = self.treeManipulate.main.attributefieldst4[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst4[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst4[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst4[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst4[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst4[5]
        if self.tabnumber == 4:
            self.tvattributesview = self.treeManipulate.main.attributefieldst5[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst5[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst5[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst5[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst5[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst5[5]
        if self.tabnumber == 5:
            self.tvattributesview = self.treeManipulate.main.attributefieldst6[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst6[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst6[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst6[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst6[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst6[5]
        if self.tabnumber == 6:
            self.tvattributesview = self.treeManipulate.main.attributefieldst7[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst7[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst7[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst7[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst7[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst7[5]
        if self.tabnumber == 7:
            self.tvattributesview = self.treeManipulate.main.attributefieldst8[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst8[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst8[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst8[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst8[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst8[5]
        if self.tabnumber == 8:
            self.tvattributesview = self.treeManipulate.main.attributefieldst9[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst9[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst9[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst9[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst9[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst9[5]
        if self.tabnumber == 9:
            self.tvattributesview = self.treeManipulate.main.attributefieldst10[0]
            self.lenameattributes = self.treeManipulate.main.attributefieldst10[1]
            self.levalueattributes = self.treeManipulate.main.attributefieldst10[2]
            self.battributesinsert = self.treeManipulate.main.attributefieldst10[3]
            self.battributesdelete = self.treeManipulate.main.attributefieldst10[4]
            self.battributeshelp = self.treeManipulate.main.attributefieldst10[5]

    def setSesVarsFunsInAttributes(self):
        if self.tabnumber == 0:
            self.sesVariablest1 = self.treeManipulate.main.modellist[0][1]
            self.sesFunctionst1 = self.treeManipulate.main.modellist[0][2]
            self.sesVariablest1.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst1.sesfunChangedSignal.connect(self.validate)
        if self.tabnumber == 1:
            self.sesVariablest2 = self.treeManipulate.main.modellist[1][1]
            self.sesFunctionst2 = self.treeManipulate.main.modellist[1][2]
            self.sesVariablest2.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst2.sesfunChangedSignal.connect(self.validate)
        if self.tabnumber == 2:
            self.sesVariablest3 = self.treeManipulate.main.modellist[2][1]
            self.sesFunctionst3 = self.treeManipulate.main.modellist[2][2]
            self.sesVariablest3.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst3.sesfunChangedSignal.connect(self.validate)
        if self.tabnumber == 3:
            self.sesVariablest4 = self.treeManipulate.main.modellist[3][1]
            self.sesFunctionst4 = self.treeManipulate.main.modellist[3][2]
            self.sesVariablest4.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst4.sesfunChangedSignal.connect(self.validate)
        if self.tabnumber == 4:
            self.sesVariablest5 = self.treeManipulate.main.modellist[4][1]
            self.sesFunctionst5 = self.treeManipulate.main.modellist[4][2]
            self.sesVariablest5.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst5.sesfunChangedSignal.connect(self.validate)
        if self.tabnumber == 5:
            self.sesVariablest6 = self.treeManipulate.main.modellist[5][1]
            self.sesFunctionst6 = self.treeManipulate.main.modellist[5][2]
            self.sesVariablest6.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst6.sesfunChangedSignal.connect(self.validate)
        if self.tabnumber == 6:
            self.sesVariablest7 = self.treeManipulate.main.modellist[6][1]
            self.sesFunctionst7 = self.treeManipulate.main.modellist[6][2]
            self.sesVariablest7.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst7.sesfunChangedSignal.connect(self.validate)
        if self.tabnumber == 7:
            self.sesVariablest8 = self.treeManipulate.main.modellist[7][1]
            self.sesFunctionst8 = self.treeManipulate.main.modellist[7][2]
            self.sesVariablest8.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst8.sesfunChangedSignal.connect(self.validate)
        if self.tabnumber == 8:
            self.sesVariablest9 = self.treeManipulate.main.modellist[8][1]
            self.sesFunctionst9 = self.treeManipulate.main.modellist[8][2]
            self.sesVariablest9.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst9.sesfunChangedSignal.connect(self.validate)
        if self.tabnumber == 9:
            self.sesVariablest10 = self.treeManipulate.main.modellist[9][1]
            self.sesFunctionst10 = self.treeManipulate.main.modellist[9][2]
            self.sesVariablest10.sesvarChangedSignal.connect(self.validate)
            self.sesFunctionst10.sesfunChangedSignal.connect(self.validate)

    """read -> called from tree manipulate"""
    def readAttribList(self, lst):
        for row in range(len(lst)):
            itemnme = QStandardItem(lst[row][0])
            itemval = QStandardItem(lst[row][1])
            itemvarfun = QStandardItem(lst[row][2])
            itemcomment = QStandardItem(lst[row][3])
            self.attribmodel.appendRow([itemnme, itemval, itemvarfun, itemcomment])
        self.resz()
        self.validate()

    """write -> the entries of the list in the current node"""
    def writeAttribList(self):
        if not self.treeManipulate.isRestoringTree:  # only, if it is not called due to a selection change during reading the tree from save
            attribList = []
            # get current selected node
            nodeuid = self.treeManipulate.treeModel.getNode(self.treeManipulate.treeSelectionModel.currentIndex()).getUid()
            for row in range(self.attribmodel.rowCount()):
                indnme = self.attribmodel.item(row, 0)
                indval = self.attribmodel.item(row, 1)
                indvarfun = self.attribmodel.item(row, 2)
                indcomment = self.attribmodel.item(row, 3)
                var = [indnme.data(QtCore.Qt.DisplayRole), indval.data(QtCore.Qt.DisplayRole), indvarfun.data(QtCore.Qt.DisplayRole), indcomment.data(QtCore.Qt.DisplayRole)]
                attribList.append(var)
            self.treeManipulate.treeModel.insertNodeSpecProp(self.treeManipulate.treeSelectionModel.currentIndex(), attribList, "attriblist", nodeuid)  # write into the node

    """resize"""
    """
    def resz(self):
        self.tvattributesview.setColumnWidth(0, self.tvattributesview.width()*0.4)
        header = self.tvattributesview.horizontalHeader()
        header.setStretchLastSection(True)
    """
    def resz(self):
        i = 0
        while i < 2:
            self.tvattributesview.resizeColumnToContents(i)
            i += 1
        header = self.tvattributesview.horizontalHeader()
        header.setStretchLastSection(True)

    """add an attribute to the model"""
    def addAttrib(self):
        name = self.lenameattributes.text()
        value = self.levalueattributes.text()
        cname, cnameb, deleten = self.checkReturnName(name, False)
        cvalue, cvalueb, deletev, varfun = self.checkReturnValue(value, False)
        if cnameb and cvalueb:
            itemnm = QStandardItem(cname)
            itemval = QStandardItem(str(cvalue))
            itemvarfun = QStandardItem(varfun)
            itemcomment = QStandardItem("")
            self.attribmodel.appendRow([itemnm, itemval, itemvarfun, itemcomment])
            self.lenameattributes.setText("")
            self.levalueattributes.setText("")
        self.writeAttribList()
        self.resz()
        self.validate()

    """model changed via double click"""
    def changeAttrib(self):
        if self.changeOnce:
            self.changeOnce = False
            index = self.tvattributesview.currentIndex()
            #cloumn 0 -> name
            if index.column() == 0:
                namedic = self.attribmodel.itemData(index)
                name = namedic[0]
                cname, cnameb, deleten = self.checkReturnName(name, True)
                if cnameb:  # set data
                    dict = {0: cname}
                    self.attribmodel.setItemData(index, dict)
                if deleten:  # remove row
                    self.deleteAttrib(self.attribselectionmodel.currentIndex().row(), True)
            #column 1 -> value
            elif index.column() == 1:
                valuedic = self.attribmodel.itemData(index)
                value = valuedic[0]
                cvalue, cvalueb, deletev, varfun = self.checkReturnValue(value, True)
                if cvalueb:  # set data
                    dict = {0: str(cvalue)}
                    self.attribmodel.setItemData(index, dict)
                    #set the value for the varfun column
                    index2 = self.attribmodel.index(index.row(), 2)
                    dict2 = {0: varfun}
                    self.attribmodel.setItemData(index2, dict2)
                if deletev:  # remove row
                    self.deleteAttrib(self.attribselectionmodel.currentIndex().row(), True)
            self.writeAttribList()
            self.resz()
            self.validate()
            self.changeOnce = True

    """check the name"""
    def checkReturnName(self, name, edited):
        if name != "" and not name == "''" and not name == '""' and not name == '\n':
            name = name.strip() #remove whitespaces before and after

            # check for two words as name
            namesplit = name.split(" ")
            if not edited and len(namesplit) > 1:
                QMessageBox.information(None, "Inserting not possible", "The variable name contains spaces. Please remove them.", QtWidgets.QMessageBox.Ok)
                return("", False, False)
            elif edited and len(namesplit) > 1:
                QMessageBox.information(None, "Changing not possible", "The variable name contains spaces. The variable is deleted.", QtWidgets.QMessageBox.Ok)
                return("", False, True)

            # check for duplicates of variable name
            if not edited and len(self.attribmodel.findItems(name)) != 0:
                QMessageBox.information(None, "Inserting not possible", "The variable name already exists. Please enter another variable name.", QtWidgets.QMessageBox.Ok)
                return ("", False, False)
            elif edited and len(self.attribmodel.findItems(self.attribmodel.item(self.attribselectionmodel.currentIndex().row(), 0).data(QtCore.Qt.DisplayRole))) > 1:
                QMessageBox.information(None, "Changing not possible", "The variable name already exists. The variable is deleted.", QtWidgets.QMessageBox.Ok)
                return ("", False, True)

            # check that the variable name is no Python keyword
            if not edited and keyword.iskeyword(name):
                QMessageBox.information(None, "Inserting not possible", "The variable name denotes a Python keyword. Please enter another variable name.", QtWidgets.QMessageBox.Ok)
                return ("", False, False)
            elif edited and keyword.iskeyword(name):
                QMessageBox.information(None, "Changing not possible", "The variable name denotes a Python keyword. The variable is deleted.", QtWidgets.QMessageBox.Ok)
                return ("", False, True)

            # check that the variable name is not 'PARENT', 'CHILDREN' or 'NUMREP'
            if not edited and (name == 'PARENT' or name == 'CHILDREN' or name == 'NUMREP'):
                QMessageBox.information(None, "Inserting not possible", "The variable name is 'PARENT', 'CHILDREN' or 'NUMREP'. Please enter another variable name.", QtWidgets.QMessageBox.Ok)
                return ("", False, False)
            elif edited and (name == 'PARENT' or name == 'CHILDREN' or name == 'NUMREP'):
                QMessageBox.information(None, "Changing not possible", "The variable name is 'PARENT', 'CHILDREN' or 'NUMREP'. The variable is deleted.", QtWidgets.QMessageBox.Ok)
                return ("", False, True)

            #check if the variable name is in Python syntax
            attribregex = re.compile('^([a-z]|[A-Z])(\w+)?$')
            attribregexcorrect = attribregex.match(name)
            if not edited and attribregexcorrect is None:
                QMessageBox.information(None, "Inserting not possible", "Please enter correct Python syntax for the variable name.", QtWidgets.QMessageBox.Ok)
                return ("", False, False)
            elif edited and attribregexcorrect is None:
                QMessageBox.information(None, "Changing not possible", "Please enter correct Python syntax for the variable name. The variable is deleted.", QtWidgets.QMessageBox.Ok)
                return ("", False, True)

            return (name, True, False)

        else:   #empty name
            if not edited:
                QMessageBox.information(None, "The variable name is empty", "The variable name is empty. The variable can not be inserted.", QtWidgets.QMessageBox.Ok)
                return ("", False, False)
            else:
                QMessageBox.information(None, "The variable name is empty", "The variable name is empty. The variable is deleted.", QtWidgets.QMessageBox.Ok)
                return ("", False, True)

    """check the value"""
    def checkReturnValue(self, value, edited):
        if value != "" and not value == "''" and not value == '""' and not value == '\n':
            value = value.strip()  # remove whitespaces before and after
            isString = False
            if (ord(value[0]) == 39 and ord(value[-1]) == 39) or (ord(value[0]) == 34 and ord(value[-1]) == 34):    #check ascii code: ord() for getting the number and chr() for getting the character again, unichr() for getting the unicode character
                isString = True
            try:
                if not isString:    #a string shall stay a string, try to interprete if not entered as string
                    value = ast.literal_eval(value)
                return (value, True, False, "")
            except:
                #the value is no Python value so it could be the name of an SES variable or function
                #check if it can be the syntax of an SES variable or function
                attribregex = re.compile('^([a-z]|[A-Z])(\w+)?(\(([\"\']?\w+[\"\']?)?(,\s*?[\"\']?\w+[\"\']?)*\))?$')
                attribregexcorrect = attribregex.match(value)
                if attribregexcorrect is not None and not isString:
                    return (value, True, False, "x")
                QMessageBox.information(None, "Inserting not possible",
                                        "Please enter a variable using Python syntax or the possible name of an SES variable or function. SES variables and functions may not be part of a list or other Python datatype.\n"
                                        "If edited the variable will be deleted.", QtWidgets.QMessageBox.Ok)
                if not edited:
                    return ("", False, False, "")
                else:
                    return ("", False, True, "")

        else:  # empty value
            if not edited:
                QMessageBox.information(None, "The variable value is empty",
                                        "The variable value is empty. The variable can not be inserted.",
                                        QtWidgets.QMessageBox.Ok)
                return ("", False, False, "")
            else:
                QMessageBox.information(None, "The variable value is empty",
                                        "The variable value is empty. The variable is deleted.", QtWidgets.QMessageBox.Ok)
                return ("", False, True, "")

    """delete"""
    def deleteAttrib(self, rw=-1, rowsdelete=False):
        selectedrows = self.attribselectionmodel.selectedRows()
        if len(selectedrows) == 0 and rw == -1:
            QMessageBox.information(None, "Deleting not possible", "Please select at least one attribute to delete.", QtWidgets.QMessageBox.Ok)
        elif len(selectedrows) > 0 and not rowsdelete:
            deleteListRows = []
            for rowind in selectedrows:
                deleteListRows.append(rowind.row())
            deleteListRows.sort(reverse=True)
            for row in deleteListRows:
                self.attribmodel.removeRow(row, QtCore.QModelIndex())
        elif rw != -1 and rowsdelete:
            self.attribmodel.removeRow(rw, QtCore.QModelIndex())
        self.writeAttribList()
        self.resz()

    """color the value field if an SES variable or SES function can be interpreted"""
    def validate(self, sesvarl="", sesfunl="", nd=None):

        #sub function
        def validateAttr(nd, sviat, sesfunl):

            attrlist = nd.attributes

            #there can be several attributes, so we have to put the results of this sub function into lists
            attrlinel = []
            isVarFunl = []
            varFoundl = []
            funFoundl = []
            funVarFoundl = []
            resl = []
            for row in attrlist:
                data = row[1]
                datavarfun = row[2]

                attrline = row
                isVarFun = False
                varFound = False
                funFound = False
                funVarFound = True
                res = ""
                #check if it is an SES variable or function
                if datavarfun == "":
                    #if type(data) is str:  #it can only be a string
                    res = data
                elif datavarfun == "x":
                    isVarFun = True

                    # evaluate the SES variable
                    try:
                        res = eval(data, globals(), sviat.__dict__)
                        varFound = True
                    except:
                        pass

                    # check if the expression is an SES function
                    if isinstance(data, str) and "(" in data and ")" in data:
                        funname = data.split("(")
                        funname[1] = funname[1][0:-1]
                        vars = funname[1].split(",")
                        if vars[0] == '':
                            del vars[0]
                        for v in range(len(vars)):
                            vars[v] = vars[v].strip()
                        # check if the parameters are SES variables and get the values
                        varvalues = []
                        for v in vars:
                            try:
                                vv = ast.literal_eval(v)
                                varvalues.append(vv)
                            except:
                                # the value is no Python value so it could be the name of an SES variable or function
                                # check if the expression is an SES variable
                                try:
                                    ret = eval(v, globals(), sviat.__dict__)
                                    # replace the name with the value
                                    varvalues.append(ret)
                                except:
                                    varvalues.append("")

                        # now get the function from the sesFunctions and try to find a match with the entry
                        for sesfunvalue in sesfunl:
                            if sesfunvalue[0] == funname[0]:
                                # get the vars of the found function match since the parameters in the function definition do not have to match the SES variable names
                                funvarsfound = re.findall('def\s+' + re.escape(funname[0]) + '\(.*\)', sesfunvalue[1])
                                funvarsfound[0] = funvarsfound[0].replace("def", "")
                                funvarsfound[0] = funvarsfound[0].replace(funname[0] + "(", "")
                                funvarsfound[0] = funvarsfound[0].replace(")", "")
                                funvarsfound[0] = funvarsfound[0].strip()
                                vars2 = funvarsfound[0].split(",")
                                if vars2[0] == '':
                                    del vars2[0]
                                # remove existing default values
                                for i in range(len(vars2)):
                                    if i < len(vars):
                                        vars2[i] = vars2[i].split("=")[0]
                                # make variables to default variables by position
                                for i in range(len(vars2)):
                                    if i < len(vars):
                                        if varvalues[i] != "":
                                            if isinstance(varvalues[i], str):
                                                vars2[i] = vars2[i] + " = '" + varvalues[i] + "'"
                                            else:
                                                vars2[i] = vars2[i] + " = " + str(varvalues[i])
                                        else:
                                            funVarFound = False

                                # build a string from the variables to pass
                                for i in range(len(vars2)):
                                    vars2[i] = str(vars2[i])
                                varstring = ', '.join(vars2)

                                # replace parameters in the function with the varstring
                                sesfunvalue[1] = re.sub('def ' + re.escape(sesfunvalue[0]) + '\(.*\)', 'def ' + re.escape(sesfunvalue[0]) + '(' + varstring + ')', sesfunvalue[1])

                                # try to execute the function
                                try:
                                    exec(sesfunvalue[1])
                                    self.ret = None
                                    execute = "self.ret = " + sesfunvalue[0] + "()"
                                    if sesfunvalue[0] in locals():
                                        try:
                                            exec(execute)
                                            funFound = True
                                            res = self.ret
                                        except:
                                            pass
                                except:
                                    pass

                #always return a string
                res = str(res)

                attrlinel.append(attrline)
                isVarFunl.append(isVarFun)
                varFoundl.append(varFound)
                funFoundl.append(funFound)
                funVarFoundl.append(funVarFound)
                resl.append(res)

            return attrlinel, isVarFunl, varFoundl, funFoundl, funVarFoundl, resl

        #here the validate function begins

        # own class for SES variables
        class sesvarsinattr:
            pass

        # create an instance of the SES variables class
        sviat = sesvarsinattr

        #was the process started for coloring the lines or for pruning?
        if sesvarl == "" and sesfunl == "" and nd == None:  # the validate process was started from the editor for coloring the lines
            # fill the instance of the sesvar class
            for sesvarvalue in self.treeManipulate.main.modellist[self.treeManipulate.main.activeTab][1].outputSesVarList():
                try:
                    sesvarvalue[1] = ast.literal_eval(sesvarvalue[1])  # interprete the type of the value
                except:
                    pass  # do nothing, it stays a string
                setattr(sviat, sesvarvalue[0], sesvarvalue[1])

            #get the SES functions
            sesfunl = self.treeManipulate.main.modellist[self.treeManipulate.main.activeTab][2].outputSesFunList()

            #go through all nodes
            indices = self.treeManipulate.listAllIndices(self.treeManipulate.treeSelectionModel.currentIndex())
            for ind in indices:
                #get the node
                nd = self.treeManipulate.treeModel.getNode(ind[0])
                #only continue if the node has attributes
                if nd.typeInfo() == "Entity Node":

                    attrlinel, isVarFunl, varFoundl, funFoundl, funVarFoundl, resl = validateAttr(nd, sviat, sesfunl)

                    #update the model
                    self.updateModel(attrlinel, isVarFunl, varFoundl, funFoundl, funVarFoundl)

        else:   # the validate process was started for pruning
            # fill the instance of the sesvar class
            for sesvarvalue in sesvarl:
                try:
                    sesvarvalue[1] = ast.literal_eval(sesvarvalue[1])  # interprete the type of the value
                except:
                    pass  # do nothing, it stays a string
                setattr(sviat, sesvarvalue[0], sesvarvalue[1])

            #the SES functions are given in the pass list

            #only continue if the node has attributes
            if nd.typeInfo() == "Entity Node":

                attrlinel, isVarFunl, varFoundl, funFoundl, funVarFoundl, resl = validateAttr(nd, sviat, sesfunl)

                #return the evaluated results
                return resl



    def updateModel(self, attrlinel, isVarFunl, varFoundl, funFoundl, funVarFoundl):    #the information how to color the rows is not in the node (no True/False), so we have to pass the lists

        for row in range(self.attribmodel.rowCount()):
            index0 = self.attribmodel.index(row, 0)
            index1 = self.attribmodel.index(row, 1)
            index2 = self.attribmodel.index(row, 2)
            index3 = self.attribmodel.index(row, 3)

            #if the attribute the parameters were calculated for fits the attribute of the line
            attrname = index0.data(QtCore.Qt.DisplayRole)
            attrvalue = index1.data(QtCore.Qt.DisplayRole)
            attrvarfun = index2.data(QtCore.Qt.DisplayRole)
            attrcomment = index3.data(QtCore.Qt.DisplayRole)
            for i in range(len(attrlinel)):
                if attrlinel[i][0] == attrname and attrlinel[i][1] == attrvalue and attrlinel[i][2] == attrvarfun and attrlinel[i][3] == attrcomment:
                    if isVarFunl[i]:
                        #color the rows according to the found result
                        if varFoundl[i] or (funFoundl[i] and funVarFoundl[i]):
                            color1 = QtGui.QColor(195, 255, 195, 255)
                        else:
                            color1 = QtGui.QColor(255, 195, 195, 255)
                    else:
                        #get the alternating colors
                        if row % 2 == 0:
                            color1 = QtGui.QColor(QtCore.Qt.white)
                        else:
                            color1 = QtGui.QColor(239, 240, 241, 255)
                    self.attribmodel.setData(index1, color1, QtCore.Qt.BackgroundColorRole)
                    self.attribmodel.setData(index2, color1, QtCore.Qt.BackgroundColorRole)

    """empty the model"""
    def emptyAttribModel(self):
        self.attribmodel.clear()
        self.attribmodel.setHorizontalHeaderLabels(["Name", "Value", "var/fun", "comment"])

    """help"""
    def help(self):
        msgBox = QMessageBox(self.treeManipulate.main)
        msgBox.setIcon(QMessageBox.Information)
        msgBox.setWindowTitle("attributes: Help")
        msgBox.setText(self.helptext[0])
        msgBox.setDetailedText(self.helptext[1])
        msgBox.setWindowModality(Qt.NonModal)
        msgBox.setStandardButtons(QMessageBox.Ok)
        msgBox.setDefaultButton(QMessageBox.Ok)
        msgBox.setEscapeButton(QMessageBox.Ok)
        msgBox.show()

    #validate function where only the existence of the SES function and parameters is checked but not if it is interpretable
    """
    def validate(self):
        self.changeOnce = False
        for row in range(self.attribmodel.rowCount()):
            data = self.attribmodel.item(row, 1).data(QtCore.Qt.DisplayRole)
            datavarfun = self.attribmodel.item(row, 2).data(QtCore.Qt.DisplayRole)
            index1 = self.attribmodel.index(row, 1)
            index2 = self.attribmodel.index(row, 2)
            #if it is an SES variable or function
            if datavarfun == "x":
                varFound = False
                funFound = False
                parameterFound = []

                for sesvarvalue in self.treeManipulate.main.modellist[self.treeManipulate.main.activeTab][1].outputSesVarList():
                    if data == sesvarvalue[0]:
                        varFound = True

                attribregex = re.compile('^([a-z]|[A-Z])(\w+)?(\(([\"\']?\w+[\"\']?)?(,\s*?[\"\']?\w+[\"\']?)*\))$')
                attribregexfun = attribregex.match(data)
                if attribregexfun is not None:
                    funsplit = data.split("(")
                    funsplit[1] = funsplit[1][0:len(funsplit[1])-1]
                    for sesfunvalue in self.treeManipulate.main.modellist[self.treeManipulate.main.activeTab][2].outputSesFunList():
                        if funsplit[0] == sesfunvalue[0]:
                            funFound = True
                            #now interprete the parameters
                            parameters = funsplit[1].split(",")
                            for p in range(len(parameters)):
                                parameters[p] = parameters[p].strip()
                                if not parameters[p] == "":
                                    try:
                                        ast.literal_eval(parameters[p])
                                    except: #the parameter is maybe an SES variable
                                        found = False
                                        for sesvarvalue in self.treeManipulate.main.modellist[self.treeManipulate.main.activeTab][1].outputSesVarList():
                                            if parameters[p] == sesvarvalue[0]:
                                                found = True
                                        if found:
                                            parameterFound.append(True)
                                        else:
                                            parameterFound.append(False)

                #color the rows according to the found result
                parameterFoundRes = all(parameterFound)

                if varFound or (funFound and parameterFoundRes):
                    color1 = QtGui.QColor(195, 255, 195, 255)
                else:
                    color1 = QtGui.QColor(255, 195, 195, 255)
            else:
                #get the alternating colors
                if row % 2 == 0:
                    color1 = QtGui.QColor(QtCore.Qt.white)
                else:
                    color1 = QtGui.QColor(239, 240, 241, 255)
            self.attribmodel.setData(index1, color1, QtCore.Qt.BackgroundColorRole)
            self.attribmodel.setData(index2, color1, QtCore.Qt.BackgroundColorRole)
        self.changeOnce = True
    """

    #functions when the syntax var() and fun() is used------------------------------------------------------------------

    """check the value -> old function: with var as keyword for SES Variable and fun as keyword for SES function"""
    """
    def checkReturnValue(self, value, edited):
        def checkQuotes(val):  # it must be an even number of quotes and one type of quotes may only be twice in the string since it defines the string
            quote = val.count("'")
            doublequote = val.count('"')
            if quote % 2 == 1 or doublequote % 2 == 1:  # if one number of quotetype is odd -> return False
                return False
            elif quote == 0 or doublequote == 0:  # one number of quotetype must be 0 (since the string delimiters are not counted)
                return True
            else:
                return False

        if value != "":
            value = value.strip()  # remove whitespaces before and after
            try:
                value = ast.literal_eval(value)

                sesvarfunkeyexists = False
                sesvarkeyfound = None
                sesfunkeyfound = None
                sesvarregex = re.compile('^var\([\"\']([a-z]|[A-Z])(\w+)?[\"\']\)$')  # regular expression: var("abc") or var('abc'), not found: var("abc def") since SES variable names may not contain whitespaces
                sesfunregex = re.compile('^fun\([\"\']([a-z]|[A-Z])(\w+)?[\"\'](,\s?((\d+(\.\d+)?)|([\"\']var\([\"\']([a-z]|[A-Z])(\w+)?[\"\']\)[\"\'])))*\)$')  # regular expression: fun("abc"[...]) or fun('abc'[...]) with [...] optional containing: , 4 or , "var("a")" with whitespace optional between , and text
                checkquotes = False

                if isinstance(value, str) and ("var(" in value or "fun(" in value):
                    sesvarfunkeyexists = True
                    sesvarkeyfound = sesvarregex.match(value)
                    sesfunkeyfound = sesfunregex.match(value)
                    checkquotes = checkQuotes(value)
                # if isinstance(value, list) and (("var(" in v for v in value) or ("fun(" in v for v in value)):   #does not perfectly function
                if isinstance(value, list):
                    for v in value:
                        if isinstance(v, str) and ("var(" in v or "fun(" in v):
                            sesvarfunkeyexists = True
                            sesvarkeyfound = sesvarregex.match(v)
                            sesfunkeyfound = sesfunregex.match(v)
                            checkquotes = checkQuotes(v)
                # if isinstance(value, tuple) and (("var(" in v for v in value) or ("fun(" in v for v in value)):  #does not perfectly function
                if isinstance(value, tuple):
                    for v in value:
                        if isinstance(v, str) and ("var(" in v or "fun(" in v):
                            sesvarfunkeyexists = True
                            sesvarkeyfound = sesvarregex.match(v)
                            sesfunkeyfound = sesfunregex.match(v)
                            checkquotes = checkQuotes(v)
                # if isinstance(value, dict) and (("var(" in v for v in list(value.values())) or ("fun(" in v for v in list(value.values()))): #does not perfectly function
                if isinstance(value, dict):
                    for v in list(value.values()):
                        if isinstance(v, str) and ("var(" in v or "fun(" in v):
                            sesvarfunkeyexists = True
                            sesvarkeyfound = sesvarregex.match(v)
                            sesfunkeyfound = sesfunregex.match(v)
                            checkquotes = checkQuotes(v)

                if not sesvarfunkeyexists:  # all correct Python values which do not contain the keywords fun( or var(
                    return (value, True, False)
                elif sesvarfunkeyexists and sesvarkeyfound is not None and checkquotes:  # value contains var( keyword in correct syntax
                    return (value, True, False)
                elif sesvarfunkeyexists and sesfunkeyfound is not None and checkquotes:  # value contains fun( keyword in correct syntax
                    return (value, True, False)
                elif sesvarfunkeyexists and (sesvarkeyfound is not None or sesfunkeyfound is not None) and not checkquotes:
                    QMessageBox.information(None, "Inserting not possible",
                                            "It seems you want to reference an SES variable or function. Please watch your quotes. "
                                            "If edited the variable will be deleted.", QtWidgets.QMessageBox.Ok)
                    if not edited:
                        return (value, False, False)
                    else:
                        return (value, False, True)
                elif sesvarfunkeyexists and sesvarkeyfound is None and sesfunkeyfound is None:  # value contains var( or fun( keywords not in correct syntax
                    QMessageBox.information(None, "Inserting not possible",
                                            "It seems you want to reference an SES variable or function.\n"
                                            "Please use the syntax\n\"var('sesvarname')\" or\n\"fun('sesfunname'[, 4.5])\" or\n\"fun('sesfunname'[, 'var('sesvarname')'])\" .\n"
                                            "The expression in square brackets is optional, do not type the square brackets. Use it if you want to pass parameters.\n"
                                            "sesvarname and sesfunname must be alphanumeric not beginning with a number.\n"
                                            "If edited the variable will be deleted.", QtWidgets.QMessageBox.Ok)
                    if not edited:
                        return (value, False, False)
                    else:
                        return (value, False, True)
                else:
                    return (value, False, False)  # if it is none of the above cases -> do nothing
            except:
                QMessageBox.information(None, "Inserting not possible",
                                        "Please enter a variable using Python syntax.\n"
                                        "If edited the variable will be deleted.", QtWidgets.QMessageBox.Ok)
                if not edited:
                    return ("", False, False)
                else:
                    return ("", False, True)

        else:  # empty value
            if not edited:
                QMessageBox.information(None, "The variable value is empty",
                                        "The variable value is empty. The variable can not be inserted.",
                                        QtWidgets.QMessageBox.Ok)
                return ("", False, False)
            else:
                QMessageBox.information(None, "The variable value is empty",
                                        "The variable value is empty. The variable is deleted.", QtWidgets.QMessageBox.Ok)
                return ("", False, True)
    """

    """color the value field if a var() or fun() can be interpreted -> old function: with var as keyword for SES Variable and fun as keyword for SES function"""
    """
    def validate(self):
        self.changeOnce = False
        for row in range(self.attribmodel.rowCount()):
            data = self.attribmodel.item(row, 1).data(QtCore.Qt.DisplayRole)
            #find all occurences of var
            matches = re.findall('var\([\"\']([a-z]|[A-Z])(\w+)?[\"\']\)', data)
            sesvarfound = []
            for ma in matches:
                #connect the tuple of each resulting group
                m = ma[0] + ma[1]
                #check if SES variable with this found name exists
                nameexists = False
                for sesvarvalue in self.sesVariables.outputSesVarList():
                    if m == sesvarvalue[0]:
                        nameexists = True
                        break
                sesvarfound.append(nameexists)
            #find all occurrences of fun
            matches = re.findall('fun\([\"\']([a-z]|[A-Z])(\w+)?[\"\'].*\)', data)
            sesfunfound = []
            for ma in matches:
                #connect the tuple of each resulting group
                m = ma[0] + ma[1]
                #check if SES function with this found name exists
                nameexists = False
                for sesfunvalue in self.sesFunctions.outputSesFunList():
                    if m == sesfunvalue[0]:
                        nameexists = True
                        break
                sesfunfound.append(nameexists)

            #color the rows according to the found result
            if not (not sesvarfound and not sesfunfound):   #if both lists are empty -> line does not contain fun(...) or var(...) -> do not color
                sesvarallfound = all(sesvarfound)
                sesfunallfound = all(sesfunfound)
                index1 = self.attribmodel.index(row, 1)
                if sesvarallfound and sesfunallfound:
                    color1 = QtGui.QColor(195, 255, 195, 255)
                else:
                    color1 = QtGui.QColor(255, 195, 195, 255)
                self.attribmodel.setData(index1, color1, QtCore.Qt.BackgroundColorRole)
        self.changeOnce = True
    """

    """new function: validate (commented function above)"""
    """