如何在对象中包装 QFileDialog 和 QPushButton
How to wrap a QFileDialog and QPushButton in an object
这是我的代码:
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_())
window中有两个按钮:"buttonA"和"button B"。
按钮A正常,可以成功打开QFileDialog
.
按钮 B 在 class 中定义,应该像按钮 A 一样工作,但它不会打开 QFileDialog
。如果将 browse
方法更改为 lambda 函数,它会起作用。为什么 browse
方法不起作用?
问题是 DicAsk
没有定义为 PyQt 对象。它只是定义为一个基本的python class,所以它的方法不能是插槽。 DicAsk.browse
在您单击按钮 B 时永远不会被调用。
真正的问题是您没有保留对 dicAsk
的引用。它在Window.__init__
中本地定义,然后被销毁。您仍然可以使用 dicAsk.buttton
,因为它已添加到布局中(window
成为 dicAsk.button
的父级,因此保留对按钮的引用)
要解决此问题,您可以使用 self.dicAsk=DicAsk()
保留参考,或修改 class 以拥有父级:
class DicAsk(QtCore.Qobject):
def __init__(self,parent):
super(DicAsk, self).__init__(parent)
#in Window
dicAsk=DicAsk(self)
另一种解决问题的方法是 subclass 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")
这更有意义,因为您想要的是自定义按钮。
这是我的代码:
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_())
window中有两个按钮:"buttonA"和"button B"。
按钮A正常,可以成功打开QFileDialog
.
按钮 B 在 class 中定义,应该像按钮 A 一样工作,但它不会打开 QFileDialog
。如果将 browse
方法更改为 lambda 函数,它会起作用。为什么 browse
方法不起作用?
问题是 DicAsk
没有定义为 PyQt 对象。它只是定义为一个基本的python class,所以它的方法不能是插槽。 DicAsk.browse
在您单击按钮 B 时永远不会被调用。
真正的问题是您没有保留对 dicAsk
的引用。它在Window.__init__
中本地定义,然后被销毁。您仍然可以使用 dicAsk.buttton
,因为它已添加到布局中(window
成为 dicAsk.button
的父级,因此保留对按钮的引用)
要解决此问题,您可以使用 self.dicAsk=DicAsk()
保留参考,或修改 class 以拥有父级:
class DicAsk(QtCore.Qobject):
def __init__(self,parent):
super(DicAsk, self).__init__(parent)
#in Window
dicAsk=DicAsk(self)
另一种解决问题的方法是 subclass 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")
这更有意义,因为您想要的是自定义按钮。