我是使用pyQt进行gui编程的新手。我已经设置了一个简单的gui,它有一个按钮,当点击时,它将从一个单独的类中执行一个方法。但当我点击按钮时,会出现以下错误:
*处理接收信号信号:分段故障(11)信号代码:地址未映射(1)失败地址:(零)[0]/lib/x86_64-linux-gnu/libphread.so.0(+0x113d0)[0x7fc1957ff3d0]错误消息结束*
这是我的代码:
from PyQt4.QtCore import *
from PyQt4 import QtGui, uic
class MyWindow(QtGui.QDialog):
def __init__(self):
super(MyWindow, self).__init__()
self.ui = uic.loadUi('gui.ui', self)
self.ui.show()
class A(QObject):
def __init__(self):
super(A, self).__init__()
@pyqtSlot()
def funcA(self):
class Main(QtGui.QDialog):
def __init__(self, parent=None):
gui = MyWindow()
H = A()
gui.connect(gui.button, SIGNAL("clicked()"), H.funcA)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
Main()
sys.exit(app.exec_())
将GUI元素与应执行的方法连接起来的正确方式是什么?
我无法在我的系统上用您的代码重现segfault,但这一定是因为您没有保留对应该存在到Qt应用程序结束的对象的引用。
在Main.__init__
中,将新创建的MyWindow
和A
分配给局部变量。这些对象将被垃圾收集器销毁在__init__
退出之后,信号被连接到一个不存在的对象的插槽,这将导致各种恶劣的事情,包括segfault。
要解决此问题,您有两个选项:
(选项1)将这些对象保存为Main
的属性:
self.gui = MyWindow()
self.H = A()
(Option2)通过在构造函数的父参数中传递self,将它们插入Qt的对象树中
gui = MyWindow(self)
这是适用于我的代码:
from PyQt4.QtCore import *
from PyQt4 import QtGui
import sys
class MyWindow(QtGui.QDialog):
# (Option2) Notice that the added `parent` argument is passed to super().__init__
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
layout = QtGui.QVBoxLayout(self)
self.button = QtGui.QPushButton(self)
layout.addWidget(self.button)
self.show()
class A(QObject):
def __init__(self):
super(A, self).__init__()
@pyqtSlot()
def funcA(self):
print 'funcA'
class Main(QtGui.QDialog):
def __init__(self, parent=None):
super(Main, self).__init__()
# (Option1)
self.H = A()
# (Option2)
gui = MyWindow(self)
gui.button.clicked.connect(self.H.funcA)
# gui.connect(gui.button, SIGNAL("clicked()"), self.H.funcA)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
# the Main object must be saved from the garbage collector too
main_dlg = Main()
sys.exit(app.exec_())