如何实现 QPushbutton 来发出 pyqt 信号并调用另一个类?

Posted

技术标签:

【中文标题】如何实现 QPushbutton 来发出 pyqt 信号并调用另一个类?【英文标题】:How to implement a QPushbutton to emit pyqt signal and call another class? 【发布时间】:2017-07-25 16:41:30 【问题描述】:

我正在尝试学习发射/接收信号的基本用法,但遇到了一些麻烦。

我想从一些基本的东西开始,所以我创建了一个 MainWindow 并放置了一个名为“plot”的 QPushButton。

按下按钮时,它接受参数(self、xdata、ydata)并从我的类 MainWindow(QMainWindow) 中运行方法initialPlot

    self.plotbtn = QPushButton("Plot")
    self.plotbtn.clicked.connect(partial(self.initiatePlot, xdata, ydata))

    def initiatePlot(self,x,y):
        PlotSignal = pyqtSignal(list, list)
        self.PlotSignal.emit(x, y)

之后我尝试将它连接到我的绘图仪类,但我只是得到“处理完成退出代码 1”我相信错误来自我下面类中的这一特定代码行。

self.PlotSignal.connect(self.plotData)

绘图仪类代码

class createFIG(FigureCanvas):
  def __init__(self):
    #super().__init__(Figure(tight_layout=True))
    self.figure = plt.figure()
    self.axes = self.figure.add_subplot(111)

    self.name = ""

    # xdata = [1,2,3,4,5]
    # ydata = [12,4,56,78,9]

    plt.figure()
    self.axes.set_xlabel('x label')

    #self.plotData(xdata,ydata)

    self.PlotSignal.connect(self.plotData)


  def plotData(self, xdata,ydata):
    print("plotting")
    self.axes.plot(xdata, ydata)
    self.draw()
    plt.show()

抱歉,空格可能有点乱。

当前的问题是如何接收我从initialPlot 方法发出的信号。

最终目标是能够单击绘图按钮并每次创建一个带有新绘图图形的新窗口。

如果有一种更简单的方法可以将我的主窗口中的按钮链接到绘图类,那将很有帮助。

这是我完整代码的链接:https://github.com/Silvuurleaf/InteractiveGraphing/blob/master/LiveGraphing.py

【问题讨论】:

能否请您创建一个minimal reproducible example 的问题?!正如 SO 所说:寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建minimal reproducible example。 这是最少的代码,我不能给你一个可验证的例子,因为我的 IDE 在我运行它时只给出错误“处理完成退出代码 1”。我相信错误发生在“self.PlotSIgnal.connect(self.plotData)”行中 正是这个想法:提供minimal reproducible example,让其他人重现您遇到的错误。 IE。我需要能够从问题中复制代码,运行它,得到与您相同的错误,更正代码,将其粘贴为答案,您会很高兴。 好的,我添加了一个 github 链接以提供对我的代码的完全访问权限。 查看代码,我不清楚您需要什么信号和插槽。每次按下按钮时,您似乎都想创建一个 matplotlib 绘图窗口。这将通过启动createFIG 类(它不需要继承FigureCanvas)并简单地从中调用绘图函数来完成。我在这里错过了什么吗?还有其他使用信号的理由吗? 【参考方案1】:

如前所述,我不确定这是否真的是您要查找的内容,但以下代码应在每次按下按钮时创建一个新的 matplotlib 窗口。

import sys
#Importing PyQt5 library to construct widgets for Graphic User Interface (GUI) application
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import (QLineEdit, QPushButton, QSlider, QApplication, QVBoxLayout, QHBoxLayout,
                             QWidget, QLabel, QCheckBox, QRadioButton, QPlainTextEdit, QSizePolicy,
                             QMainWindow,QFrame, QFileDialog, QTableWidgetItem, QTableWidget, QMenu, QMessageBox,
                             QAction, QToolBar)
from PyQt5.QtCore import Qt, QAbstractTableModel, pyqtSignal

from functools import partial
import matplotlib
matplotlib.use("Qt5Agg")

from matplotlib import pyplot as plt
plt.style.use(['ggplot'])

class createFIG():
    def __init__(self):
        self.figure = plt.figure()
        self.axes = self.figure.add_subplot(111)
        self.name = ""
        self.axes.set_xlabel('x label')

    def plotData(self, xdata,ydata):
        print("plotting")
        self.axes.plot(xdata, ydata)
        plt.show()


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setWindowTitle("Perspective")

        self.initializeUI()

    def initializeUI(self):

        xdata = [1,2,3,4,5]
        ydata = [12,4,56,78,9]

        #Main Widget
        self.main_widget = QWidget(self)
        self.setCentralWidget(self.main_widget)

        self.plotbtn = QPushButton("Plot")
        self.plotbtn.clicked.connect(partial(self.initiatePlot, xdata, ydata))

        self.hMAIN = QHBoxLayout(self.main_widget)
        self.vboxLeft = QVBoxLayout()
        self.vboxLeft.addWidget(self.plotbtn)

        self.hbox1 = QHBoxLayout()

        self.vboxLeft.addLayout(self.hbox1)

        self.PlotLayout = QVBoxLayout()

        self.hMAIN.addLayout(self.vboxLeft)
        self.hMAIN.addLayout(self.PlotLayout)

        self.show()

    def initiatePlot(self,x,y):
        print("emit signal")
        f = createFIG()
        f.plotData(x, y)


def main():
        # main loop
        app = QApplication(sys.argv)
        # instance
        window = MainWindow()
        window.show()
        # appWindow = MainWindow()
        sys.exit(app.exec_())

if __name__ == "__main__":
    main()

【讨论】:

是的,谢谢,这正是我想要的。下次我发帖阐明我的问题时,我会提高我的沟通技巧。谢谢! 我会看看如何在别处正确利用信号 This question 可能会向您展示如何使用信号以及为什么:因为不同的线程需要通过它们进行通信。此外,this question 似乎与您想要的相似。

以上是关于如何实现 QPushbutton 来发出 pyqt 信号并调用另一个类?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用paintEvent的情况下旋转PyQt5 QPushButton?

如何阻止空格键在 PyQt5 中触发聚焦的 QPushButton?

Pyqt5:如何限制QMainWindow中QPushButton的拖动区域?

如何在 PyQt 中获取按钮或标签(QPushButton、QLabel)的背景颜色

PyQt4:如何使图标大于 QPushButton? (像素图按钮)

如何在PyQt5中使用QDrag拖动时显示QPushButton?