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

时间:2013-11-12 16:08:10

标签: python pyside signals-slots qfiledialog

基本上我想要的是:

  1. 在主窗口中显示一个小部件,其中包含一个打开QFileDialog
  2. 的按钮
  3. 当选择文件时,包含该按钮的窗口小部件应切换到新窗口小部件,该窗口小部件显示基于文件内容的一些可视化。
  4. 在下面的代码示例中,这意味着从open_file()方法调用showFileSelectionDialog()方法。

    问题是如何做到这一点?我在初始化窗口小部件然后将按钮连接到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()
    

1 个答案:

答案 0 :(得分:2)

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)