【发布时间】:2021-04-20 14:28:52
【问题描述】:
我得到了 Python GUI 的以下代码。发现无法将主窗口中运行的数据更新到弹窗中。
在此示例中,我使用一些随机数据来模拟视频帧并使用计时器来更新数据(updateData() 函数)。
我想看看弹出窗口中的绿色曲线变化...但是我找不到有效的方法将变化的数据传递给弹出窗口。
我应该使用 pyqtSignal() 来定义自定义信号吗?我读了this page。我应该将updateData() 槽函数定义为自定义信号,然后连接到另一个槽函数plot_data() 吗?
"""
1/15/2021 Yuanhang Zhang
"""
from PyQt5.QtWidgets import QMainWindow,QApplication,QGridLayout,QWidget, QPushButton,QDockWidget
from PyQt5.QtCore import Qt,QTimer
from PyQt5.QtGui import QPixmap,QFont
import numpy as np
import pyqtgraph as pg
from pyqtgraph import GradientWidget
class power_window(QMainWindow):
# this window has no parent. It will appear as a free-floating window as we want.
def __init__(self,parent):
super().__init__()
self.setWindowTitle("Total power in the frame")
self.main_widget = QWidget()
self.main_layout = QGridLayout()
self.main_widget.setLayout(self.main_layout)
self.setCentralWidget(self.main_widget)
self.plot_plt = pg.PlotWidget() # this is our plot canvas
self.plot_plt.showGrid(x=True,y=True) # show grid
self.main_layout.addWidget(self.plot_plt, 1, 0, 3, 3)
# self.plot_plt.setYRange(max=100,min=0)
self.data_list = []
parent.timer.timeout.connect(self.plot_data) # update plot
# parent.updateData.change.connect(self.plot_data) # not working, may need to use pyqtSignal for custom signals
self.frame_sum_data = parent.updateData()
self.plot_data()
def plot_data(self):
self.data_list.append(self.frame_sum_data)
self.plot_plt.plot().setData(self.data_list,pen='g') # change the color of the pen
class CameraGUI(QMainWindow):
def __init__(self):
super().__init__()
## Create some random data to mimic video data
# scale: Standard deviation (spread or “width”) of the distribution.
# loc: Mean (“centre”) of the distribution.
self.data = np.random.normal(size=(15, 30, 30), loc=1024, scale=200).astype(np.uint16)
self.i = 0
self.power_gui = None # for the pop up window
self.initializeUI()
def initializeUI(self):
"""
Initialize the window and display its contents to the screen
"""
self.setGeometry(100,100,1000,800) # (x, y, width, height)
self.setWindowTitle('Camera GUI')
self.main_widget = pg.GraphicsLayoutWidget()
self.setCentralWidget(self.main_widget) # set the default widget of the MainWindow
self.createCameraWidgets()
self.show()
def updateLUT(self): ## change colormap (color look up table)
lut = self.gradient.getLookupTable(256)
return lut
def action_on_button_clicked(self): # for the pop-up windown
# https://www.learnpyqt.com/tutorials/creating-multiple-windows/
if self.power_gui is None:
# self.power_gui = power_window(np.sum(self.data[self.i]))
self.power_gui = power_window(self)
self.power_gui.show()
def createCameraWidgets(self):
"""
Setup widgets using QGridLayout
"""
self.gradient = GradientWidget(parent = self.main_widget,orientation='top')
self.gradient.sigGradientChanged.connect(self.updateLUT)
self.dock_widget = QDockWidget(self)
self.dock_widget.setAllowedAreas(Qt.AllDockWidgetAreas)
# set initial location of dock widget in main window
self.addDockWidget(Qt.TopDockWidgetArea,self.dock_widget)
self.button = QPushButton('Power',self)
self.button.clicked.connect(self.action_on_button_clicked) ## --> not updating the data ??
self.dock_widget.setWidget(self.button)
## add view box
self.view1 = self.main_widget.addViewBox(row = 1, col = 0)
self.view2 = self.main_widget.addViewBox(row = 1, col = 1)
## lock the aspect ratio so pixels are always square
self.view1.setAspectLocked(True)
self.view2.setAspectLocked(True)
## Create image item
self.img1 = pg.ImageItem(border='w')
self.img2 = pg.ImageItem(border='w')
self.view1.addItem(self.img1)
self.view2.addItem(self.img2)
# timer of the main window
self.timer = QTimer()
self.timer.setInterval(200) # every 200 ms will emit timeout signal
self.timer.timeout.connect(self.updateData) # when timeout signal is emit, it will run updatedata() function
self.timer.start()
print(np.sum(self.data[self.i])) # this will only run once
print(self.i)
def updateData(self):
## Display the data
self.img1.setImage(self.data[self.i],lut = self.updateLUT()) # when i changes, set to display in img1
self.data2 = np.log(np.abs(np.fft.fft2(self.data[self.i]))) # calculate data2 beased on data[i]
self.i = (self.i+1) % self.data.shape[0] # update i
self.img2.setImage(self.data2,lut = self.updateLUT())
# print(self.i)
print(np.sum(self.data[self.i])) # this will keep running every 200 ms
return np.sum(self.data[self.i])
## run the program
if __name__ =="__main__":
import sys
app = QApplication(sys.argv)
window = CameraGUI()
window.updateData()
sys.exit(app.exec_())
【问题讨论】: