动态更新标签/按钮文本

Posted

技术标签:

【中文标题】动态更新标签/按钮文本【英文标题】:Update Labels/Button Texts dynamically 【发布时间】:2020-09-15 20:37:20 【问题描述】:

我使用 PyQt 设计器创建了这个 .ui 文件,我通过第二个脚本调用它(它也有一些数据处理)我如何制作 QPushButton,即 Confirmed、Active、Recovered 和 Deaths(旁边的数字它只是一个占位符,我想将它们更新为从主脚本处理的数据)尝试将其转换为 .py 无法弄清楚。

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>COVID19_Updater</class>
 <widget class="QMainWindow" name="COVID19_Updater">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>917</width>
    <height>615</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <property name="styleSheet">
   <string notr="true">background-color: rgb(5, 25, 55);</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QFrame" name="frame">
      <property name="maximumSize">
       <size>
        <width>16777215</width>
        <height>16777215</height>
       </size>
      </property>
      <property name="styleSheet">
       <string notr="true">QFrame
    
    
    background-color: rgb(5, 25, 55);

    border-radius: 10px
</string>
      </property>
      <property name="frameShape">
       <enum>QFrame::StyledPanel</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Raised</enum>
      </property>
      <widget class="QLabel" name="Title">
       <property name="geometry">
        <rect>
         <x>-10</x>
         <y>20</y>
         <width>921</width>
         <height>61</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Segoe UI</family>
         <pointsize>25</pointsize>
        </font>
       </property>
       <property name="styleSheet">
        <string notr="true">color: rgb(3, 122, 245);
lable.adjustSize();</string>
       </property>
       <property name="text">
        <string>&lt;strong&gt;COVID-19&lt;/strong&gt; &lt;i&gt;LIVE&lt;/i&gt;</string>
       </property>
       <property name="alignment">
        <set>Qt::AlignCenter</set>
       </property>
      </widget>
      <widget class="QLabel" name="Description">
       <property name="geometry">
        <rect>
         <x>-10</x>
         <y>70</y>
         <width>921</width>
         <height>61</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Segoe UI</family>
         <pointsize>10</pointsize>
        </font>
       </property>
       <property name="styleSheet">
        <string notr="true">color: rgb(190, 191, 196);</string>
       </property>
       <property name="text">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Realtime COVID-19 status of all Countries including &lt;span style=&quot; font-weight:600;&quot;&gt;Indian&lt;/span&gt; States and Districts&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
       <property name="textFormat">
        <enum>Qt::MarkdownText</enum>
       </property>
       <property name="alignment">
        <set>Qt::AlignCenter</set>
       </property>
       <property name="wordWrap">
        <bool>true</bool>
       </property>
      </widget>
      <widget class="QPushButton" name="CheckData">
       <property name="geometry">
        <rect>
         <x>300</x>
         <y>190</y>
         <width>281</width>
         <height>61</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Segoe UI Emoji</family>
         <pointsize>15</pointsize>
         <weight>50</weight>
         <bold>false</bold>
        </font>
       </property>
       <property name="focusPolicy">
        <enum>Qt::StrongFocus</enum>
       </property>
       <property name="layoutDirection">
        <enum>Qt::LeftToRight</enum>
       </property>
       <property name="styleSheet">
        <string notr="true">background-color: rgba(0, 122, 255,50);

color: rgb(3, 122, 245);
border-radius: 30px;

</string>
       </property>
       <property name="text">
        <string>Check Live Data</string>
       </property>
       <property name="checkable">
        <bool>false</bool>
       </property>
      </widget>
      <widget class="QLabel" name="AuthorName">
       <property name="geometry">
        <rect>
         <x>730</x>
         <y>570</y>
         <width>161</width>
         <height>21</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Segoe UI</family>
         <pointsize>8</pointsize>
        </font>
       </property>
       <property name="cursor">
        <cursorShape>IBeamCursor</cursorShape>
       </property>
       <property name="styleSheet">
        <string notr="true">color: rgba(190, 191, 196,95);</string>
       </property>
       <property name="text">
        <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Created by: &lt;span style=&quot; font-style:italic;&quot;&gt;Sumukh Jadhav&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
       </property>
       <property name="textFormat">
        <enum>Qt::MarkdownText</enum>
       </property>
       <property name="alignment">
        <set>Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing</set>
       </property>
       <property name="wordWrap">
        <bool>true</bool>
       </property>
       <property name="textInteractionFlags">
        <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
       </property>
      </widget>
      <widget class="QPushButton" name="UpdataData">
       <property name="geometry">
        <rect>
         <x>300</x>
         <y>290</y>
         <width>281</width>
         <height>61</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Segoe UI Emoji</family>
         <pointsize>15</pointsize>
         <weight>50</weight>
         <italic>false</italic>
         <bold>false</bold>
         <underline>false</underline>
         <strikeout>false</strikeout>
        </font>
       </property>
       <property name="focusPolicy">
        <enum>Qt::StrongFocus</enum>
       </property>
       <property name="layoutDirection">
        <enum>Qt::LeftToRight</enum>
       </property>
       <property name="styleSheet">
        <string notr="true">background-color: rgba(0, 122, 255,50);

color: rgb(3, 122, 245);
border-radius: 30px;

</string>
       </property>
       <property name="text">
        <string>Update Status</string>
       </property>
       <property name="checkable">
        <bool>false</bool>
       </property>
      </widget>
      <widget class="QPushButton" name="Confirmed">
       <property name="geometry">
        <rect>
         <x>20</x>
         <y>460</y>
         <width>201</width>
         <height>81</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Helvetica LT Std</family>
         <pointsize>15</pointsize>
         <weight>75</weight>
         <italic>false</italic>
         <bold>true</bold>
         <underline>false</underline>
         <strikeout>false</strikeout>
         <kerning>true</kerning>
        </font>
       </property>
       <property name="focusPolicy">
        <enum>Qt::StrongFocus</enum>
       </property>
       <property name="layoutDirection">
        <enum>Qt::LeftToRight</enum>
       </property>
       <property name="styleSheet">
        <string notr="true">
background-color: rgba(112,108,195,50);

color: rgb(112,108,195);


</string>
       </property>
       <property name="text">
        <string>Confirmed
 2,94,59,649</string>
       </property>
       <property name="checkable">
        <bool>false</bool>
       </property>
      </widget>
      <widget class="QPushButton" name="Active">
       <property name="geometry">
        <rect>
         <x>240</x>
         <y>460</y>
         <width>201</width>
         <height>81</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Helvetica LT Std</family>
         <pointsize>15</pointsize>
         <weight>75</weight>
         <italic>false</italic>
         <bold>true</bold>
         <underline>false</underline>
         <strikeout>false</strikeout>
        </font>
       </property>
       <property name="focusPolicy">
        <enum>Qt::StrongFocus</enum>
       </property>
       <property name="layoutDirection">
        <enum>Qt::LeftToRight</enum>
       </property>
       <property name="styleSheet">
        <string notr="true">
background-color: rgba(238, 14, 63,50);

color: rgb(238, 14, 63);


</string>
       </property>
       <property name="text">
        <string>Active
 72,41,136</string>
       </property>
       <property name="checkable">
        <bool>false</bool>
       </property>
      </widget>
      <widget class="QPushButton" name="Recovered">
       <property name="geometry">
        <rect>
         <x>460</x>
         <y>460</y>
         <width>201</width>
         <height>81</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Helvetica LT Std</family>
         <pointsize>15</pointsize>
         <weight>75</weight>
         <italic>false</italic>
         <bold>true</bold>
         <underline>false</underline>
         <strikeout>false</strikeout>
        </font>
       </property>
       <property name="focusPolicy">
        <enum>Qt::StrongFocus</enum>
       </property>
       <property name="layoutDirection">
        <enum>Qt::LeftToRight</enum>
       </property>
       <property name="styleSheet">
        <string notr="true">background-color: rgba(46, 155, 80,50);
color: rgb(42, 160, 79);


</string>
       </property>
       <property name="text">
        <string>Recovered
 2,12,92,324</string>
       </property>
       <property name="checkable">
        <bool>false</bool>
       </property>
      </widget>
      <widget class="QPushButton" name="Deaths">
       <property name="geometry">
        <rect>
         <x>680</x>
         <y>460</y>
         <width>201</width>
         <height>81</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Helvetica LT Std</family>
         <pointsize>15</pointsize>
         <weight>75</weight>
         <italic>false</italic>
         <bold>true</bold>
         <underline>false</underline>
         <strikeout>false</strikeout>
        </font>
       </property>
       <property name="focusPolicy">
        <enum>Qt::StrongFocus</enum>
       </property>
       <property name="layoutDirection">
        <enum>Qt::LeftToRight</enum>
       </property>
       <property name="styleSheet">
        <string notr="true">background-color: rgba(110, 116, 128,50);
color: rgb(110, 114, 126);

</string>
       </property>
       <property name="text">
        <string>Deaths
 9,33,150</string>
       </property>
       <property name="checkable">
        <bool>false</bool>
       </property>
      </widget>
      <widget class="QPushButton" name="UpdataData_2">
       <property name="geometry">
        <rect>
         <x>300</x>
         <y>420</y>
         <width>281</width>
         <height>31</height>
        </rect>
       </property>
       <property name="font">
        <font>
         <family>Gravity</family>
         <pointsize>13</pointsize>
         <weight>75</weight>
         <italic>true</italic>
         <bold>true</bold>
         <underline>false</underline>
         <strikeout>false</strikeout>
        </font>
       </property>
       <property name="focusPolicy">
        <enum>Qt::StrongFocus</enum>
       </property>
       <property name="layoutDirection">
        <enum>Qt::LeftToRight</enum>
       </property>
       <property name="styleSheet">
        <string notr="true">

color: rgb(169, 206, 244);
border-radius: 30px;

</string>
       </property>
       <property name="text">
        <string>Current World Data</string>
       </property>
       <property name="checkable">
        <bool>false</bool>
       </property>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

主脚本


from PyQt5 import QtWidgets, uic
import sys
from bs4 import BeautifulSoup
import requests
import re

url = 'https://www.worldometers.info/coronavirus/'
page = requests.get(url)
soup = BeautifulSoup(page.content, 'html.parser')

class Ui(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui, self).__init__()
        uic.loadUi('AutoSize.ui', self)
        self.show()


app = QtWidgets.QApplication(sys.argv)
window = Ui()
app.exec_()

data = []

for x in range(0, 3):
    x = soup.find_all(class_ = 'maincounter-number')[x].find('span').text
    data.append(x)

Active = int((re.sub("[],]","", data[0]))) - (int((re.sub("[],]","", data[1]))) + int((re.sub("[],]","", data[2]))))

res = ":,".format(Active)


con = data[0]
det = data[1]
rec = data[2]
act = str(res)

【问题讨论】:

【参考方案1】:

获取信息的任务非常耗时,所以不应该在主线程中执行,而是在辅助线程中执行,并通过信号发送信息。 OP 没有明确描述它应该在什么事件之前更新,所以在我的示例中,我将使用 QTimer 每 T 秒更新一次:

import sys
import threading

from PyQt5 import QtCore, QtWidgets, uic

from bs4 import BeautifulSoup
import requests


class Scrapper(QtCore.QObject):
    dataChanged = QtCore.pyqtSignal(tuple)

    def start(self):
        threading.Thread(target=self._execute, daemon=True).start()

    def _execute(self):
        url = "https://www.worldometers.info/coronavirus/"
        page = requests.get(url)
        soup = BeautifulSoup(page.content, "html.parser")

        data = []

        for e in soup.find_all(class_="maincounter-number"):
            value = int(e.find("span").text.strip().replace(",", ""))
            data.append(value)

        total, deaths, recovered = data
        active = total - deaths - recovered

        self.dataChanged.emit((total, deaths, recovered, active))


class Ui(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui, self).__init__()
        uic.loadUi("AutoSize.ui", self)

        self.s = Scrapper()
        self.s.dataChanged.connect(self.update_data)
        self.s.start()

    @QtCore.pyqtSlot(tuple)
    def update_data(self, data):
        total, deaths, recovered, active = data

        self.Confirmed.setText("Confirmed\n:,".format(total))
        self.Active.setText("Active\n:,".format(active))
        self.Recovered.setText("Recovered\n:,".format(recovered))
        self.Deaths.setText("Deaths\n:,".format(deaths))

        QtCore.QTimer.singleShot(2 * 1000, self.s.start)


def main():
    app = QtWidgets.QApplication(sys.argv)

    window = Ui()
    window.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

【讨论】:

这段代码显示 ValueError: invalid literal for int() with base 10: '29,675,950' 我想将总数、死亡、活跃和恢复到 UI 中 是的,只是再次复制粘贴整个内容,同样的错误 :( 声明数据时似乎是个问题 = [] 如果你不介意,你能给我解释一下这里发生了什么吗?这是我第一次使用 UI @SumukhJadhav 我的回答清楚地解释了我实现的内容,我认为您并不完全理解,因为它是 这是我第一次使用 UI,不幸的是我和我都不是导师们,我建议你复习教程,再见。

以上是关于动态更新标签/按钮文本的主要内容,如果未能解决你的问题,请参考以下文章

动态更新标签

Kivy 更新动态标签文本

动态更新 Extjs autoEl :'button' 文本和 css

UWP Windows10开发更新磁贴和动态更新磁贴

动态 TextView 未在片段中更新

TextField 没有动态更新