python
class CheckBoxDeleta(QAbstractItemDelegate):
def __init__(self, parent: QObject | None = ...) -> None:
super().__init__(parent)
def createEditor(self, parent: QWidget, option: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex) -> QWidget:
return super().createEditor(parent, option, index)
def setEditorData(self, editor: QWidget, index: QModelIndex | QPersistentModelIndex) -> None:
return super().setEditorData(editor, index)
def setModelData(self, editor: QWidget, model: QAbstractItemModel, index: QModelIndex | QPersistentModelIndex) -> None:
return super().setModelData(editor, model, index)
def updateEditorGeometry(self, editor: QWidget, option: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex) -> None:
return super().updateEditorGeometry(editor, option, index)
class TableModel(QAbstractTableModel):
def __init__(self, parent: QObject | None = ...) -> None:
super(TableModel,self).__init__()
# paint row
def rowCount(self, parent: QModelIndex | QPersistentModelIndex = ...) -> int:
return 12
# paint col
def columnCount(self, parent: QModelIndex | QPersistentModelIndex = ...) -> int:
return 12
# Data to View Change and Save data
def setData(self, index: QModelIndex | QPersistentModelIndex, value: Any, role: int = ...) -> bool:
print(f"row:{index.row()} col:{index.column()} value:{value} ")
return True
# Init Data
def data(self, index: QModelIndex | QPersistentModelIndex, role: int = ...) -> Any:
return 12
def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> Any:
return super().headerData(section, orientation, role)
#Table Can Selected and Checked
def flags(self, index: QModelIndex | QPersistentModelIndex) -> Qt.ItemFlag:
return Qt.ItemFlag.ItemIsEditable | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled
#TODO:User define functions
class QSqlTableModelV2(QSqlTableModel):
__changed__={}
def __init__(self, parent, db) -> None:
super().__init__(parent, db)
def changedList(self)->dict:
return self.__changed__
def setRemoteData(self):
pass
def setData(self, index: QModelIndex | QPersistentModelIndex, value: Any, role: int = ...) -> bool:
self.__changed__[self.data(index.sibling(index.row(),0),Qt.ItemDataRole.DisplayRole)]=value
return super().setData(index, value, role) #Commit to database
#Set data
def data(self, idx: QModelIndex | QPersistentModelIndex, role: int = ...) -> Any:
print("data row:%d col:%d"%(idx.row(),idx.column()))
return super().data(idx, role)
def submitAll(self) -> bool:
return super().submitAll()
def submit(self) -> bool:
self.__changed__.clear()
return super().submit()
def revertAll(self) -> None:
self.__changed__.clear()
return super().revertAll()
全是嵌套的callback 的实现方法,层级分离,通过类的继承,拓展基础类的功能,通用性不错,省了自己在,调用原始方法,构建view 和 控制数据库,再将数据同步到板卡,利用现成的基础类,自己在拓展一个功能就🆗了
C 没有继承和多态,一言难尽,Python 的继承和多态应该是最容易理解的
添加复选框的方法(大体上只能说有这么一个功能,还有一些细节上的问题)
python
class QSqlTableModelV2(QSqlTableModel):
__changed__={}
def __init__(self, parent,DB) -> None:
super().__init__(parent,DB)
def data(self, idx: QModelIndex | QPersistentModelIndex, role: int = ...) -> Any:
if idx.column() != 0:
return super().data(idx, role)
else:
if self.__changed__.get(idx.row()) is not None:
self.__changed__[idx.row()][1]=super().data(idx,role)
if self.__changed__[idx.row()][0] == Qt.CheckState.Checked:
return Qt.CheckState.Checked
else:
return Qt.CheckState.Unchecked
else:
return Qt.CheckState.Unchecked
def setData(self, index: QModelIndex | QPersistentModelIndex, value: Any, role: int = ...) -> bool:
if role == Qt.ItemDataRole.CheckStateRole and index.column() ==0:
if value == Qt.CheckState.Checked.value:
self.__changed__[index.row()]=[Qt.CheckState.Checked,super().data(index,role),index.sibling(index.row(),3).data()]
elif value == Qt.CheckState.Unchecked.value:
self.__changed__[index.row()]=[Qt.CheckState.Unchecked,0,0]
return True
else:
return super().setData(index, value, role)
def flags(self, index: QModelIndex | QPersistentModelIndex) -> Qt.ItemFlag:
_flags = super().flags(index)
if index.column() in [1,2,4,5,6,7,8,9]:
_flags =_flags&(~Qt.ItemFlag.ItemIsEditable)
elif index.column() == 0:
_flags = Qt.ItemFlag.ItemIsUserCheckable|Qt.ItemFlag.ItemIsEnabled|Qt.ItemFlag.ItemIsSelectable|Qt.ItemFlag.ItemIsEditable
return _flags
def checkedTable(self) -> dict:
return self.__changed__
python
def flags(self, index: QModelIndex | QPersistentModelIndex) -> Qt.ItemFlag:
_flags = super().flags(index)
if index.sibling(index.row(),2).data() == "RO" or index.column() != self.__EditCol__:
_flags =_flags&(~Qt.ItemFlag.ItemIsEditable)
return _flags
装饰器的优势
python
def QuestionBox(msg:str):
def Msg(func):
def init(parent=None):
if QMessageBox.question(parent,"参数发生了变化","%s"%msg) == QMessageBox.StandardButton.Yes:
func(parent)
return init
return Msg
@QuestionBox("确认保存?")
def actSave(self):
print(self.__tableModel__.checkWrite())
self.__tableModel__.clearCheckWrite()
if self.__tableModel__.submitAll():
QMessageBox.information(self,"Operator Save","Successful")
else:
QMessageBox.critical(self,"Operator Save","Failed")
@QuestionBox("确认取消?")
def actAdd(self):
curIndex=self.__selModel__.currentIndex()
self.__tableModel__.insertRow(self.__tableModel__.rowCount()-1,1)
self.__selModel__.clearSelection()
self.__selModel__.setCurrentIndex(curIndex,QItemSelectionModel.SelectionFlag.Select)
@QuestionBox("确认删除")
def actDelete(self):
curIndex=self.__selModel__.currentIndex()
self.__tableModel__.removeRow(curIndex.row())
@QuestionBox("确认插入?")
def actInsert(self):
curIndex=self.__selModel__.currentIndex()
self.__tableModel__.insertRow(curIndex.row(),QModelIndex())
self.__selModel__.clearSelection()
self.__selModel__.setCurrentIndex(curIndex,QItemSelectionModel.SelectionFlag.Select)
@QuestionBox("确认取消?")
def actCancel(self):
if self.__tableModel__.revertAll():
QMessageBox.information(self,"Operator Cancel","Successful")
else:
QMessageBox.critical(self,"Operator Cancel","Failed")
一个完整的练习及操作方法
python
from typing import Any, Dict, Optional, Union
from PySide6.QtCore import *
import PySide6.QtCore
import PySide6.QtSql
from PySide6.QtWidgets import *
from PySide6.QtSql import *
from PySide6.QtGui import *
import PySide6.QtWidgets
from tableView_ui import Ui_MainWindow
import sys
import time
class CheckBoxDeleta(QAbstractItemDelegate):
def __init__(self, parent: QObject | None = ...) -> None:
super().__init__(parent)
def createEditor(self, parent: QWidget, option: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex) -> QWidget:
return super().createEditor(parent, option, index)
def setEditorData(self, editor: QWidget, index: QModelIndex | QPersistentModelIndex) -> None:
return super().setEditorData(editor, index)
def setModelData(self, editor: QWidget, model: QAbstractItemModel, index: QModelIndex | QPersistentModelIndex) -> None:
return super().setModelData(editor, model, index)
def updateEditorGeometry(self, editor: QWidget, option: QStyleOptionViewItem, index: QModelIndex | QPersistentModelIndex) -> None:
return super().updateEditorGeometry(editor, option, index)
class TableModel(QAbstractTableModel):
def __init__(self, parent: QObject | None = ...) -> None:
super(TableModel,self).__init__()
# paint row
def rowCount(self, parent: QModelIndex | QPersistentModelIndex = ...) -> int:
return 12
# paint col
def columnCount(self, parent: QModelIndex | QPersistentModelIndex = ...) -> int:
return 12
# Data to View Change and Save data
def setData(self, index: QModelIndex | QPersistentModelIndex, value: Any, role: int = ...) -> bool:
print(f"row:{index.row()} col:{index.column()} value:{value} ")
return True
# Init Data
def data(self, index: QModelIndex | QPersistentModelIndex, role: int = ...) -> Any:
return 12
def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> Any:
return super().headerData(section, orientation, role)
#Table Can Selected and Checked
def flags(self, index: QModelIndex | QPersistentModelIndex) -> Qt.ItemFlag:
return Qt.ItemFlag.ItemIsEditable | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled
class SelectedPara:
state:Qt.CheckState
indexForDB:str
idx:QModelIndex
def __init__(self,_st,id,idx) -> None:
self.state=_st
self.indexForDB=id
self.idx=idx
#TODO:User define functions
class QSqlTableModelV2(QSqlTableModel):
__EditCol__=2
__checkList__={}
__preValue__:Any
__querry__:str
__ro__:int = 0
def __init__(self, parent,DB) -> None:
super().__init__(parent,DB)
def setColumQuerry(self,columName:str):
self.__querry__ = columName
def setEditColumn(self,col:int):
self.__EditCol__=col
def setData(self, index: QModelIndex | QPersistentModelIndex, value: Any, role: int = ...) -> bool:
self.__checkList__[index.sibling(index.row(),0).data()]=value
return super().setData(index, value, role)
def selectStatement(self) -> str:
return "SELECT %s from %s"%(self.__querry__,self.tableName())
def checkWrite(self):
return self.__checkList__
def setReadonly(self,ro:int):
self.__ro__ = ro
def clearCheckWrite(self):
self.__checkList__.clear()
def flags(self, index: QModelIndex | QPersistentModelIndex) -> Qt.ItemFlag:
_flags = super().flags(index)
if index.sibling(index.row(),self.__ro__).data() == "RO" or index.column() != self.__EditCol__:
_flags =_flags&(~Qt.ItemFlag.ItemIsEditable)
return _flags
def QuestionBox(msg:str):
def Msg(func):
def init(parent=None):
if QMessageBox.question(parent,"参数发生了变化","%s"%msg) == QMessageBox.StandardButton.Yes:
func(parent)
return init
return Msg
class MainWindow(QMainWindow):
def __init__(self,parent=None):
super().__init__(parent)
self.ui=Ui_MainWindow()
self.ui.setupUi(self)
self.ui.select.clicked.connect(self.InitTable)
self.ui.open.clicked.connect(self.OpenDatabase)
self.ui.actionSave.triggered.connect(self.actSave)
self.ui.actionCancel.triggered.connect(self.actCancel)
self.ui.actionDelete.triggered.connect(self.actDelete)
self.ui.actionadd.triggered.connect(self.actAdd)
self.ui.actionInsert.triggered.connect(self.actInsert)
self.__handle__=QSqlDatabase.addDatabase("QSQLITE")
self.__tableModel__=QSqlTableModelV2(self,self.__handle__)
self.ui.tableView.verticalHeader().setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
self.__tableModel__.setEditStrategy(QSqlTableModel.EditStrategy.OnManualSubmit)
self.ui.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
self.ui.tableView.setModel(self.__tableModel__)
self.__selModel__=QItemSelectionModel(self.__tableModel__)
self.__selModel__.currentRowChanged.connect(self.do_currentChanged)
self.ui.tableView.setSelectionModel(self.__selModel__)
self.__tableModel__.setColumQuerry("ID,name,mode,V0")
self.__tableModel__.setReadonly(2)
self.__tableModel__.setEditColumn(3)
def do_currentChanged(self,cur:QModelIndex,pre:QModelIndex):
print("hello world")
def OpenDatabase(self):
self.__dbName__=self.ui.lineEdit
dbName,flt=QFileDialog.getOpenFileName(self,"Select Database File","","SQLITE DB(*.db)")
self.__dbName__.setText(dbName)
if dbName == "":
return
self.__handle__.setDatabaseName(dbName)
self.ui.comboBox.clear()
if self.__handle__.open() is not False:
rec=self.__handle__.exec("select * from sqlite_master where type='table'")
while rec.next():
self.ui.comboBox.addItem(str(rec.value(1)))
@QuestionBox("确认保存?")
def actSave(self):
print(self.__tableModel__.checkWrite())
self.__tableModel__.clearCheckWrite()
if self.__tableModel__.submitAll():
QMessageBox.information(self,"Operator Save","Successful")
else:
QMessageBox.critical(self,"Operator Save","Failed")
@QuestionBox("确认增加?")
def actAdd(self):
curIndex=self.__selModel__.currentIndex()
self.__tableModel__.insertRow(self.__tableModel__.rowCount()-1,1)
self.__selModel__.clearSelection()
self.__selModel__.setCurrentIndex(curIndex,QItemSelectionModel.SelectionFlag.Select)
@QuestionBox("确认删除?")
def actDelete(self):
curIndex=self.__selModel__.currentIndex()
self.__tableModel__.removeRow(curIndex.row())
@QuestionBox("确认插入?")
def actInsert(self):
curIndex=self.__selModel__.currentIndex()
self.__tableModel__.insertRow(curIndex.row(),QModelIndex())
self.__selModel__.clearSelection()
self.__selModel__.setCurrentIndex(curIndex,QItemSelectionModel.SelectionFlag.Select)
@QuestionBox("确认取消?")
def actCancel(self):
if self.__tableModel__.revertAll():
QMessageBox.information(self,"Operator Cancel","Successful")
else:
QMessageBox.critical(self,"Operator Cancel","Failed")
def InitTable(self):
self.__tableModel__.setTable(self.ui.comboBox.currentText())
if self.__tableModel__.select():
QMessageBox.information(self,"Operator Cancel","Successful")
else:
QMessageBox.critical(self,"Operator Cancel","Failed")
if __name__ == "__main__":
app=QApplication(sys.argv)
Window=MainWindow()
Window.show()
app.exit(app.exec())
界面定稿, 剩下的局势补充,交互逻辑,测试逻辑,还有一些合适的图标需要补充
还有使用的说明手册