【问题标题】:QtButton and Qtimer in pythonpython中的QtButton和Qtimer
【发布时间】:2016-04-08 17:23:21
【问题描述】:

就代码而言,我几乎将这段代码放在了我想要的地方。我希望每分钟刷新一次此脚本,并且还有一个手动刷新的按钮。该按钮已经存在,但似乎没有按预期工作。我希望它重绘或刷新小部件中的信息。

按键代码:

bottom2 = QtGui.QPushButton("Refresh") 
#bottom2.setFrameShape(QtGui.QFrame.StyledPanel)
#bottom2.setWordWrap(True)
bottom2.clicked.connect(InfoCenter)

定时器代码:

timer = QtCore.QTimer()
QtCore.QTimer.connect(timer, QtCore.SIGNAL("timeout()"), self, QtCore.SLOT("func()"))
timer.start(6000)

完整代码:

 import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt, QTimer
from PyQt4.QtGui import QWidget, QApplication, QSplitter, QLabel, QVBoxLayout, QColor, QPixmap, QIcon
import Adafruit_DHT
import urllib2
from wunderground import high_0, low_0, conditions_0
from BeautifulSoup import BeautifulSoup

sensor_args = { '11': Adafruit_DHT.DHT11,
                '22': Adafruit_DHT.DHT22,
                '2302': Adafruit_DHT.AM2302 }

humidity, temperature = Adafruit_DHT.read_retry(11, 4)


temp = 'Temp={0:0.1f}*  Humidity={1:0.1f}%'.format(temperature, humidity)

soup = BeautifulSoup(urllib2.urlopen('http://partner.mlb.com/partnerxml/gen/news/rss/bos.xml').read())

title = soup.find('item').title
desc = soup.find('item').description
url = soup.find('item').guid



temperature = temperature * 9/5.0 + 32




class InfoCenter(QtGui.QWidget):

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

        self.initUI()

    def initUI(self):      

        hbox = QtGui.QHBoxLayout(self)


        self.outsidetemp = QLabel("Todays High:{}\nTodays Low:{}\nConditions:{}".format(high_0,low_0,conditions_0),self)
        self.outsidetemp.setFrameShape(QtGui.QFrame.StyledPanel)


        self.insidetemp = QLabel('Temperature:{:0.1f}F\nHumidity:{:0.1f}%'.format(temperature,humidity),self )
        self.insidetemp.setFrameShape(QtGui.QFrame.StyledPanel)

        self.mlbnews = QLabel("Redsox News \nTitle: %s\nSummary: %s " % (title.text, desc.text), self) 
        self.mlbnews.setFrameShape(QtGui.QFrame.StyledPanel)
        self.mlbnews.setWordWrap(True)

        self.button = QtGui.QPushButton("Refresh") 
        self.button.clicked.connect(InfoCenter)

        splitter1 = QtGui.QSplitter(QtCore.Qt.Horizontal)
        splitter1.addWidget(outsidetemp)
        splitter1.addWidget(insidetemp)

        splitter2 = QtGui.QSplitter(QtCore.Qt.Vertical)
        splitter2.addWidget(splitter1)
        splitter2.addWidget(mlbnews)
        splitter2.addWidget(button)


        hbox.addWidget(splitter2)
        self.setLayout(hbox)
        QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Cleanlooks'))

        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('QtGui.QSplitter')
        self.show()

        #color widget code
        palette = self.palette()
        role = self.backgroundRole()
        palette.setColor(role, QColor('black'))
        self.setPalette(palette)
        outsidetemp.setStyleSheet("QLabel {color:yellow}")
        insidetemp.setStyleSheet("QLabel {color:yellow}")
        mlbnews.setStyleSheet("QLabel {background-color: black; color:white}")

@QtCore.pyqtSlot()
def refreshLabels(self):
    self.outsidetemp.setText('Temperature:{:0.1f}F\nHumidity:{:0.1f}%'.format(temperature,humidity),self )

    timer = QtCore.QTimer()
    self.timer.timeout.connect(self.refreshLabels)    
    timer.start(5000)
    print 'done'




def main():

    app = QtGui.QApplication(sys.argv)
    ex = InfoCenter()
    app.exec_()    


if __name__ == '__main__':
    main()  

更新代码

【问题讨论】:

  • “不工作”是什么意思?没发生什么事?更具体。
  • InfoCenter 中不是缺少funct() 插槽吗?定时器触发时会调用什么?另外,在插槽上,button.clicked.connect(InfoCenter) 不会创建另一个InfoCenter 实例吗?这是故意的吗?
  • 另外,您正在创建一堆QFrames,然后立即创建另一个具有完全相同名称的小部件。所有这些QFrames 都没有添加到任何布局中。
  • 不,这不是故意的。我已经纠正了这个问题。但似乎还是不清爽。我认为我的问题是,当应用程序加载时,它会提取数据并将其存储在变量中,但是当计时器刷新时,它只会刷新已经存储的全局变量。如果我错了,请纠正我。
  • 是的,您将一个字符串传递给QLabel 构造函数。当您刷新它时,它不会再次重新计算字符串。您需要创建一个刷新函数来重新计算字符串。

标签: python qt pyqt pyqt4


【解决方案1】:

首先,您需要存储对小部件的引用(注意 self

self.outsidetemp = QLabel(...)

您可能应该为所有小部件执行此操作,具体取决于您运行的对象和环境,不存储对小部件的 python 引用可能会导致它被垃圾收集,并且您可能会出错。

您还可以使用更简洁的新型信号语法

self.timer.timeout.connect(self.refreshLabels)

然后创建一个将更新标签的函数,将timeout 信号连接到该函数。

@QtCore.pyqtSlot()
def refreshLabels(self):
    self.outsidetemp.setText("Todays High:{}\nTodays Low:{}\nConditions:{}".format(high_0,low_0,conditions_0))

我还将添加强制性警告,即在此处使用全局变量可能不是最好的方法。你如何更新全局变量?为什么不使用 QTimer,而让更新全局变量的进程更新小部件?

【讨论】:

  • 好的,谢谢。我添加了这个@QtCore.pyqtSlot() def refreshLabels(self): self.outsidetemp.setText("Todays High:{}\nTodays Low:{}\nConditions:{}".format(high_0,low_0,conditions_0)) timer = QtCore.QTimer() QtCore.QTimer.connect(timer, QtCore.SIGNAL("timeout()"), self, QtCore.pyqtSlot("func()")) timer.start(5000) print 'done' This没有按预期工作。
  • 你添加的不是我在回答中写的。
  • 此外,“未按预期工作”并不能告诉我们太多信息。如果您描述您期望发生的事情以及实际发生的事情会更有帮助。
  • 我添加了打印完成,所以我知道它什么时候运行。除了你写的复制/粘贴
  • 这很难说,因为 cmets 中的代码格式化并不能真正起作用。此外,您仍在使用旧的计时器连接代码,而不是将其连接到 refreshLabels
猜你喜欢
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多