我正在尝试从我的表中的mysql数据库更新一个单元格,但我无法将全局变量传递给单元格。目前我从mysql数据库中获取一个整数,然后我尝试全局定义,然后我将变量传递给mystruct(表的结构),最后我将mystruct应用到表中,并给出了错误{{ 1}},我知道为什么因为self.mystruct1首先在AttributeError: 'Window' object has no attribute 'struct1'
中使用。有替代方案吗?请查看下面的代码以了解。
*注意位置无关紧要
__init__
手动触发(代码2):
import sys
from PyQt4.QtGui import QTableWidget
from PyQt4 import QtGui,QtCore
import MySQLdb as mdb
import time
class Window(QtGui.QDialog,object):
def get_data_status(self):
self.model.execute("""SELECT cpu FROM table
WHERE date = (SELECT MAX(date) FROM table)""")
rows_status = self.model.fetchone()
self.listc1 = ['%s' % rows_status]#['%s %s' % self.rows_status]
self.lista1 = 'Juliet','Julietleft','Pong','Hulk'
self.listb1 = 'None','None','None','None'
self.mystruct1 = {'A':self.lista1, 'B':self.listb1, 'C':self.listc1}
print self.mystruct1
return self.mystruct1
# this is only for the temp time test
def new_data_status(self):
self.update_ready_status.emit()
update_ready_status = QtCore.pyqtSignal()
def __init__(self,parent=None):
super(Window, self).__init__()
self.layout = QtGui.QVBoxLayout(self)
self.db = mdb.connect('server','user','user','db')
self.model = self.db.cursor()
self.table1 = MyTableStatus(Window.get_data_status(self),145,4)
self.table1.repaint()
self.table1.reset()
self.layout.addWidget(self.table1)
self.update_ready_status.connect(self.get_data_status)
self.timer_status = QtCore.QTimer()
self.timer_status.timeout.connect(self.new_data_status)
# check every half-second
self.timer_status.start(1000*2)
class MyTableStatus(QTableWidget):
def sizeHint(self):
width = 0
for i in range(self.columnCount()):
width += self.columnWidth(i)
width += self.verticalHeader().sizeHint().width()
width += self.verticalScrollBar().sizeHint().width()
width += self.frameWidth()*2
return QtCore.QSize(width,self.height())
def __init__(self, thestruct,*args):
QTableWidget.__init__(self, *args)
self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Preferred)
self.data = thestruct
self.setHorizontalHeaderLabels(['Server', 'Avg. Disk Queue','CPU Load',"Status"])
self.setmydata()
QTableWidget.setSortingEnabled(self,True)
def setmydata(self):
for n, key in enumerate(self.data):
for m, item in enumerate(self.data[key]):
newitem = QtGui.QTableWidgetItem(item)
self.setItem(m, n, newitem)
def main():
app = QtGui.QApplication(sys.argv)
app.setStyle(QtGui.QStyleFactory.create("plastique"))
main_window = Window()
main_window.repaint()
main_window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
答案 0 :(得分:2)
此代码中的逻辑有点乱,但我可以看到数据未更新的问题。
self.mystruct1
传递到自定义表以首次显示数据。在后续触发器上,然后在主窗口中覆盖该字典,认为Table将具有相同的引用。发生的事情是Window有了新的字典,而Table就坐在原来的对象上。model
并不能赋予它与QModel相同的功能。__init__
放在类的顶部,这样人们阅读它就可以在看到它的方法之前立即看到设置类的内容。 / LI>
醇>
要解决这个问题,首先要清除一些问题。在这种情况下,您不需要向发出另一个信号的插槽发送信号。除了让它更加混乱之外,它没有做任何事情。只需将信号直接连接到Table上将执行更新的插槽即可。还要摆脱桌面主窗口中的重绘和重置调用。
您可以采用两条路径向表中提供数据。您可以直接从窗口更新表格上的数据模型,然后告诉它刷新,或者,您可以通过信号传递新数据并让表格处理它......
class Window(QtGui.QDialog):
def __init__(self,parent=None):
super(Window, self).__init__()
...
initialData = self.get_data_status()
self.table1 = MyTableStatus(initialData, 145, 4)
...
self.timer_status = QtCore.QTimer()
self.timer_status.timeout.connect(self.updateAllViews)
# check every half-second
self.timer_status.start(1000*2)
def get_data_status(self):
...
self.mystruct1 = {'A':self.lista1, 'B':self.listb1, 'C':self.listc1}
return self.mystruct1
def updateAllViews(self):
_ = self.get_data_status()
self.updateTable()
def updateTable(self):
self.table1.updateFromDict(self.mystruct1)
class MyTableStatus(QTableWidget):
def __init__(self, thestruct, *args):
QTableWidget.__init__(self, *args)
self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Preferred)
self.setHorizontalHeaderLabels(['Server', 'Avg. Disk Queue','CPU Load',"Status"])
self.setSortingEnabled(True)
self.data = {}
self.setmydata(thestruct)
def updateFromDict(self, aDict):
self.data.clear()
self.data.update(aDict)
self.setmydata()
def setmydata(self):
for n, key in enumerate(self.data):
for m, item in enumerate(self.data[key]):
newitem = QtGui.QTableWidgetItem(item)
self.setItem(m, n, newitem)
您可以为表提供初始数据,但您还需要将其设置为将来的数据库提取更新。在这里,我们只需将计时器连接到更新本地数据的方法,然后刷新您正在使用的各种视图,包括表格。
Table现在有一个方法可以接受dict,并更新自己的内部数据结构。
这种方法的一个细微变化就是在信号中发出新的数据结构,并在窗口中本地数据结构发生变化时触发...
class Window(QtGui.QDialog):
update_ready = QtCore.pyqtSignal(dict)
def __init__(self,parent=None):
...
# call a generate update and emit wrapper
self.timer_status.timeout.connect(self.refreshData)
# connect each view with a slot that expects a dict
self.update_ready.connect(self.table1.updateFromDict)
...
def refreshData(self):
new_data = self.get_data_status()
self.update_ready.emit(new_data)
在这个例子中,您只需让信号将新数据结构传递到需要dict的插槽上的视图(来自前面的示例)。
答案 1 :(得分:0)
这里有一些事情发生:
无论如何,我不是百分之百确定你要做什么 - 但我希望有所帮助!