将信息从小部件模块传递到主窗口

时间:2013-08-12 16:21:00

标签: python pyqt

如果我有一个非常简单(自包含,可重复)的程序如下:

import sys
from PyQt4 import QtCore, QtGui, Qt

class mainWrapper(QtGui.QMainWindow):

  def __init__(self):
    super(mainWrapper, self).__init__()
    self.resize(800, 600)    
    self.statusBar().showMessage('Welcome to my 1st project')

    self.tw = testWidget()
    fileName = self.tw.open()

    self.setCentralWidget(Qt.QLabel(str(fileName)))
    self.statusBar().showMessage("Showing file " + str(fileName))

  def open(self):
    fileName = QtGui.QFileDialog.getOpenFileName(self, "Open File",
        QtCore.QDir.currentPath())
    if fileName.isNull():
      QtGui.QMessageBox.information(self, "test project",
         "Cannot load %s." % fileName)
    print fileName
    return fileName 

  if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    mw = mainWrapper()
    mw.show()
    sys.exit(app.exec_())  

然后根据需要在主窗口和状态栏中打印文件名。如果我修改代码将其分成2个模块,为了开始为更大的项目(从长远来看......)开始有一些构建块,那么我得到:

testMainWindow.py

import sys
from PyQt4 import QtCore, QtGui, Qt

from testWidget import testWidget_widget

class mainWrapper(QtGui.QMainWindow):

  def __init__(self):
  super(mainWrapper, self).__init__()
  self.resize(800, 600)    
  self.statusBar().showMessage('Welcome to my 1st project')

  self.tw = testWidget()
  fileName = self.tw.open()

  self.setCentralWidget(Qt.QLabel(str(fileName)))
  self.statusBar().showMessage("Showing file " + str(fileName))

if __name__ == '__main__':
  app = QtGui.QApplication(sys.argv)
  mw = mainWrapper()
  mw.show()
  sys.exit(app.exec_())   

testWidget.py

from PyQt4 import QtCore, QtGui, Qt

class testWidget(QtGui.QWidget):

def __init__(self):
  super(testWidget, self).__init__()
  print "ImageViewer_widget called successfully"

def open(self):
  fileName = QtGui.QFileDialog.getOpenFileName(self, "Open File",
        QtCore.QDir.currentPath())
  if fileName.isNull():
    QtGui.QMessageBox.information(self, "test project",
         "Cannot load %s." % fileName)
  print fileName
  return fileName 

然后我仍然按预期在主窗口和状态栏上打印文件名。但是,这只是self.tw.open()。我真正想要做的是在widget模块中设置内容,并在我的调用窗口小部件的方法中尽可能少地编写代码,理由是当这些模块变得更重要时,我想保留所有该模块中与testWidget相关的代码。但是,鉴于setCentralWidget只是QMainWindow的一种方法,实现这一目标的最佳方法是什么?

当然,我可能完全错过了关于PyQt的观点,而且我完全错误地设计了我的模块的工作方式。如果是这种情况,请随意将我推回正确的方向......

1 个答案:

答案 0 :(得分:1)

这个问题有点模糊,只是因为你必须就用户如何与GUI交互做出一些设计决定。第一次尝试可能涉及以下一些事项:

1)向您的小部件添加一个信号,让它设置自己的名称。当它改变名称时,也会发出新名称的信号。

class testWidget(QtGui.QLabel):

    textChanged = QtCore.pyqtSignal(object)

    def open(self):
        fileName = QtGui.QFileDialog.getOpenFileName(self, "Open File",
                                                QtCore.QDir.currentPath())
        if fileName.isNull():
            QtGui.QMessageBox.information(self, "test project",
                                          "Cannot load %s." % fileName)
        self.setText(fileName)
        self.textChanged.emit(fileName)

2)添加小部件,并将其信号连接到主窗口中的插槽(回调)以更新其状态栏。

class mainWrapper(QtGui.QMainWindow):

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

  def init_ui(self):
    self.resize(800, 600)    
    self.statusBar().showMessage('Welcome to my 1st project')
    self.tw = testWidget()
    self.setCentralWidget(self.tw)
    self.tw.textChanged.connect(self.update_status_bar)
    self.tw.open()

  def update_status_bar(self, f):
    self.statusBar().showMessage("Showing file " + f)

if __name__ == '__main__':
  app = QtGui.QApplication(sys.argv)
  mw = mainWrapper()
  mw.show()
  mw.init_ui()
  sys.exit(app.exec_())  

**正如您所看到的,这实际上只适用于一个显示小部件。如果要添加更多小部件,则必须使中央小部件成为通用小部件,设置其布局,并将其他小部件添加到其布局中。