- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
当我尝试从 pyqt 小部件更新数据库时,我得到一个 sqlite3.OperationalError: database is locked
。
主窗口显示数据库中的项目列表。双击一个项目时,将弹出一个小部件,其中包含用于修改数据库同一行中的值的选项。
我有 4 个独立的 .py 文件;(我已经删除了大部分代码)
DBmanager.py
,包含与数据库交互的所有函数。
class DatabaseUtility:
def __init__(self, databaseFile):
self.db = databaseFile
self.conn = sqlite3.connect(self.db)
self.c = self.conn.cursor()
def ChangeItemQuantity(self, itemName, incramentQuantity):
try:
# Change given item quantity in database
self.c.execute('''
SELECT quantity
FROM items
WHERE itemName=?
''',(itemName,))
print(itemName)
print(incramentQuantity)
current_quantity = self.c.fetchone()
print(current_quantity[0])
new_quantity = current_quantity[0] + incramentQuantity
self.c.execute('''
UPDATE items
SET quantity = ?
WHERE itemName=?
''',(new_quantity, itemName))
self.conn.commit()
except Exception as error:
# Rollback any changes if something goes wrong.
self.conn.rollback()
raise error
def __del__(self):
"""Commit and close database connection when the class is terminated."""
# pass
self.conn.commit()
self.c.close()
self.conn.close()
StartGui.py
包含 GUI 的功能。
import sys
from PyQt4 import QtCore, QtGui
from guiFormat import Ui_MainWindow
from itemWidget import Ui_itemWidget
from DBmanager import DatabaseUtility
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.db = 'testdb.db'
self.dbUtil = DatabaseUtility(self.db)
self.ui.updateButton.clicked.connect(self.populateTable_default)
self.ui.updateButton.clicked.connect(self.dbUtil.UpdateDatabase)
self.ui.searchButton.clicked.connect(self.populateTable_search)
self.ui.tableWidget.doubleClicked.connect(self.open_item_widget)
self.ui.tableWidget.resizeRowsToContents()
# Populate table on initial startup
self.populateTable_default()
def open_item_widget(self):
self.item_widget = ItemWidget(self)
# self.item_widget.show()
column_count = self.ui.tableWidget.columnCount()
self.item_widget.ui.tableWidget.setColumnCount(column_count)
self.item_widget.ui.tableWidget.setRowCount(1)
column_names = self.dbUtil.GetColumns('items')
self.item_widget.ui.tableWidget.setHorizontalHeaderLabels(column_names)
row = self.ui.tableWidget.currentRow()
for column in range(column_count):
x = self.ui.tableWidget.item(row, column).text()
item_data = QtGui.QTableWidgetItem(str(x))
self.item_widget.ui.tableWidget.setItem(0, column, item_data)
self.item_widget.show()
class ItemWidget(QtGui.QWidget):
def __init__(self, parent=None):
self.db = 'testdb.db'
self.dbUtil2 = DatabaseUtility(self.db)
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_itemWidget()
self.ui.setupUi(self)
self.ui.cancelOkButtonBox.rejected.connect(self.close)
self.ui.cancelOkButtonBox.accepted.connect(self.submit_changes)
def submit_changes(self):
# Get item Name.
item_name = self.ui.tableWidget.item(0,0).text()
# Get number from increment box.
quant_increment = self.ui.QuantSpinBox.value()
alert_incrament = self.ui.alertSpinBox.value()
print('Changing quantity...', item_name, quant_increment)
self.dbUtil2.ChangeItemQuantity(item_name, quant_increment)
self.close()
##======================================================================================================================
##======================================================================================================================
if __name__ == "__main__":
dbUtil = DatabaseUtility('testdb.db')
app = QtGui.QApplication(sys.argv)
mainwindow = MainWindow()
mainwindow.show()
# itemwidget = ItemWidget()
# itemwidget.show()
sys.exit(app.exec_())
Mainwindow.py
是主窗口的 pyqt 设计器的导出。
Itemwidget.py
也是项目小部件的 pyqt 设计器的导出。
谢谢大家的帮助。
最佳答案
sqlite3
文档说:
When a database is accessed by multiple connections, and one of the processes modifies the database, the SQLite database is locked until that transaction is committed.
由于您有两个连接,一个由 MainWindow
打开,另一个由 ItemWidget
打开,您的问题的一个可能原因就是文档所说的。当另一个连接所做的更改未提交时,一个连接会尝试更新数据库。您显示的 ChangeItemQuantity
方法不会发生这种情况,因为它所做的更改会立即提交,但显然 DatabaseUtility
有您未显示的其他方法,例如 更新数据库
。如果他们做出的更改没有立即提交,那可能就是问题所在。
让 MainWindow
和 ItemWidget
共享一个连接,看看问题是否消失。您可以通过使 conn
成为 DatabaseUtility
实例的共享属性来做到这一点,而不更改调用者:
class DatabaseUtility:
conn = None
def __init__(self, databaseFile):
self.db = databaseFile
if self.__class__.conn is None:
self.__class__.conn = sqlite3.connect(self.db)
self.c = self.conn.cursor()
此外,虽然这似乎不太可能成为问题,但如果其他进程在同一个 SQLite 数据库上有一个打开的事务,只要该事务处于事件状态,数据库就会被锁定。有些应用程序似乎有保持活跃交易的坏习惯。每当我用 SQLite Browser 打开数据库时,我无法从其他程序对数据库执行任何操作(也许我可以将其关闭,但我从来没有想过如何...)
关于Python Sqlite3 数据库锁定,QWidget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35517710/
我有一个关于 c++ 中的 qt 的问题 头文件: #ifndef TIMER_H #define TIMER_H #include #include #include #include cl
我有以下代码: import os from functools import partial import numpy as np from PyQt5 import QtCore, QtWidge
我有一个 QWidget B,它包含在 QWidget A 中。QWidget A 有一个 QLabel。我在 QWidget B 中有一些数据,我想将其设置为 QLabel 的值。这种事情怎么办?
为了解释这种情况,我有一个 QMainWindow,里面有很多东西。我的目标是制作某种通知,显示在该窗口的右下角。 通知小部件必须位于所有其他小部件之上。 到目前为止,我已经创建了从 QWidget
这个问题对我来说可能是缺乏对 C++ 的理解,因为我为我的问题考虑过的所有可能性似乎都无法说明为什么会发生这种情况。感谢反馈。 我正在使用表单设计器创建一个包含表格的表单类。我正在尝试用辅助类中生成的
我选择使用 Qt 来管理我正在处理的项目的 GUI。 在找到如何在我的 QWidget 底部应用图片后,我注意到它对添加到其中的所有组件都有影响。 无论通过 setStyleSheet 方法或什至使用
我有一个带有两个小部件的主窗口,buttonsWidget 和 infoWidget。我试图在单击 buttonsWidget 中的按钮后隐藏 infoWidget(并最终显示不同的小部件)。 我试过
虽然 Qt's docs表明这两个功能是不同的(第一个不包括框架)无论我选择什么小部件 - 包括我的应用程序的主窗口 - someWidget->frameGeometry().height()始终返
这是包含一系列小部件的 QFormLayout 的屏幕截图。请注意,顶部和底部输入小部件未与中间两行水平对齐。另请注意,左侧的标签未与中间两行垂直对齐。 不同之处在于顶部和底部小部件是普通的 QLin
我有几个小部件,比如 QLineEdit m_namePoiFilter; QLineEdit m_ID_MSSIPoiFilter; 我想将它们添加到 qwi
我创建了一个非常简单的 QWidget 子类,如下所示: class WorldView : public QWidget { Q_OBJECT public: explicit Wo
我在屏幕上有很多固定的 qwidgets,还有很多其他的 widgets 我可以在屏幕上拖动。当一个小部件被拖动到固定小部件之上时,固定小部件需要执行一些代码。我无法弄清楚静止对象如何知道它上面有一个
我正在使用 Qt 设计器 4.8.7,从它开始。我创建了一个 MainWindow ,我想在其中加载布局。 我有一个小部件,由 Qt 设计器使用 pyuic4 生成。 我加载我的小部件正在做 self
我正在尝试使 QWidget 粘在屏幕右边框上,并在左侧显示/隐藏另一个 QWidget。我们的目标是在决赛中实现类似的目标: ---------------------------------- |
完全使用 QT Designer。我创建了一个 QWidget 来封装一组控件。我现在想在 QMainWindow 表单中多次使用此 QWidget。 如何仅使用 QT Designer 将我的 QW
我有一组出现在不同地方的小弹出窗口小部件,但每次只出现一个。对于简单的功能,new-to-show 和 delete-to-hide 没问题,并且按预期工作,但当它们开始处理自己的数据时,我可以看到内
我有一些 QWidget 类,它的 ui 文件与 QMainWindow ui 文件是分开的。 如何将粘附到 QMainWindow 的当前 QWidet 添加或替换为来自同一 QMainWindow
我正在使用基于 QWidget 的 PyQt 开发应用程序。我将整个应用程序放在一个类中(名为“示例”)。在这个应用程序中,我有一个按钮可以调用我在 QtDesigner 上设计的另一个 QWidge
在运行时尝试向 QWidget 添加按钮时,我遇到了一个奇怪的问题。我有一个带有 QTabWidget 的窗口,它有 2 个选项卡。当我按下窗口上的按钮时,它会在第一个选项卡上生成一组复选框。 问题是
我正在尝试运行一个简单的 Qt 程序,这样做时,我得到一个控制台窗口,提示:QWidget: Cannot create a QWidget when no GUI is being used,第二行
我是一名优秀的程序员,十分优秀!