简体   繁体   English

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

[英]Displaying a long loop function in pyqt4 scroll area python

I am designing a GUI and as part of the GUI I want to retrieve data in a special way and display it on the scrollarea. 我正在设计一个GUI,并且作为GUI的一部分,我想以一种特殊的方式检索数据并将其显示在滚动区域上。 However I am not sure how to do that, I have defined the database retrieval function as cpu_alert, however how do I put the result (rows) in the scroll area? 但是我不确定该怎么做,我已将数据库检索功能定义为cpu_alert,但是如何将结果(行)放在滚动区域中? Please take a look at the code. 请看一看代码。

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()

First let me start by addressing how you are checking to see if there is a new update available. 首先,让我开始讨论您如何检查是否有新的更新。 If you were to call this cpu_alert method, you would enter a busy loop in the main thread and block much of your GUI functionality. 如果要调用此cpu_alert方法,则将在主线程中进入繁忙循环,并阻止许多GUI功能。 Furthermore, there is nothing limiting this busy loop so it will spin extremely fast on your file. 此外,没有任何限制此繁忙循环的功能,因此它将在文件上快速旋转。 Assuming checking the file for content is the approach you intend to use, it needs to be in a separate thread. 假设检查文件内容是您打算使用的方法,则需要将其放在单独的线程中。 The thread will loop on the file and sleep a reasonable amount. 线程将在文件上循环并休眠合理的时间。 If it finds the text it needs, then it can emit a signal. 如果找到所需的文本,则可以发出信号。 This signal would then connect to the slot that updates your table. 然后,该信号将连接到更新表的插槽。

But lets keep this even simpler, since all you are doing to check is quickly read a file. 但是,让它变得更加简单,因为您要检查的所有内容都是快速读取文件。 Because it does not take much time, we can use a QTimer. 因为不需要花费很多时间,所以我们可以使用QTimer。 The timer will fire and call the checker. 计时器将触发并致电检查程序。 If the checker finds and update it can either call the table update directly or to make it more robust you just emit a signal. 如果检查器找到并更新了它,则可以直接调用表更新,或者使其更健壮,您只需发出一个信号即可。

Here is a complete example which I will break down afterwards: 这是一个完整的示例,之后我将对其进行细分:

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()

Instead of needing to do the raw driver query, you can use the built in QSql to create a model that automatically drives your table. 无需执行原始驱动程序查询,您可以使用内置的QSql创建自动驱动表的模型。 There are a bunch of options to set how the table and model should show each row. 有很多选项可以设置表格和模型应如何显示每一行。 But I am leaving it pretty basic. 但我将其保留为基本内容。

I create a button and connect it to the select() on the sql model. 我创建一个按钮并将其连接到sql模型上的select()。 I also create the QTimer, and set its timeout to call your cpu_alert_checker(). 我还创建了QTimer,并将其超时设置为调用您的cpu_alert_checker()。 We start the timer so that every second it will fire. 我们启动计时器,以便每秒钟触发一次。 You can adjust this speed to your taste. 您可以根据自己的喜好调整此速度。

When the timeout fires, the code in the cpu_alert_checker runs. 当超时触发时,cpu_alert_checker中的代码将运行。 I simply put a time counter in there as a place holder to make testing easier to see. 我只是在其中放置一个时间计数器作为占位符,以使测试更易于查看。 When the time passes 5 seconds it will fire and reset. 时间过了5秒钟,它将启动并重置。 You see we have defined a custom signal called update_ready. 您会看到我们已经定义了一个称为update_ready的自定义信号。 We can emit on that, and connect to that. 我们可以对此进行发射,并与之连接。 It makes your checker more robust because it doesn't have to directly know about that able. 它使您的检查器更加强大,因为它不必直接知道该功能。 It can just notify your app that something is ready. 它可以仅通知您的应用程序已准备就绪。

I hope this example helps you out. 我希望这个例子能对您有所帮助。 It is a lot easier to manage this way I think. 我认为以这种方式进行管理要容易得多。 If your checker were doing a lot more heavy work, it would need to be moved to a QThread to not block the main thread. 如果您的检查器正在做很多繁重的工作,则需要将其移动到QThread上以免阻塞主线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM