在pyqt4滚动区域python中显示长循环函数

时间:2012-07-20 15:08:41

标签: python pyqt pyqt4

我正在设计一个GUI,作为GUI的一部分,我希望以特殊方式检索数据并将其显示在scrollarea上。但是我不知道怎么做,我已经将数据库检索功能定义为cpu_alert,但是如何将结果(行)放在滚动区域?请看一下代码。

from PyQt4 import QtCore, QtGui
import ui_intex_server_monitorui as intex
from PyQt4 import Qt
import sys
import os
import MySQLdb as mdb

class MyMain(QtGui.QMainWindow, intex.Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMain, self).__init__(parent)
        self.setupUi(self)  

        #Exit Button
        self.connect(self.pushButton_2, QtCore.SIGNAL('clicked()'),
            self.close)
        #Refresh Button here#
        self.testdata = QtGui.QListWidget(self)
        layout = self.scrollArea_10
        layout.setWidget(self.testdata)
        self.testdata.addItem(self.cpu_alert.rows)

def cpu_alert():
    control = True

    while (control == True):

        f = open("connection_cpu.txt","r")
        a = f.read()
        con = mdb.connect('server', 'user', 'pass', 'db')

        if a == "CPU Overload":
            with con: 
                cur = con.cursor()
                cur.execute("""SELECT *
                               FROM cpu_alert
                               WHERE date = (SELECT MAX(date) FROM cpu_alert)""")
                rows = str(cur.fetchone())
                rows = rows.strip("()" "''")
                open("connection_cpu.txt","w").close()
      return rows


def main():
   app = QtGui.QApplication(sys.argv)
   app.setStyle(QtGui.QStyleFactory.create("plastique"))
   main_window = MyMain()
   main_window.show()
   app.exec_()

if __name__ == '__main__':
   main()

1 个答案:

答案 0 :(得分:0)

首先让我先谈谈你是如何检查是否有可用的新更新。如果您要调用此cpu_alert方法,则应在主线程中输入busy循环并阻止大部分GUI功能。此外,没有任何限制这个繁忙的循环,所以它会在你的文件上极快地旋转。假设检查文件中的内容是您打算使用的方法,它需要在一个单独的线程中。线程将循环文件并睡眠合理的数量。如果它找到了所需的文本,那么它就会发出信号。然后,此信号将连接到更新表格的插槽。

但是让我们保持这个更简单,因为您要检查的所有内容都会快速读取文件。因为它不需要太多时间,我们可以使用QTimer。计时器将触发并调用检查器。如果检查器找到并更新它,可以直接调用表更新或使其更强大,只需发出信号。

这是一个完整的例子,我将在之后分解:

from PyQt4 import QtGui, QtCore, QtSql
import time

class Window(QtGui.QDialog):

    update_ready = QtCore.pyqtSignal()

    def __init__(self):
        super(Window, self).__init__()

        self.layout = QtGui.QVBoxLayout(self)
        self.table = QtGui.QTableView()
        self.layout.addWidget(self.table)

        self.db = QtSql.QSqlDatabase.addDatabase("QMYSQL")
        self.db.setHostName("server")
        self.db.setDatabaseName("db")
        self.db.setUserName("user")
        self.db.setPassword("pass")
        self.db.open()

        self.model = QtSql.QSqlTableModel(self, self.db)
        self.model.setTable("cpu_alert")
        self.model.setEditStrategy(self.model.OnManualSubmit)
        self.model.setQuery(QtSql.QSqlQuery("""
            SELECT *
            FROM cpu_alert
            WHERE date = (SELECT MAX(date) FROM cpu_alert)"""))
        self.model.select()

        self.table.setModel(self.model)

        self.button = QtGui.QPushButton("Select")
        self.layout.addWidget(self.button)

        self.button.clicked.connect(self.model.select)
        self.update_ready.connect(self.model.select)

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.cpu_alert_checker)
        # check every second
        self.timer.start(1000*1)

        # this is only for the temp time test
        self._now = time.time()

    def cpu_alert_checker(self):
        # You would do whatever check you want 
        # in this function
        if time.time() - self._now > 5:
            print "Update ready!"
            # emit this signal if the table should refresh
            self.update_ready.emit()
            self._now = time.time()

您可以使用内置的QSql创建自动驱动表的模型,而不需要执行原始驱动程序查询。有许多选项可用于设置表和模型应如何显示每一行。但我离开它非常基本。

我创建了一个按钮并将其连接到sql模型上的select()。我还创建了QTimer,并将其超时设置为调用cpu_alert_checker()。我们启动计时器,以便它每秒都会触发。您可以根据自己的喜好调整速度。

当超时触发时,cpu_alert_checker中的代码将运行。我只是在那里放一个计时器作为占位符,使测试更容易看到。当时间超过5秒时,它将触发并重置。您看到我们已经定义了一个名为update_ready的自定义信号。我们可以发射,并连接到那。它使您的检查器更加健壮,因为它不必直接了解它的能力。它可以通知您的应用程序已准备就绪。

我希望这个例子可以帮助你。我认为以这种方式管理要容易得多。如果你的检查员做了很多繁重的工作,那么就需要将它移到QThread来阻止主线程。