在Python桌面应用程序中使用什么架构模式

时间:2014-11-17 11:41:02

标签: python design-patterns

我是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工具包找到可以在数据库桌面应用程序上应用的最流行的模式。

希望你能在这个主题上深入了解我。

0 个答案:

没有答案
相关问题