0

我正在设计一个 GUI,作为 GUI 的一部分,我想以一种特殊的方式检索数据并将其显示在滚动区域上。但是我不知道该怎么做,我已将数据库检索功能定义为 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()
4

1 回答 1

0

首先让我先谈谈您如何检查是否有可用的新更新。如果您要调用此cpu_alert方法,您将在主线程中进入一个繁忙的循环并阻塞您的大部分 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 以不阻塞主线程。

于 2012-07-21T19:36:08.837 回答