【发布时间】:2021-04-27 22:08:57
【问题描述】:
我正在尝试让 PyQt 中的多窗口应用程序工作,它应该以不同的方式在多个窗口中显示数据。现在我遇到了一个我不了解QDataWidgetMapper 的问题。为了解释,我创建了一个示例应用程序。 下面的代码确实创建了
-
与 SQLite 数据库的连接
-
创建两个相同的窗口,显示一个 QTable 和一个映射在单元格 0,0 上的 QlineEdit
import sys from PyQt5.QtCore import QSize, Qt from PyQt5.QtSql import QSqlDatabase, QSqlTableModel from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView, QMessageBox,\ QLineEdit, QWidget, QVBoxLayout, QDataWidgetMapper from Singleton import Singleton class SqlModel(QSqlTableModel, metaclass=Singleton): def __init__(self, parent=None): con = QSqlDatabase.addDatabase("QSQLITE") con.setDatabaseName("chinook.sqlite") con.open() super().__init__() class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setMinimumSize(QSize(400, 200)) widget = QWidget() layout = QVBoxLayout() widget.setLayout(layout) self.setCentralWidget(widget) self.table = QTableView() layout.addWidget(self.table) self.inputField = QLineEdit() layout.addWidget(self.inputField) self.model = SqlModel() self.model.setTable("Track") print(self.model.lastError().text()) self.table.setModel( self.model ) print(self.model.lastError().text()) self.mapper = QDataWidgetMapper() self.mapper.setModel(self.model) self.mapper.addMapping(self.inputField, 0) self.model.select() self.mapper.toFirst() def createConnection(): con = QSqlDatabase.addDatabase("QSQLITE") con.setDatabaseName("chinook.sqlite") if not con.open(): print('could not open db') return False return True app = QApplication(sys.argv) window = MainWindow() window.show() window2 = MainWindow() window2.show() app.exec_()
两个窗口都打开了。 两个 QTables 都完美同步。 但只有一个 LineEdit 在其中一个窗口中确实会跟随任何值更改,另一个窗口中的 QLineEdit 只是显示打开时的初始值无需任何进一步的操作。
为了完整起见,单例类的代码:
from PyQt5.QtCore import QObject
class Singleton(type(QObject), type):
'''
:class: Parent class used to build the individial singletons across the program.
'''
def __init__(cls, name, bases, dict): # @NoSelf @ReservedAssignment
super().__init__(name, bases, dict)
cls._instance = None
def __call__(cls, *args, **kwargs): # @NoSelf
if cls._instance is None:
cls._instance = super().__call__(*args, **kwargs)
return cls._instance
【问题讨论】:
-
你给
select()打了两次电话。您需要重新组织您的代码,以便它 separates the concerns 来自 windows 的模型。事实上,模型的设置是在窗口初始化期间执行的,所以所有事情都会完成两次。在它自己的__init__中为模型进行所有设置(它只被调用一次,因为它是一个单例)。