我是Python编程语言的新手。 我打算使用“PyQt”构建桌面应用程序......
我一直在搜索构建应用程序时使用的最佳架构设计。
每个应用程序将由以下组成:用户界面和数据库(mySql)。
我感谢这个领域的任何帮助,一些有见地的例子会非常有用。
我尝试在测试对象中应用mvc模式,因为我的导演告诉我......这是我的代码:
视图类(由pyuic5命令生成):
from PyQt5 import QtWidgets, QtCore, QtGui
from datetime import *
import sys
class Ui_Dialog(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.setupUi(self)
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 200)
self.vLayout = QtWidgets.QVBoxLayout(Dialog)
self.vLayout.setObjectName("verticalLayout")
self.widget = QtWidgets.QWidget(Dialog)
self.widget.setGeometry(QtCore.QRect(15, 20, 366, 206))
self.widget.setObjectName("widget")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.gridLayout.setRowMinimumHeight(0, 50)
self.gridLayout.setRowMinimumHeight(1, 50)
self.gridLayout.setRowMinimumHeight(2, 50)
self.gridLayout.setRowMinimumHeight(3, 20)
self.label = QtWidgets.QLabel(self.widget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.lineEdit = QtWidgets.QLineEdit(self.widget)
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.setEnabled(False)
self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 3)
self.label_2 = QtWidgets.QLabel(self.widget)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
self.lineEdit_2 = QtWidgets.QLineEdit(self.widget)
self.lineEdit_2.setObjectName("lineEdit_2")
self.gridLayout.addWidget(self.lineEdit_2, 1, 1, 1, 3)
self.label_3 = QtWidgets.QLabel(self.widget)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 2, 0, 1, 1)
self.lineEdit_3 = QtWidgets.QLineEdit(self.widget)
self.lineEdit_3.setObjectName("lineEdit_3")
self.gridLayout.addWidget(self.lineEdit_3, 2, 1, 1, 3)
#Add PushButtons
self.pbNext = QtWidgets.QPushButton(">", self)
self.gridLayout.addWidget(self.pbNext, 3, 2)
self.pbPrevious = QtWidgets.QPushButton("<", self)
self.gridLayout.addWidget(self.pbPrevious, 3, 1)
self.pbFirst = QtWidgets.QPushButton("<<", self)
self.gridLayout.addWidget(self.pbFirst, 3, 0)
self.pbLast = QtWidgets.QPushButton(">>", self)
self.gridLayout.addWidget(self.pbLast, 3, 3)
self.pbAdd = QtWidgets.QPushButton("+", self)
self.gridLayout.addWidget(self.pbAdd, 0, 4)
self.pbDelete = QtWidgets.QPushButton("x", self)
self.gridLayout.addWidget(self.pbDelete, 1, 4)
self.pbOpenId = QtWidgets.QPushButton("OpenId", self)
self.gridLayout.addWidget(self.pbOpenId, 2, 4)
self.pbQuit = QtWidgets.QPushButton("Quit", self)
self.gridLayout.addWidget(self.pbQuit, 3, 4)
self.vLayout.addLayout(self.gridLayout)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Test my dialog"))
self.label.setText(_translate("Dialog", "Id"))
self.label_2.setText(_translate("Dialog", "First name"))
self.label_3.setText(_translate("Dialog", "Last name"))
Model类:
from PyQt5 import QtSql, QtCore
class DBModel(QtCore.QObject):
def __init__(self, p_sdbName, p_sHostName, p_sUserName, p_sUserPassword, p_sMainTblName):
super().__init__()
# connect to mydb on mysql drive
bConnected, self.connection = self.connectDB(p_sdbName, p_sHostName, p_sUserName)
if bConnected:
self.initModel(p_sMainTblName)
self.modelRowCount = self.getModelRowCount()
else:
self.lastError = "Failed to connect to the database due to the following error: \n{}" \
.format(self.connection.lastError())
def connectDB(self, p_dbName, p_hostName, p_userName):
bReturn = False
connection = QtSql.QSqlDatabase.addDatabase("QMYSQL")
connection.setDatabaseName(p_dbName)
connection.setHostName(p_hostName)
connection.setUserName(p_userName)
if connection.open():
bReturn = True
return bReturn, connection
def initModel(self, p_sTblName):
self.model = QtSql.QSqlTableModel(self, self.connection)
self.model.setTable(p_sTblName)
self.model.select()
def getModelRowCount(self):
return self.model.rowCount()
def insertRow(self):
self.model.insertRow(self.modelRowCount)
self.modelRowCount += 1
def getMaxId(self):
query = QtSql.QSqlQuery("Select Max(personid) as maxid from person", self.connection)
if (query.next()):
return query.value(0)
return
def deleteRowByIndex(self, p_intIndex):
self.model.removeRow(p_intIndex)
self.model.submitAll()
self.modelRowCount = self.model.rowCount()
self.model.select()
def getDataForId(self, p_intId):
self.model.setFilter(" personId = {}".format(p_intId))
self.model.select()
这是我的控制者:
import sys
from PyQt5 import QtGui, QtCore, QtWidgets, QtSql
import View
import Model
FIRST, LAST, PREVIOUS, NEXT = range(4)
class Controller(QtWidgets.QDialog):
def __init__(self, parent = None):
super().__init__(parent)
self.myDlg = View.Ui_Dialog()
self.connectButtons()
self.dbModel = Model.DBModel("mydb", "localhost", "root", "", "person")
# create a model that reads from "Person" table in db "MyDB"
self.tblRowCount = self.dbModel.modelRowCount
self.modelRowCount = self.dbModel.getModelRowCount()
# map the dlg fields to the db fields
self.mapper = QtWidgets.QDataWidgetMapper(self)
self.mapper.setSubmitPolicy(QtWidgets.QDataWidgetMapper.ManualSubmit)
self.mapper.setModel(self.dbModel.model)
self.mapper.addMapping(self.myDlg.lineEdit, 0)
self.mapper.addMapping(self.myDlg.lineEdit_2, 1)
self.mapper.addMapping(self.myDlg.lineEdit_3, 2)
self.mapper.toFirst()
self.setButtonsEnabled()
def connectButtons(self):
self.myDlg.pbNext.clicked.connect(lambda: self.navigate(NEXT))
self.myDlg.pbPrevious.clicked.connect(lambda: self.navigate(PREVIOUS))
self.myDlg.pbLast.clicked.connect(lambda: self.navigate(LAST))
self.myDlg.pbFirst.clicked.connect(lambda: self.navigate(FIRST))
self.myDlg.pbQuit.clicked.connect(self.quit)
self.myDlg.pbAdd.clicked.connect(self.addRecord)
self.myDlg.pbDelete.clicked.connect(self.deleteRecord)
self.myDlg.pbOpenId.clicked.connect(self.openId)
def navigate(self, p_intDirection):
intRow = self.mapper.currentIndex()
self.mapper.submit()
if p_intDirection == FIRST:
intRow = 0
elif p_intDirection == LAST:
intRow = self.dbModel.modelRowCount - 1
elif p_intDirection == NEXT:
intRow += 1
elif p_intDirection == PREVIOUS:
intRow -= 1
self.mapper.setCurrentIndex(intRow)
self.setButtonsEnabled()
def setButtonsEnabled(self):
intCurrentIndex = self.mapper.currentIndex()
if self.modelRowCount == 1:
self.myDlg.pbPrevious.setEnabled(False)
self.myDlg.pbNext.setEnabled(False)
self.myDlg.pbLast.setEnabled(False)
self.myDlg.pbFirst.setEnabled(False)
if intCurrentIndex == 0:
self.myDlg.pbPrevious.setEnabled(False)
self.myDlg.pbNext.setEnabled(True)
self.myDlg.pbLast.setEnabled(True)
self.myDlg.pbFirst.setEnabled(False)
elif intCurrentIndex == self.modelRowCount - 1:
self.myDlg.pbPrevious.setEnabled(True)
self.myDlg.pbNext.setEnabled(False)
self.myDlg.pbLast.setEnabled(False)
self.myDlg.pbFirst.setEnabled(True)
else:
self.myDlg.pbPrevious.setEnabled(True)
self.myDlg.pbNext.setEnabled(True)
self.myDlg.pbLast.setEnabled(True)
self.myDlg.pbFirst.setEnabled(True)
def quit(self):
self.mapper.submit()
QtWidgets.QDialog.accept(self.myDlg)
def addRecord(self):
self.mapper.submit()
self.dbModel.insertRow()
self.mapper.setCurrentIndex(self.modelRowCount + 1)
self.modelRowCount += 1
self.myDlg.lineEdit.setText(str(self.modelRowCount + 1))
self.myDlg.lineEdit_2.setText("")
self.myDlg.lineEdit_3.setText("")
self.setButtonsEnabled()
self.myDlg.lineEdit_2.setFocus()
self.dbModel.getMaxId()
def deleteRecord(self):
intCrntRow = self.mapper.currentIndex()
if QtWidgets.QMessageBox.question(self, "Confirmation", """Are you sure you want to delete the person
{0} {1} ?""".format(self.lineEdit_2.text(), self.lineEdit_3.text())) == QtWidgets.QMessageBox.No:
return
self.dbModel.deleteRowByIndex(intCrntRow)
if intCrntRow - 1 < 0:
intCrntRow += 1
else:
intCrntRow -= 1
self.mapper.setCurrentIndex(intCrntRow)
self.setButtonsEnabled()
def openId(self):
self.dbModel.getDataForId(7)
self.mapper.toFirst()
关键是我读到视图应该有一个控制器的实例,而不是这里,我不明白在这里做的事情。特别是我不想从pyuic命令更改生成的文件。
我并不具体说明使用什么模式,我正在寻找使用PyQt工具包找到可以在数据库桌面应用程序上应用的最流行的模式。
希望你能在这个主题上深入了解我。