PyQt5 按钮信号在小部件内的布局中不起作用

PyQt5 Button signal doesnt work in a Layout inside a Widget

我正在尝试在 Widget 中实现布局,然后将其添加到 Main Window。如果我在 Main Window 中声明按钮和布局,它可以正常工作。但是,如果我创建一个 class 继承 QWidget 并添加布局和按钮,则信号不工作。我正在使用 setLayout 添加小部件 method.I 尝试将父项也传递给按钮,但结果相同。

我不确定我还有什么地方做错了,欢迎任何关于问题所在的方向或提示。

from PyQt5.QtWidgets import QApplication,QMainWindow,QWidget,\
                            QVBoxLayout,\
                            QLineEdit,\
                            QPushButton
from PyQt5 import QtCore
from PyQt5.uic import loadUi
import sys 


class MyWidget(QWidget):
    def __init__(self,parent):
        super(MyWidget, self).__init__()
        self.start=QPushButton("Start",parent)
        self.pause=QPushButton("Pause",parent)
        self.end=QPushButton("End",parent)
        self.line=QLineEdit()
        
        self.start.pressed.connect(self.OnStart)
        self.pause.clicked.connect(self.OnPause)
        self.end.clicked.connect(self.OnEnd)
        
        self.layout=QVBoxLayout()
        self.layout.addWidget(self.start)
        self.layout.addWidget(self.pause)
        self.layout.addWidget(self.end)
        self.layout.addWidget(self.line)
        self.line.textChanged.connect(self.doSomething)

    def doSomething(self):
        print("do")

    def OnStart(self):
        print("start")
    def OnPause(self):
        print("pause")
    def OnEnd(self):
        print("end")

class TheWindow(QMainWindow):
    def __init__(self):
        super(TheWindow, self).__init__()
        self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinimizeButtonHint)
        loadUi('template.ui', self)     
        the_widget=MyWidget(self)
        self.horizontalLayout.addLayout(the_widget.layout)



QApplication.setAttribute(QtCore.Qt.AA_Use96Dpi)
app = QApplication([])
app.aboutToQuit.connect(app.deleteLater)
widget = TheWindow()
widget.show()
sys.exit(app.exec_())

我用Qt Designer制作的UI模板在这里 https://github.com/vChavezB/PyQt5_Button_layout

问题与变量的所有权以及发送者或接收者被移除时信号的行为有关。 the_widget 是一个变量,除非某个对象占有该变量,否则它将被销毁,但是 none 这样做它会立即销毁,并且由于该对象是连接的接收者,因此连接也将被消除.为什么按钮和布局没有被破坏?好吧,因为布局是在另一个布局中建立的,所以第二个布局拥有所有权,并且由于按钮由布局管理,因此它们将是添加了布局的小部件的子项,并且这种亲属关系使父项成为小部件取得按钮的所有权。

注意:如果仅用于创建其他小部件,则创建从 QWidget 继承的 class 没有意义。

在这种情况下,最好在同一个布局中建立 class 然后将小部件添加到布局中:

class MyWidget(QWidget):
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)
        self.start = QPushButton("Start")
        self.pause = QPushButton("Pause")
        self.end = QPushButton("End")
        self.line = QLineEdit()

        self.start.pressed.connect(self.OnStart)
        self.pause.clicked.connect(self.OnPause)
        self.end.clicked.connect(self.OnEnd)

        lay = QVBoxLayout(self)
        lay.addWidget(self.start)
        lay.addWidget(self.pause)
        lay.addWidget(self.end)
        lay.addWidget(self.line)
        self.line.textChanged.connect(self.doSomething)

    def doSomething(self):
        print("do")

    def OnStart(self):
        print("start")

    def OnPause(self):
        print("pause")

    def OnEnd(self):
        print("end")


class TheWindow(QMainWindow):
    def __init__(self):
        super(TheWindow, self).__init__()
        self.setWindowFlags(
            QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinimizeButtonHint
        )
        loadUi("template.ui", self)
        the_widget = MyWidget()
        self.horizontalLayout.addWidget(the_widget)