按下按钮时获取 PyQt4 以打开另一个 Qt 窗口
Posted
技术标签:
【中文标题】按下按钮时获取 PyQt4 以打开另一个 Qt 窗口【英文标题】:Get PyQt4 to open another Qt window when a button is pressed 【发布时间】:2014-01-28 23:32:21 【问题描述】:我试图让一个 Qt 窗口在按下按钮时在另一个 Qt 窗口中显示 matplotlib 图。我有一个 .py 文件可以生成带有按钮的 UI,另一个 .py 文件在运行时会打开一个显示图形的 QT 窗口。
如果我只运行第二个 .py 文件,会打开显示图形的 QT 窗口,没问题。
但是,问题是当我通过第一个运行第二个 .py 文件时,当我单击运行第二个的按钮时 pythonw.exe 崩溃了strong>.py 文件。
这是代码(一个 .py 文件。它为用户创建 UI,如果他们想查看 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的main函数运行。
在 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])
?
在__init__
中对于任何Qt 对象,我们是否运行super 的__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】:好的,你的代码有几个问题:
-
您有一个
Ui
定义对象,但您没有使用它。
您不能在一次运行中使用两次matplotlib.use
(一次在主 .py 中,一次在 matplotlibtest 中)
如果您想运行 PyQt
应用程序,您必须创建一个 QApplication
对象
其他涉及布局的小错误
对于解决方案,请检查代码,这是我对您的代码进行的一些修改以使其正常工作:
在您的 .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
【讨论】:
它有效。谢谢!关于你所做的事情,我有一些小问题,我在我的帖子的编辑中写道。你能看看我的问题吗?以上是关于按下按钮时获取 PyQt4 以打开另一个 Qt 窗口的主要内容,如果未能解决你的问题,请参考以下文章