python - 从小部件调用主窗口中的函数 (PySide)

标签 python pyside signals-slots qfiledialog

基本上我想要的是:

  1. 在主窗口中显示一个小部件,其中包含打开 QFileDialog 的按钮
  2. 选择文件后,包含按钮的小部件应切换到新的小部件,该新小部件会显示一些基于文件内容的可视化效果。

在下面的代码示例中,这意味着从 showFileSelectionDialog() 方法调用 open_file() 方法。

问题是如何做到这一点?我尝试在初始化小部件时将父级作为参数,然后将按钮连接到 self.parent.open_file 。但这变得很复杂,而且我不喜欢将小部件硬编码为主窗口的子窗口。

据我所知,更好的方法是使用 Communicate() 来发出事件。但后来我不知道如何将文件名信息获取到open_file()方法。

#Code greatly inspired by the ZetCode PySide tutorial (http://zetcode.com/gui/pysidetutorial/)

import sys
from PySide import QtGui

class MainApplicationWindow(QtGui.QMainWindow):

    def __init__(self):
        super(MainApplicationWindow, self).__init__()

        self.initUI()

    def initUI(self):

        self.setWindowTitle('<Application title>')
        self.setCentralWidget(FileSelectWidget())
        self.statusBar()

        self.resize(250, 200)
        self.center()
        self.show()

    def center(self):
        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def open_file(self, file_name):
        f = open(file_name, 'r')
        with f:
            data = f.read()
            #TODO: Do something with the data and visualize it!
            print data

class FileSelectWidget(QtGui.QWidget):

    def __init__(self):
        super(FileSelectWidget, self).__init__()

        self.initUI()

    def initUI(self):

        selectLogFilesButton = QtGui.QPushButton('Select log files', self)
        selectLogFilesButton.clicked.connect(self.showFileSelectionDialog)

        hbox = QtGui.QHBoxLayout()
        hbox.addStretch()
        hbox.addWidget(selectLogFilesButton)
        hbox.addStretch()

        vbox = QtGui.QVBoxLayout()
        vbox.addStretch()
        vbox.addLayout(hbox)
        vbox.addStretch()

        self.setLayout(vbox)

    def showFileSelectionDialog(self):

        file_name, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', '/home')


def main():

    app = QtGui.QApplication(sys.argv)
    window = MainApplicationWindow()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

最佳答案

FileSelectWidget 类应定义一个可以连接到 open_file 插槽的自定义信号。

为此,请确保导入 QtCore 模块,然后定义自定义信号,如下所示:

class FileSelectWidget(QtGui.QWidget):
    fileSelected = QtCore.Signal(object)

然后每当选择文件时发出信号:

    def showFileSelectionDialog(self):
        file_name, _ = QtGui.QFileDialog.getOpenFileName(
                           self, 'Open file', '/home')
        if file_name:
            self.fileSelected.emit(file_name)

最后,将信号连接到插槽:

    widget = FileSelectWidget()
    widget.fileSelected.connect(self.open_file)
    self.setCentralWidget(widget)

关于python - 从小部件调用主窗口中的函数 (PySide),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19934123/

相关文章:

python - 为什么 pandas.DataFrame.apply 打印出垃圾?

python - 三重嵌套和 Numpy

python - 如何在布局中设置正确的列大小 - PySide/PyQt

python - PySide 获取 QSpinBox 中箭头按钮的宽度

python - 如何从 PySide QAbstractItemModel 子类向 QML ListView 提供数据?

python - 如何使用 OAuth 从 Python 应用程序访问 Google App Engine 端点 API?

python - 如何创建形状为 (0, 2) 的 numpy 数组?

c++ - 等待多个对象发出信号

c++ - 保持 GUI 独立

c++ - Qt Designer - 如何将信号连接到静态函数?