- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我希望通过 QSqlQueryModel 查询 SQL 数据库(PyqQt 5/Qt 5.2) 异步,因此 GUI 不会阻塞。如何实现?也许通过多线程?请提供如何执行此操作的代码。如果异步使用 QSqlQueryModel 不实用,请随时提供替代方案(尽管应该可以与 QTableView 一起使用)。
我的(同步)代码当前如下所示。主脚本 bin/app.py 加载 gui/__init__.py 并执行其 main
方法。这反过来使用 gui.models.Table
从数据库加载数据。问题是 gui.models.Table
同步查询数据库并同时锁定 GUI。
斌/应用程序.py:
import os.path
import sys
sys.path.insert(0, os.path.abspath(os.path.join(
os.path.dirname(__file__), "..")))
import gui
if __name__ == "__main__":
gui.main()
import sys
import os.path
from PyQt5 import uic
from PyQt5 import QtCore, QtWidgets
from gui import models
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi(os.path.join(os.path.dirname(__file__), 'app.ui'), self)
self.tableView.setModel(models.Table(self))
def main():
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
import os.path
from PyQt5.QtCore import *
from PyQt5.QtSql import *
class Table(QSqlQueryModel):
def __init__(self, parent=None):
super(Table, self).__init__(parent)
pth = os.path.abspath(os.path.join(os.path.dirname(__file__), "..",
"test.sqlite"))
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(pth)
if not db.open():
raise Exception("Couldn't open database '{}'".format(pth))
try:
self.setQuery("select * from Test")
finally:
db.close()
最佳答案
不幸的是,Qt(或其他任何人)使用的典型数据库驱动程序是同步的。不幸的是,Qt View 不知道如何处理外部线程中的模型。
因此,该解决方案需要一个 shim 代理模型,子类化 QIdentityProxyModel
.实现的第一步是使用阻塞 QMetaObject::invokeMethod
填充源模型的所有方法调用。来电。这只是为了正确,如果还不是异步的话。它只是向存在于另一个线程中的模型公开一个安全接口(interface)。
下一步是在某些功能上提供异步胶合板。假设您要制作 data
方法异步。你要做的是:
dataChanged
来自源模型的信号,缓存所有角色中更改的所有值。 data
调用需要在模型的线程中排队 - 稍后会详细介绍。 data
,如果有缓存命中,则返回它。否则返回一个空变量并将 data
排队调用模型的线程。 cacheData
的私有(private)方法将从排队的调用中调用。在另一个答案中,我有
detailed how to queue functor calls in another thread .利用这一点,您的数据调用队列方法可能如下所示:
void ThreadsafeProxyModel::queueDataCall(const QModelIndex & index, int role) {
int row = index.row();
int column = index.column();
void * data = index.internalPointer();
postMetacall(sourceModel()->thread(), [this, row, column, data, role]{
QVariant data = sourceModel()->data(createIndex(row, column, data), role);
QMetaObject::invoke(this, "cacheData",
Q_ARG(QVariant, data), Q_ARG(int, role),
Q_ARG(int, row), Q_ARG(int, column), Q_ARG(void*, data));
});
}
关于multithreading - 如何通过 QSqlQueryModel 进行异步查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22482599/
我有一个我维护的数据库的小型管理应用程序。我所关注的表中的记录永远不会超过 1000 到 1500 条,而且只有大约八列数据。我查看它的表单是 QTableView 的子类,我正在使用 QSqlQue
我有一个包含查询结果的 QSqlQueryModel 可以有几万行。 这个模型有两个用例: 一个用例,我需要完整的模型来计算行的一些统计信息; 一个用例,我想显示内容的概览。 我的问题是第二种情况,什
我使用QSqlQueryModel查询一个postgresql数据库,我发现数据库中所有的Infinity和-Infinity值( double )我使用 model->data(index, Qt:
我正在尝试使用 QSqlQueryModel 来从我的数据库中检索一些值,例如: QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL", "test
我在实现 QSqlQueryModel 时无法理解如何访问返回的元素。 我知道你可以做到 QSqlQuery 查询; query.prepare("select * from database");
我希望通过 QSqlQueryModel 查询 SQL 数据库(PyqQt 5/Qt 5.2) 异步,因此 GUI 不会阻塞。如何实现?也许通过多线程?请提供如何执行此操作的代码。如果异步使用 QSq
我只想处理数据库并将结果添加到模型并将其发送到另一个类并在 GUI 中查看。摘要代码为: 我有一个公共(public)类成员: QSqlQueryModel *model; 加载数据并将其添加到模型
我要为这个下层的每个结果计算新行 QSqlQueryModel *model = new QSqlQueryModel(); model->setQuery("SELECT height,age fr
我很少有组合框,其中包含大约 10 万行或更多行的非常挖掘的数据集。我尝试使用 QStandardItemModel - 如果预加载模型,工作速度足够快,如果在单独的线程中执行,模型加载也需要几秒钟。
我有一个名为 Load 的类,它从数据库中加载数据。另一类是将数据显示在表格中。在我返回 QSqlQueryModel 的函数中,它是:目前只是基本的,因为我无法编译它: QSqlQueryModel
我有一个 lineExdit 和一个 tableView,我想根据在 lineEdit 中输入的文本实时更新 tableView。 void updateTableView(QString *st)
我在正确转置从 db 收到的表时遇到问题。我按照找到的路径 here ,并最终继承了 QAbstractProxyModel - 如描述的那样 here .不幸的是,它不能完全工作,这就是问题所在:
我想在 qml TableView 中显示 QSqlQueryModel,但我不想为每个新查询创建单独的 QML 文件,因为我无法创建给定的无限 qml 文件 here .还有 question对于动
为了加快 QComboBox 处理非常大的数据集,想尝试使用 QSqlQueryModel 而不是 QStandardItemModel。然而,QComboBox 中的文本数据我需要映射到一个 ID,
我在将 QSqlQueryModel 与准备好的语句一起使用时遇到问题。手动执行语句时一切正常,但将其绑定(bind)到模型时 - 它不会执行。另一方面,当我使用“静态”查询(通过 QString)设
我正在尝试从 QSqlQueryModel 中删除一行,如下所示: void MainWindow::deleteRecord() { int row_index= ui->tableView
我有一个显示QSqlQueryModel 的QTableView。该模型包含在第一列的每一行中创建的复选框(其中包含 ref_no;我的数据库中的主键)如下所示: void MainWindow::s
我想从我的 SQlite 数据库中获取模型,当我在 QSqlQueryModel 中设置查询时,我可以获得行数、列数等。但是每列中的数据我有一个 ReferenceError 试图获取列名cpp代码:
如果我们使用以下 QT 功能从 SQL 数据库获取数据 QSqlQueryModel *model = new QSqlQueryModel; model->setQuery("SELECT na
我使用以下方法在 QTableView 中显示 select 语句的结果。我应该如何修改此代码以在同一 QTableView 中显示两个或多个不同选择语句的结果? QSqlDatabase db =
我是一名优秀的程序员,十分优秀!