PyQt4 QSqlTableModel,QTableView间歇性更新
我遇到了一个很奇怪的bug,怎么也找不到原因。
我有一个用PyQt4做的应用程序,它使用QSqlTableModel来在QTableView中显示数据。我在一个独立的程序中重复了这个bug。运行程序时,大部分单元格和列都是可以编辑的,并且可以更改数据库的数据。但是,这次运行时,第五行却无法编辑。奇怪的是,出现问题的行似乎是会变化的。
有没有什么建议可以帮助我进一步调试这个问题?我重写了setData方法,它的表现是正常的。它能接收到新的值,父类的setData也返回了True;但是,数据库的数据并没有改变,tableView又回到了旧的数据。
补充说明:我怀疑这可能是PyQt4的一个bug,所以我安装了最新的PyQt4(版本4.10)。但这似乎并没有改变问题的表现。我还注意到我没有包含我的数据库类。我更新了代码,加入了数据库类。它是从配置文件中获取数据库连接信息的。基本上,它只是使用了MySQL5的服务器作为后端。
class Database:
def __init__(self, parent = None):
print "Opening database connection."
self.data = QtSql.QSqlDatabase.addDatabase("QMYSQL")
self.data.setHostName(parent.config.get('Database','mysql_server'))
self.data.setPort(int(parent.config.get('Database','mysql_port')))
self.data.setDatabaseName(parent.config.get('Database','mysql_database'))
self.data.setUserName(parent.config.get('Database','mysql_user'))
self.data.setPassword(parent.config.get('Database','mysql_pass'))
if not self.data.open() :
print "error opening database"
print self.data.lastError().text()
print "database init complete"
class Model(QtSql.QSqlTableModel):
def __init__(self, prjID, parent = None):
super(Model, self).__init__(parent)
self.setEditStrategy(QtSql.QSqlTableModel.OnRowChange)
self.setTable("Debug")
self.setFilter("PrjID = " + str(prjID))
if not self.select() :
print "error, ", self.lastError().text()
class Main(QtGui.QMainWindow) :
def __init__(self) :
QtGui.QMainWindow.__init__(self)
self.config = ConfigParser.ConfigParser()
self.config.read("default.cfg")
self.db = Database(self)
self.model = Model(39,self)
self.tableView = QtGui.QTableView(self)
self.tableView.setGeometry(0,0,4000,400)
self.tableView.setModel(self.model)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = Main() #QtGui.QMainWindow()
#ui = Ui_MainWindow()
#ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
这是我创建的调试表。正如你在上面看到的,我的后端数据库是MySQL。我是不是在定义这个表的方式上做错了什么呢?
CREATE TABLE IF NOT EXISTS `Debug` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`PrjID` int(11) DEFAULT NULL,
`WorkType` int(11) DEFAULT NULL,
`Qty` double DEFAULT NULL,
`UnitCost` double DEFAULT NULL,
`Note` varchar(256) DEFAULT NULL,
`ShowDetail` tinyint(1) NOT NULL,
`SubTotal` float DEFAULT NULL,
UNIQUE KEY `ID` (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=101 ;
--
-- Dumping data for table `Debug`
--
INSERT INTO `Debug` (`ID`, `PrjID`, `WorkType`, `Qty`, `UnitCost`, `Note`, `ShowDetail`, `SubTotal`) VALUES
(1, 37, 10, 66, 1, 'asdfasdf', 1, 66),
(2, 37, 7, 22, 2, 'asdfasdf', 1, 44),
(3, 37, 11, 11, 33, 'asdfasdf', 1, 363),
(4, 37, 7, 1, 10, 'asdfasdf', 1, 10),
(5, 37, 10, NULL, NULL, 'aa', 0, NULL),
(100, 39, 6, 8, 10, 'aa', 0, 80),
(6, 38, 10, 2151, 0.20000000298, NULL, 0, 430.2),
(7, 38, 27, 120.25, 0, '123', 1, 0),
(8, 38, 22, 5.69, 5, NULL, 0, 28.45),
(9, 38, 7, 3, 35, NULL, 1, 105),
(11, 39, 1, 6, 35, 'aa', 0, 210),
(12, 39, 17, 17.78842, 6.5, 'zz', 0, 115.625),
(13, 39, 27, 147.944803, 0, 'zz', 0, 0),
(14, 39, 28, 82.17064, 15, NULL, 0, 1232.56),
(15, 39, 30, 64.42334, 0, 'aa', 0, 0);
1 个回答
1
可能的解释:我发现了一些其他的事情。我觉得我最根本的问题是我的表没有定义主键。当我用主键(PRIMARY KEY)来创建表,而不是唯一键(UNIQUE KEY)时,这个问题就解决了。
关于PyQt4,我还了解到我需要通过QTableView的setColumnHidden方法来隐藏列(比如ID列),而不是使用QSqlTableModel的removeColumn方法。一旦ID列(主键)被移除,更新就会出现问题。
我还发现,如果我使用的是视图(前提是这个视图必须是可编辑的,符合MySQL的要求),我需要在QSqlTableModel中手动设置主键。例如:
pk = QtSql.QSqlIndex("cursName","idxName")
pk.append(QtSql.QSqlField("ID"))
self.setPrimaryKey(pk)