根据另一个 class 上的变量值设置 Qlabel 文本
setting a Qlabel text according to a variable's value on another class
我正在为与多个传感器交互的 raspberry pi 创建一个 GUI。我需要 GUI 来显示这些值。为此,我使用 QT 创建主要的 window/UI,然后使用 pyuic5 将结果转换为 python,以开发 python 上的所有其他内容,包括实时电流图(可能在同一图或其他图上添加几条其他曲线)。话虽如此,我有点坚持为我一直在测试的 Qlabel 设置文本。我认为更改该文本的最佳方法是使用信号和槽(而且我确定我会在其他事件中需要这些知识)。
这是我的 UI 在 运行 pyuic5 之后:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1075, 622)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralWidget)
self.gridLayout.setContentsMargins(11, 11, 11, 11)
self.gridLayout.setSpacing(6)
self.gridLayout.setObjectName("gridLayout")
self.lblSolar = QtWidgets.QLabel(self.centralWidget)
self.lblSolar.setObjectName("lblSolar")
self.gridLayout.addWidget(self.lblSolar, 3, 1, 1, 1)
self.progressBar = QtWidgets.QProgressBar(self.centralWidget)
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.gridLayout.addWidget(self.progressBar, 4, 0, 1, 1)
self.progressBar_2 = QtWidgets.QProgressBar(self.centralWidget)
self.progressBar_2.setProperty("value", 24)
self.progressBar_2.setObjectName("progressBar_2")
self.gridLayout.addWidget(self.progressBar_2, 4, 1, 1, 1)
self.btnSelectSol = QtWidgets.QPushButton(self.centralWidget)
self.btnSelectSol.setStyleSheet("background-color: rgb(114, 159, 207);")
self.btnSelectSol.setObjectName("btnSelectSol")
self.gridLayout.addWidget(self.btnSelectSol, 1, 3, 1, 1)
self.btnSelectBat = QtWidgets.QPushButton(self.centralWidget)
self.btnSelectBat.setStyleSheet("background-color: rgb(114, 159, 207);")
self.btnSelectBat.setObjectName("btnSelectBat")
self.gridLayout.addWidget(self.btnSelectBat, 2, 3, 1, 1)
self.lblBattery = QtWidgets.QLabel(self.centralWidget)
self.lblBattery.setObjectName("lblBattery")
self.gridLayout.addWidget(self.lblBattery, 3, 0, 1, 1)
self.btnON = QtWidgets.QPushButton(self.centralWidget)
self.btnON.setObjectName("btnON")
self.gridLayout.addWidget(self.btnON, 4, 3, 1, 1)
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
self.verticalLayout.setContentsMargins(11, 11, 11, 11)
self.verticalLayout.setSpacing(6)
self.verticalLayout.setObjectName("verticalLayout")
self.lblCSTitle = QtWidgets.QLabel(self.centralWidget)
self.lblCSTitle.setAlignment(QtCore.Qt.AlignCenter)
self.lblCSTitle.setObjectName("lblCSTitle")
self.verticalLayout.addWidget(self.lblCSTitle)
self.lblCSStatus = QtWidgets.QLabel(self.centralWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lblCSStatus.sizePolicy().hasHeightForWidth())
self.lblCSStatus.setSizePolicy(sizePolicy)
self.lblCSStatus.setAutoFillBackground(False)
self.lblCSStatus.setAlignment(QtCore.Qt.AlignCenter)
self.lblCSStatus.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
self.lblCSStatus.setObjectName("lblCSStatus")
self.verticalLayout.addWidget(self.lblCSStatus)
self.gridLayout.addLayout(self.verticalLayout, 0, 3, 1, 1)
self.widget = CustomPlot(self.centralWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())
self.widget.setSizePolicy(sizePolicy)
self.widget.setObjectName("widget")
self.gridLayout.addWidget(self.widget, 0, 0, 3, 3)
MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 1075, 26))
self.menuBar.setObjectName("menuBar")
self.menuHelp = QtWidgets.QMenu(self.menuBar)
self.menuHelp.setObjectName("menuHelp")
self.menuData = QtWidgets.QMenu(self.menuBar)
self.menuData.setObjectName("menuData")
MainWindow.setMenuBar(self.menuBar)
self.mainToolBar = QtWidgets.QToolBar(MainWindow)
self.mainToolBar.setObjectName("mainToolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
self.statusBar = QtWidgets.QStatusBar(MainWindow)
self.statusBar.setObjectName("statusBar")
MainWindow.setStatusBar(self.statusBar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.actionGuide = QtWidgets.QAction(MainWindow)
self.actionGuide.setObjectName("actionGuide")
self.actionAbout = QtWidgets.QAction(MainWindow)
self.actionAbout.setObjectName("actionAbout")
self.actionExport = QtWidgets.QAction(MainWindow)
self.actionExport.setObjectName("actionExport")
self.menuHelp.addAction(self.actionGuide)
self.menuHelp.addAction(self.actionAbout)
self.menuData.addAction(self.actionExport)
self.menuBar.addAction(self.menuHelp.menuAction())
self.menuBar.addAction(self.menuData.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Power System Monitor"))
self.lblSolar.setText(_translate("MainWindow", "Solar Panel"))
self.btnSelectSol.setText(_translate("MainWindow", "Power from Solar Panel"))
self.btnSelectBat.setText(_translate("MainWindow", "Power from Battery"))
self.lblBattery.setText(_translate("MainWindow", "Battery"))
self.btnON.setText(_translate("MainWindow", "EXIT"))
self.lblCSTitle.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:16pt; font-weight:600;\">Pi Charge System</span></p></body></html>"))
self.lblCSStatus.setText(_translate("MainWindow", "TextLabel"))
self.menuHelp.setTitle(_translate("MainWindow", "Help"))
self.menuData.setTitle(_translate("MainWindow", "Data"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.actionGuide.setText(_translate("MainWindow", "Guide"))
self.actionAbout.setText(_translate("MainWindow", "About"))
self.actionExport.setText(_translate("MainWindow", "Export"))
from Plotter import CustomPlot
这是我的 Plotter.py 文件:
import sys
import os
os.environ['PYQTGRAPH_QT_LIB']='PyQt5' #force pyqtgraph to use pyqt5
import pyqtgraph as pg
import PyQt5
from pyqtgraph.Qt import QtCore, QtGui
#import numpy as np #np is used for testing plot curves
#from ina219 import INA219, DeviceRangeError #sensory library
from time import sleep
from PyQt5.QtCore import Qt, pyqtSignal
from random import randrange
#SHUNT_OHMS = 0.1
#MAX_EXPECTED_AMPS = 1.0 #2.0
#ina = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS)
#ina.configure(ina.RANGE_16V)
class CustomPlot(pg.GraphicsWindow):
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
ptr1 = 0
chargeflag = "start"
#Added a signal
changedValue = pyqtSignal(str)
def __init__(self, parent=None, **kargs):
global chargeflag #variable to emit signal on change
pg.GraphicsWindow.__init__(self, **kargs)
#self.setParent(parent)
p1 = self.addPlot(labels = {'left':'Current (mA)', 'bottom':'Time(secs)'}, xRange=[0,5])
p1.showGrid(x=True, y=True)
p1.setYRange(3.4,4.6)
p1.addLegend()
#self.data1 = np.random.normal(size=10)
#print(self.data1)
self.data1 = []
for n in range(10):
#self.data1.append(ina.current()) #get actual data1 from sensor
self.data1.append(randrange(3,5))
sleep(1)
#print(self.data1)
#print(ina.current())
#self.data1 = ina.voltage
#self.data2 = np.random.normal(size=10)
self.curve1 = p1.plot(self.data1, pen='r', width=25, name='Battery')
#self.curve2 = p1.plot(self.data2, pen=(2,3))
timer = pg.QtCore.QTimer(self)
timer.timeout.connect(self.update)
#timer.timeout.connect(ina.current)
timer.start(1000) # number of seconds (every 1000) for next update
#setting a connection between chargeflag change and on_changed_value function
self.chargeflag.valueChanged.connect(self.on_changed_value)
def update(self):
#global chargeflag
self.data1[:-1] = self.data1[1:] # shift data in the array one sample left (see also: np.roll)
#self.data1[-1] = np.random.normal()
#self.data1[-1] = ina.current() #actual value from sensor
self.data1[-1] = randrange(3.5,4.5)
if self.data1[-1] < 4: #if that should send signal to update Qlabel
self.chargeflag = "solar"
else:
self.chargeflag = 'battery'
print(self.chargeflag)
self.ptr1 += 1
self.curve1.setData(self.data1)
self.curve1.setPos(self.ptr1, 0)
#self.data2[:-1] = self.data2[1:] # shift data in the array one sample left
# (see also: np.roll)
#self.data2[-1] = np.random.normal()
#self.curve2.setData(self.data2)
#self.curve2.setPos(self.ptr1,0)
self.changeflag.changedValue.connect(self.on_changed_value)
#function for other objects from other classes to listen to
def on_changed_value(self, value):
self.changedValue.emit(value)
if __name__ == '__main__':
w = CustomPlot()
w.show()
QtGui.QApplication.instance().exec_()
最后是我的 main.py 文件:
import PyQt5
from PyQt5.QtWidgets import *
import sys
import Powdesign
from PyQt5.QtCore import QCoreApplication, pyqtSlot
from Plotter import CustomPlot
from time import sleep
class Powapp(QMainWindow, Powdesign.Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.btnON.clicked.connect(QCoreApplication.instance().quit)
self.lblCSStatus.setText("starting value")
def get_chargeflag_value(self, value):
self.lblCSStatus.setText(value)
def make_connection(self, plot_object):
plot_object.changedValue.connect(self.get_flag_value)
@pyqtSlot(str)
def get_flag_value(self, val):
self.lblCSStatus.setText(val)
def main():
app = QApplication(sys.argv)
form = Powapp()
form.show()
form.make_connection(w)
sys.exit(app.exec())
if __name__ == '__main__':
main()
对于我的信号和槽实现,我基于以下示例:https://blog.manash.me/quick-pyqt5-1-signal-and-slot-example-in-pyqt5-bf502ccaf11d
我在 Plotter.py 上创建了变量 changeflag,它将根据来自传感器的值从 "solar" 更改为 "battery",这是我想要显示的文本我的 Qlabel,但我很确定那是我的错误。我想我应该创建某种会发出信号的 Qobject,但我不清楚是否允许这样做或如何做到这一点。非常感谢!
您的代码中有几个错误:
变量 chargeflag 是一个字符串,没有 valueChanged 方法。
valueChanged 是 CustomPlot class 的一个属性,如果您在 class 中使用它,您应该使用 self
实例:self.changedValue.emit(some_string)
这不是错误,但我认为没有必要,您不需要创建插槽来发出信号,您可以在 class 中的任何位置执行此操作。
没有必要创建 make_connection 方法,此外,您传递的 w 从未创建过,当使用 Qt Designer 时,它成为 [=54= 的成员]: self.widget = CustomPlot(self.centralWidget)
, 所以你可以在 Powapp 中连接它 class: self.widget.changedValue.connect(self.get_flag_value)
.
以上都在下一个class中实现,我已经修改了你代码的其他部分,但它们并不重要,此外randrange()
函数需要整数和非浮点值作为输入,所以我从同一个随机模块中通过 uniform()
更改了 randrange()
函数,因此它将导入:from random import randrange
更改为 from random import uniform
Plotter.py
class CustomPlot(pg.GraphicsWindow):
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
ptr1 = 0
#Added a signal
changedValue = pyqtSignal(str)
def __init__(self, parent=None, **kargs):
pg.GraphicsWindow.__init__(self, **kargs)
#self.setParent(parent)
p1 = self.addPlot(labels = {'left':'Current (mA)', 'bottom':'Time(secs)'}, xRange=[0,5])
p1.showGrid(x=True, y=True)
p1.setYRange(3.4,4.6)
p1.addLegend()
#self.data1 = np.random.normal(size=10)
#print(self.data1)
self.data1 = [uniform(3,5) for _ in range(10)]
# self.data1 = [ina.current() for _ in range(10)]
#print(self.data1)
#print(ina.current())
#self.data1 = ina.voltage
#self.data2 = np.random.normal(size=10)
self.curve1 = p1.plot(self.data1, pen='r', width=25, name='Battery')
#self.curve2 = p1.plot(self.data2, pen=(2,3))
timer = pg.QtCore.QTimer(self)
timer.timeout.connect(self.update)
#timer.timeout.connect(ina.current)
timer.start(1000) # number of seconds (every 1000) for next update
#setting a connection between chargeflag change and on_changed_value function
def update(self):
#global chargeflag
self.data1[:-1] = self.data1[1:] # shift data in the array one sample left (see also: np.roll)
#self.data1[-1] = np.random.normal()
#self.data1[-1] = ina.current() #actual value from sensor
self.data1[-1] = uniform(3.5,4.5)
chargeflag = "solar" if self.data1[-1] < 4 else "battery"
self.ptr1 += 1
self.curve1.setData(self.data1)
self.curve1.setPos(self.ptr1, 0)
#self.data2[:-1] = self.data2[1:] # shift data in the array one sample left
# (see also: np.roll)
#self.data2[-1] = np.random.normal()
#self.curve2.setData(self.data2)
#self.curve2.setPos(self.ptr1,0)
self.changedValue.emit(chargeflag)
if __name__ == '__main__':
w = CustomPlot()
w.show()
QtGui.QApplication.instance().exec_()
main.py
class Powapp(QMainWindow, Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.btnON.clicked.connect(QCoreApplication.instance().quit)
self.lblCSStatus.setText("starting value")
self.widget.changedValue.connect(self.get_flag_value)
def get_chargeflag_value(self, value):
self.lblCSStatus.setText(value)
@pyqtSlot(str)
def get_flag_value(self, val):
self.lblCSStatus.setText(val)
def main():
app = QApplication(sys.argv)
form = Powapp()
form.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
我正在为与多个传感器交互的 raspberry pi 创建一个 GUI。我需要 GUI 来显示这些值。为此,我使用 QT 创建主要的 window/UI,然后使用 pyuic5 将结果转换为 python,以开发 python 上的所有其他内容,包括实时电流图(可能在同一图或其他图上添加几条其他曲线)。话虽如此,我有点坚持为我一直在测试的 Qlabel 设置文本。我认为更改该文本的最佳方法是使用信号和槽(而且我确定我会在其他事件中需要这些知识)。
这是我的 UI 在 运行 pyuic5 之后:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1075, 622)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralWidget)
self.gridLayout.setContentsMargins(11, 11, 11, 11)
self.gridLayout.setSpacing(6)
self.gridLayout.setObjectName("gridLayout")
self.lblSolar = QtWidgets.QLabel(self.centralWidget)
self.lblSolar.setObjectName("lblSolar")
self.gridLayout.addWidget(self.lblSolar, 3, 1, 1, 1)
self.progressBar = QtWidgets.QProgressBar(self.centralWidget)
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.gridLayout.addWidget(self.progressBar, 4, 0, 1, 1)
self.progressBar_2 = QtWidgets.QProgressBar(self.centralWidget)
self.progressBar_2.setProperty("value", 24)
self.progressBar_2.setObjectName("progressBar_2")
self.gridLayout.addWidget(self.progressBar_2, 4, 1, 1, 1)
self.btnSelectSol = QtWidgets.QPushButton(self.centralWidget)
self.btnSelectSol.setStyleSheet("background-color: rgb(114, 159, 207);")
self.btnSelectSol.setObjectName("btnSelectSol")
self.gridLayout.addWidget(self.btnSelectSol, 1, 3, 1, 1)
self.btnSelectBat = QtWidgets.QPushButton(self.centralWidget)
self.btnSelectBat.setStyleSheet("background-color: rgb(114, 159, 207);")
self.btnSelectBat.setObjectName("btnSelectBat")
self.gridLayout.addWidget(self.btnSelectBat, 2, 3, 1, 1)
self.lblBattery = QtWidgets.QLabel(self.centralWidget)
self.lblBattery.setObjectName("lblBattery")
self.gridLayout.addWidget(self.lblBattery, 3, 0, 1, 1)
self.btnON = QtWidgets.QPushButton(self.centralWidget)
self.btnON.setObjectName("btnON")
self.gridLayout.addWidget(self.btnON, 4, 3, 1, 1)
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
self.verticalLayout.setContentsMargins(11, 11, 11, 11)
self.verticalLayout.setSpacing(6)
self.verticalLayout.setObjectName("verticalLayout")
self.lblCSTitle = QtWidgets.QLabel(self.centralWidget)
self.lblCSTitle.setAlignment(QtCore.Qt.AlignCenter)
self.lblCSTitle.setObjectName("lblCSTitle")
self.verticalLayout.addWidget(self.lblCSTitle)
self.lblCSStatus = QtWidgets.QLabel(self.centralWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lblCSStatus.sizePolicy().hasHeightForWidth())
self.lblCSStatus.setSizePolicy(sizePolicy)
self.lblCSStatus.setAutoFillBackground(False)
self.lblCSStatus.setAlignment(QtCore.Qt.AlignCenter)
self.lblCSStatus.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
self.lblCSStatus.setObjectName("lblCSStatus")
self.verticalLayout.addWidget(self.lblCSStatus)
self.gridLayout.addLayout(self.verticalLayout, 0, 3, 1, 1)
self.widget = CustomPlot(self.centralWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())
self.widget.setSizePolicy(sizePolicy)
self.widget.setObjectName("widget")
self.gridLayout.addWidget(self.widget, 0, 0, 3, 3)
MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 1075, 26))
self.menuBar.setObjectName("menuBar")
self.menuHelp = QtWidgets.QMenu(self.menuBar)
self.menuHelp.setObjectName("menuHelp")
self.menuData = QtWidgets.QMenu(self.menuBar)
self.menuData.setObjectName("menuData")
MainWindow.setMenuBar(self.menuBar)
self.mainToolBar = QtWidgets.QToolBar(MainWindow)
self.mainToolBar.setObjectName("mainToolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
self.statusBar = QtWidgets.QStatusBar(MainWindow)
self.statusBar.setObjectName("statusBar")
MainWindow.setStatusBar(self.statusBar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.actionGuide = QtWidgets.QAction(MainWindow)
self.actionGuide.setObjectName("actionGuide")
self.actionAbout = QtWidgets.QAction(MainWindow)
self.actionAbout.setObjectName("actionAbout")
self.actionExport = QtWidgets.QAction(MainWindow)
self.actionExport.setObjectName("actionExport")
self.menuHelp.addAction(self.actionGuide)
self.menuHelp.addAction(self.actionAbout)
self.menuData.addAction(self.actionExport)
self.menuBar.addAction(self.menuHelp.menuAction())
self.menuBar.addAction(self.menuData.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Power System Monitor"))
self.lblSolar.setText(_translate("MainWindow", "Solar Panel"))
self.btnSelectSol.setText(_translate("MainWindow", "Power from Solar Panel"))
self.btnSelectBat.setText(_translate("MainWindow", "Power from Battery"))
self.lblBattery.setText(_translate("MainWindow", "Battery"))
self.btnON.setText(_translate("MainWindow", "EXIT"))
self.lblCSTitle.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:16pt; font-weight:600;\">Pi Charge System</span></p></body></html>"))
self.lblCSStatus.setText(_translate("MainWindow", "TextLabel"))
self.menuHelp.setTitle(_translate("MainWindow", "Help"))
self.menuData.setTitle(_translate("MainWindow", "Data"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.actionGuide.setText(_translate("MainWindow", "Guide"))
self.actionAbout.setText(_translate("MainWindow", "About"))
self.actionExport.setText(_translate("MainWindow", "Export"))
from Plotter import CustomPlot
这是我的 Plotter.py 文件:
import sys
import os
os.environ['PYQTGRAPH_QT_LIB']='PyQt5' #force pyqtgraph to use pyqt5
import pyqtgraph as pg
import PyQt5
from pyqtgraph.Qt import QtCore, QtGui
#import numpy as np #np is used for testing plot curves
#from ina219 import INA219, DeviceRangeError #sensory library
from time import sleep
from PyQt5.QtCore import Qt, pyqtSignal
from random import randrange
#SHUNT_OHMS = 0.1
#MAX_EXPECTED_AMPS = 1.0 #2.0
#ina = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS)
#ina.configure(ina.RANGE_16V)
class CustomPlot(pg.GraphicsWindow):
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
ptr1 = 0
chargeflag = "start"
#Added a signal
changedValue = pyqtSignal(str)
def __init__(self, parent=None, **kargs):
global chargeflag #variable to emit signal on change
pg.GraphicsWindow.__init__(self, **kargs)
#self.setParent(parent)
p1 = self.addPlot(labels = {'left':'Current (mA)', 'bottom':'Time(secs)'}, xRange=[0,5])
p1.showGrid(x=True, y=True)
p1.setYRange(3.4,4.6)
p1.addLegend()
#self.data1 = np.random.normal(size=10)
#print(self.data1)
self.data1 = []
for n in range(10):
#self.data1.append(ina.current()) #get actual data1 from sensor
self.data1.append(randrange(3,5))
sleep(1)
#print(self.data1)
#print(ina.current())
#self.data1 = ina.voltage
#self.data2 = np.random.normal(size=10)
self.curve1 = p1.plot(self.data1, pen='r', width=25, name='Battery')
#self.curve2 = p1.plot(self.data2, pen=(2,3))
timer = pg.QtCore.QTimer(self)
timer.timeout.connect(self.update)
#timer.timeout.connect(ina.current)
timer.start(1000) # number of seconds (every 1000) for next update
#setting a connection between chargeflag change and on_changed_value function
self.chargeflag.valueChanged.connect(self.on_changed_value)
def update(self):
#global chargeflag
self.data1[:-1] = self.data1[1:] # shift data in the array one sample left (see also: np.roll)
#self.data1[-1] = np.random.normal()
#self.data1[-1] = ina.current() #actual value from sensor
self.data1[-1] = randrange(3.5,4.5)
if self.data1[-1] < 4: #if that should send signal to update Qlabel
self.chargeflag = "solar"
else:
self.chargeflag = 'battery'
print(self.chargeflag)
self.ptr1 += 1
self.curve1.setData(self.data1)
self.curve1.setPos(self.ptr1, 0)
#self.data2[:-1] = self.data2[1:] # shift data in the array one sample left
# (see also: np.roll)
#self.data2[-1] = np.random.normal()
#self.curve2.setData(self.data2)
#self.curve2.setPos(self.ptr1,0)
self.changeflag.changedValue.connect(self.on_changed_value)
#function for other objects from other classes to listen to
def on_changed_value(self, value):
self.changedValue.emit(value)
if __name__ == '__main__':
w = CustomPlot()
w.show()
QtGui.QApplication.instance().exec_()
最后是我的 main.py 文件:
import PyQt5
from PyQt5.QtWidgets import *
import sys
import Powdesign
from PyQt5.QtCore import QCoreApplication, pyqtSlot
from Plotter import CustomPlot
from time import sleep
class Powapp(QMainWindow, Powdesign.Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.btnON.clicked.connect(QCoreApplication.instance().quit)
self.lblCSStatus.setText("starting value")
def get_chargeflag_value(self, value):
self.lblCSStatus.setText(value)
def make_connection(self, plot_object):
plot_object.changedValue.connect(self.get_flag_value)
@pyqtSlot(str)
def get_flag_value(self, val):
self.lblCSStatus.setText(val)
def main():
app = QApplication(sys.argv)
form = Powapp()
form.show()
form.make_connection(w)
sys.exit(app.exec())
if __name__ == '__main__':
main()
对于我的信号和槽实现,我基于以下示例:https://blog.manash.me/quick-pyqt5-1-signal-and-slot-example-in-pyqt5-bf502ccaf11d
我在 Plotter.py 上创建了变量 changeflag,它将根据来自传感器的值从 "solar" 更改为 "battery",这是我想要显示的文本我的 Qlabel,但我很确定那是我的错误。我想我应该创建某种会发出信号的 Qobject,但我不清楚是否允许这样做或如何做到这一点。非常感谢!
您的代码中有几个错误:
变量 chargeflag 是一个字符串,没有 valueChanged 方法。
valueChanged 是 CustomPlot class 的一个属性,如果您在 class 中使用它,您应该使用
self
实例:self.changedValue.emit(some_string)
这不是错误,但我认为没有必要,您不需要创建插槽来发出信号,您可以在 class 中的任何位置执行此操作。
没有必要创建 make_connection 方法,此外,您传递的 w 从未创建过,当使用 Qt Designer 时,它成为 [=54= 的成员]:
self.widget = CustomPlot(self.centralWidget)
, 所以你可以在 Powapp 中连接它 class:self.widget.changedValue.connect(self.get_flag_value)
.
以上都在下一个class中实现,我已经修改了你代码的其他部分,但它们并不重要,此外randrange()
函数需要整数和非浮点值作为输入,所以我从同一个随机模块中通过 uniform()
更改了 randrange()
函数,因此它将导入:from random import randrange
更改为 from random import uniform
Plotter.py
class CustomPlot(pg.GraphicsWindow):
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
ptr1 = 0
#Added a signal
changedValue = pyqtSignal(str)
def __init__(self, parent=None, **kargs):
pg.GraphicsWindow.__init__(self, **kargs)
#self.setParent(parent)
p1 = self.addPlot(labels = {'left':'Current (mA)', 'bottom':'Time(secs)'}, xRange=[0,5])
p1.showGrid(x=True, y=True)
p1.setYRange(3.4,4.6)
p1.addLegend()
#self.data1 = np.random.normal(size=10)
#print(self.data1)
self.data1 = [uniform(3,5) for _ in range(10)]
# self.data1 = [ina.current() for _ in range(10)]
#print(self.data1)
#print(ina.current())
#self.data1 = ina.voltage
#self.data2 = np.random.normal(size=10)
self.curve1 = p1.plot(self.data1, pen='r', width=25, name='Battery')
#self.curve2 = p1.plot(self.data2, pen=(2,3))
timer = pg.QtCore.QTimer(self)
timer.timeout.connect(self.update)
#timer.timeout.connect(ina.current)
timer.start(1000) # number of seconds (every 1000) for next update
#setting a connection between chargeflag change and on_changed_value function
def update(self):
#global chargeflag
self.data1[:-1] = self.data1[1:] # shift data in the array one sample left (see also: np.roll)
#self.data1[-1] = np.random.normal()
#self.data1[-1] = ina.current() #actual value from sensor
self.data1[-1] = uniform(3.5,4.5)
chargeflag = "solar" if self.data1[-1] < 4 else "battery"
self.ptr1 += 1
self.curve1.setData(self.data1)
self.curve1.setPos(self.ptr1, 0)
#self.data2[:-1] = self.data2[1:] # shift data in the array one sample left
# (see also: np.roll)
#self.data2[-1] = np.random.normal()
#self.curve2.setData(self.data2)
#self.curve2.setPos(self.ptr1,0)
self.changedValue.emit(chargeflag)
if __name__ == '__main__':
w = CustomPlot()
w.show()
QtGui.QApplication.instance().exec_()
main.py
class Powapp(QMainWindow, Ui_MainWindow):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.btnON.clicked.connect(QCoreApplication.instance().quit)
self.lblCSStatus.setText("starting value")
self.widget.changedValue.connect(self.get_flag_value)
def get_chargeflag_value(self, value):
self.lblCSStatus.setText(value)
@pyqtSlot(str)
def get_flag_value(self, val):
self.lblCSStatus.setText(val)
def main():
app = QApplication(sys.argv)
form = Powapp()
form.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()