如何在对象中包装QFileDialog和QPushButton

时间:2015-11-16 05:32:24

标签: python pyqt5 qfiledialog

这是我的代码:

from PyQt5.QtCore import (
    QDir
)
from PyQt5.QtWidgets import(
    QApplication,QDialog,
    QVBoxLayout,QGridLayout,QPushButton,QFileDialog
)

class DicAsk(object):
    def __init__(self):
        super(DicAsk, self).__init__()
        self.button = QPushButton("ButtonB")
        self.button.clicked.connect(self.browse)
        # self.button.clicked.connect(lambda:QFileDialog.getExistingDirectory(None, "Find Files",
        #     QDir.currentPath()))
    def browse(self):
        directory = QFileDialog.getExistingDirectory(None, "Find Files",
            QDir.currentPath())

class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        buttonA = QPushButton("ButtonA")
        buttonA.clicked.connect(self.browse)

        dicAsk = DicAsk()

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(buttonA)
        mainLayout.addWidget(dicAsk.button)
        self.setLayout(mainLayout)

    def browse(self):
        directory = QFileDialog.getExistingDirectory(None, "Find Files",
            QDir.currentPath())

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

窗口中有两个按钮:“buttonA”和“按钮B”。 按钮A工作正常,它可以成功打开QFileDialog

按钮B在类中定义,应该像按钮A一样工作,但它不会打开QFileDialog。如果将browse方法更改为lambda函数,则它可以正常工作。为什么browse方法不起作用?

1 个答案:

答案 0 :(得分:2)

问题是DicAsk未定义为PyQt对象。它只定义为基本的python类,因此它的方法不能是槽。单击按钮B时,永远不会调用DicAsk.browse

真正的问题是你没有保留对dicAsk的引用。它在Window.__init__中本地定义,然后销毁。您仍然可以使用dicAsk.buttton,因为它已添加到布局中(window成为dicAsk.button的父级,因此保留对该按钮的引用)

要解决此问题,您可以使用self.dicAsk=DicAsk()保留引用,或修改类以拥有父级:

class DicAsk(QtCore.Qobject):
    def __init__(self,parent):
        super(DicAsk, self).__init__(parent)

#in Window
dicAsk=DicAsk(self)

解决问题的另一种方法是继承QPushButton

class MyButton(QPushButton):
    def __init__(self,parent=None):
        super(MyButton, self).__init__(parent)
        self.setText("ButtonB")
        self.clicked.connect(self.browse)

    def browse(self):
        print("browse")

它更有意义,因为你想要的是一个自定义按钮。