按下按钮时,让PyQt4打开另一个Qt窗口

时间:2014-01-28 23:32:21

标签: python qt matplotlib pyqt4

我正在尝试让一个Qt窗口在按下按钮时在另一个Qt窗口中显示matplotlib图形。我有一个 .py 文件,该文件使用按钮生成该UI,另一个 .py 文件在运行时会打开一个显示图形的QT窗口。

如果我只运行第二个 .py 文件,则显示图表的QT窗口会打开,没问题。

然而,问题是当我通过第一个运行第二个 .py 文件时, pythonw.exe 在我点击按钮运行第二个时崩溃< strong> .py 文件。

以下是代码(一个 .py 文件。如果用户希望查看matplotlib图,则会为用户创建用户界面以点击该按钮):

import matplotlib
matplotlib.use('Qt4Agg')
import pylab
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

import matplotlibtest
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(690, 786)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.widget_2 = QtGui.QWidget(self.centralwidget)
        self.widget_2.setGeometry(QtCore.QRect(120, 20, 471, 51))
        self.widget_2.setObjectName(_fromUtf8("widget_2"))

        #...some other irrelevant code...

        self.plotButton = QtGui.QPushButton(self.layoutWidget_2)
        self.plotButton.setMinimumSize(QtCore.QSize(0, 23))
        self.plotButton.setObjectName(_fromUtf8("plotButton"))
        self.gridLayout_2.addWidget(self.plotButton, 9, 1, 1, 1)
        self.plotButton.clicked.connect(self.showimage)

    def showimage(self):
        matplotlibtest.main()

因此,当用户点击 plotButton 时,会运行 matplotlibtest.py 的主要功能。

matplotlibtest.py 中,我有这段代码(来自http://packtlib.packtpub.com/library/9781847197900/ch06)。运行时此代码打开一个QT窗口,显示一个简单的matplotlib图。这里没有问题 - 当运行此代码时,它会按照我的意愿打开图形。

# for command-line arguments
import sys
# Python Qt4 bindings for GUI objects
from PyQt4 import QtGui
# Numpy functions for image creation
import numpy as np
# Matplotlib Figure object
from matplotlib.figure import Figure
import matplotlib
matplotlib.use('Qt4Agg')
# import the Qt4Agg FigureCanvas object, that binds Figure to
# Qt4Agg backend. It also inherits from QWidget
from matplotlib.backends.backend_qt4agg \
import FigureCanvasQTAgg as FigureCanvas
# import the NavigationToolbar Qt4Agg widget
from matplotlib.backends.backend_qt4agg \
import NavigationToolbar2QTAgg as NavigationToolbar

class Qt4MplCanvas(FigureCanvas):

    def __init__(self, parent):
        # plot definition
        self.fig = Figure()
        self.axes = self.fig.add_subplot(111)
        t = np.arange(0.0, 3.0, 0.01)
        s = np.cos(2*np.pi*t)
        self.axes.plot(t, s)
        # initialization of the canvas
        FigureCanvas.__init__(self, self.fig)
        # set the parent widget
        self.setParent(parent)
        # we define the widget as expandable
        FigureCanvas.setSizePolicy(self,
        QtGui.QSizePolicy.Expanding,
        QtGui.QSizePolicy.Expanding)
        # notify the system of updated policy
        FigureCanvas.updateGeometry(self)

class ApplicationWindow(QtGui.QMainWindow):
    def __init__(self):
        # initialization of Qt MainWindow widget
        QtGui.QMainWindow.__init__(self)
        # set window title
        self.setWindowTitle("Matplotlib Figure in a Qt4 Window With NavigationToolbar")
        # instantiate a widget, it will be the main one
        self.main_widget = QtGui.QWidget(self)
        # create a vertical box layout widget
        vbl = QtGui.QVBoxLayout(self.main_widget)
        # instantiate our Matplotlib canvas widget
        qmc = Qt4MplCanvas(self.main_widget)
        # instantiate the navigation toolbar
        ntb = NavigationToolbar(qmc, self.main_widget)
        # pack these widget into the vertical box
        vbl.addWidget(qmc)
        vbl.addWidget(ntb)
        # set the focus on the main widget
        self.main_widget.setFocus()
        # set the central widget of MainWindow to main_widget
        self.setCentralWidget(self.main_widget)

def main():
    # create the GUI application
    qApp = QtGui.QApplication(sys.argv)
    # instantiate the ApplicationWindow widget
    aw = ApplicationWindow()
    # show the widget
    aw.show()
    sys.exit(qApp.exec_())

if __name__ == '__main__':
    main()    

单击按钮时如何显示matplotlib图?

为什么 pythonw.exe 崩溃?

编辑:

如果我想传递参数(x = [1,2,3],y = [1,1,1])来制作图表,我会放class Qt4MplCanvas(FigureCanvas): def __init__(self,parent,x,y),当我构建它时我写qmc = Qt4MplCanvas(self.main_widget, [1,2,3], [1,1,1])

在任何Qt对象的__init__中,我们是否运行超级__init__来初始化Qt对象的父对象? 为什么super(MyMainWindow,self)的参数?

为什么我们使用'对象'     class Ui_MainWIndow(object): 但我们使用'QtGui.QMainWindow'     class MyMainWindow(QtGui.QMainWindow)

是'object'和'QtGui.QMainWindow'的论点吗?

当我们构建一个Ui_MainWindow时,我们为什么要写     self.ui = Ui_MainWindow() 并不是     self.ui = Ui_MainWindow(object)

1 个答案:

答案 0 :(得分:1)

好的,你的代码中有几个问题:

  1. 您有一个Ui定义对象,但您没有使用它。
  2. 您不能在运行中两次使用matplotlib.use(一个在主.py中,另一个在matplotlibtest中)
  3. 如果您希望运行PyQt应用程序,则必须创建QApplication对象
  4. 涉及布局的其他小错误
  5. 对于解决方案,请检查代码,这是我对您的代码所做的一些修改,以使其工作:

    .py主文件

    from PyQt4 import QtCore,QtGui
    
    try:
        _fromUtf8 = QtCore.QString.fromUtf8
    except AttributeError:
        def _fromUtf8(s):
            return s
    
    try:
        _encoding = QtGui.QApplication.UnicodeUTF8
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig, _encoding)
    except AttributeError:
        def _translate(context, text, disambig):
            return QtGui.QApplication.translate(context, text, disambig)
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName(_fromUtf8("MainWindow"))
            MainWindow.resize(690, 786)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
            self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget) #here
            self.centralwidget.setLayout(self.gridLayout_2) #here
    
            #...some other irrelevant code...
    
            self.plotButton = QtGui.QPushButton() #here
            self.plotButton.setMinimumSize(QtCore.QSize(0, 23))
            self.plotButton.setObjectName(_fromUtf8("plotButton"))
            self.gridLayout_2.addWidget(self.plotButton, 9, 1, 1, 1)
            self.plotButton.clicked.connect(self.showimage)
    
        def showimage(self):
            #changes here
            from matplotlibtest import ApplicationWindow
            self.aw = ApplicationWindow()
            self.aw.show()
    
    #class that actually shows something
    class MyMainWindow(QtGui.QMainWindow):
    
        def __init__(self,parent=None):
            super(MyMainWindow,self).__init__()
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
    
    #put the main window here
    def main():
        import sys
        qApp = QtGui.QApplication(sys.argv)
        aw = MyMainWindow()
        aw.show()
        sys.exit(qApp.exec_())
    
    if __name__ == '__main__':
        main()  
    

    matplotlibtest.py

    # Python Qt4 bindings for GUI objects
    from PyQt4 import QtGui
    # Numpy functions for image creation
    import numpy as np
    # Matplotlib Figure object
    from matplotlib.figure import Figure
    import matplotlib
    matplotlib.use('Qt4Agg')
    # import the Qt4Agg FigureCanvas object, that binds Figure to
    # Qt4Agg backend. It also inherits from QWidget
    from matplotlib.backends.backend_qt4agg \
    import FigureCanvasQTAgg as FigureCanvas
    # import the NavigationToolbar Qt4Agg widget
    from matplotlib.backends.backend_qt4agg \
    import NavigationToolbar2QTAgg as NavigationToolbar
    
    class Qt4MplCanvas(FigureCanvas):
    
        def __init__(self, parent):
            # plot definition
            self.fig = Figure()
            self.axes = self.fig.add_subplot(111)
            t = np.arange(0.0, 3.0, 0.01)
            s = np.cos(2*np.pi*t)
            self.axes.plot(t, s)
            # initialization of the canvas
            FigureCanvas.__init__(self, self.fig)
            # set the parent widget
            self.setParent(parent)
            # we define the widget as expandable
            FigureCanvas.setSizePolicy(self,
            QtGui.QSizePolicy.Expanding,
            QtGui.QSizePolicy.Expanding)
            # notify the system of updated policy
            FigureCanvas.updateGeometry(self)
    
    class ApplicationWindow(QtGui.QMainWindow):
        def __init__(self):
            # initialization of Qt MainWindow widget
            QtGui.QMainWindow.__init__(self)
            # set window title
            self.setWindowTitle("Matplotlib Figure in a Qt4 Window With NavigationToolbar")
            # instantiate a widget, it will be the main one
            self.main_widget = QtGui.QWidget(self)
            # create a vertical box layout widget
            vbl = QtGui.QVBoxLayout(self.main_widget)
            # instantiate our Matplotlib canvas widget
            qmc = Qt4MplCanvas(self.main_widget)
            # instantiate the navigation toolbar
            ntb = NavigationToolbar(qmc, self.main_widget)
            # pack these widget into the vertical box
            vbl.addWidget(qmc)
            vbl.addWidget(ntb)
            # set the focus on the main widget
            self.main_widget.setFocus()
            # set the central widget of MainWindow to main_widget
            self.setCentralWidget(self.main_widget)
    
    #deleted the main function here