Использование сигналов для общения между классами - PullRequest
4 голосов
/ 04 марта 2012

Я хочу использовать signals для связи между моим представлением и контроллером приложения.У меня следующий подход, но так как я новичок в PyQt, я не знаю, правильный ли это.Может кто-нибудь сказать мне, если я на правильном пути или есть лучшие решения?

РЕДАКТИРОВАТЬ: я изменил пример на полностью рабочий пример.

1 Ответ

2 голосов
/ 04 марта 2012

Лично я не создаю отдельный общий класс контроллеров, подобный этому. Это может быть моим собственным предпочтением, но я склонен рассматривать фактический класс QWidget моим контроллером, и представление обычно является определениями только с графическим интерфейсом, которые я генерирую из QtDesigner (например, Ui_Dialog), или создаю вручную. И я делаю все свои соединения в соответствующем QWidget.

Теперь к вашему коду, я не знаю, рассматриваете ли вы этот фрагмент как общий псевдокод пример направления, в котором вы идете ... но в нем есть ошибки ... Я бы обычно предложите опубликовать рабочий код, чтобы люди не запутались в том, есть ли у вас ошибки из-за него, или просто спросите, является ли это в целом правильным направлением для выкладывания кода.

Вы забыли вызвать __init__() в суперклассе QMainWindow.

Я не уверен, что будет делать controller.show () (на данный момент не удалось), потому что я не вижу пример того, как вы намереваетесь перенаправить эту команду show () вашему объекту главного окна? Опять же, я не понимаю, зачем вообще нужен этот отдельный класс.

Вот как я мог бы увидеть более реалистичный пример, снова рассматривая сами классы QWidget в качестве контроллеров:

Посмотреть

## mainUI.py ##

from PyQt4 import QtCore, QtGui

class Ui_MyWidget(object):

    def setupUi(self, obj):
        obj.layout = QtGui.QVBoxLayout(obj)

        obj.cbFoo = QtGui.QComboBox()
        obj.cbBar = QtGui.QComboBox()

        obj.layout.addWidget(self.cbFoo)
        obj.layout.addWidget(self.cbBar)

Модуль библиотеки не-Gui (контроллер)

## nonGuiModule.py ##

class LibModule(object):

    def handleBarChanged(self, *args):
        print("Bar Changed: %s" % args)

Контроллер (любая точка входа)

## main.py ##

import sys
from PyQt4 import QtCore, QtGui

from mainUI import Ui_MyWidget
from nonGuiModule import LibModule


class Main(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(Main, self).__init__(parent)

        self.resize(640,480)

        self._lib = LibModule()

        self.myWidget = MyWidget(self)
        self.setCentralWidget(self.myWidget)

        self.myWidget.sigFooChanged.connect(self.handleFooChanged)
        self.myWidget.sigBarChanged.connect(self._lib.handleBarChanged)


    def handleFooChanged(self, *args):
        print("Foo Changed: %s" % args)


class MyWidget(QtGui.QFrame, Ui_MyWidget):

    sigFooChanged = QtCore.pyqtSignal(str)  
    sigBarChanged = QtCore.pyqtSignal(str) 

    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)

        # this is where you set up from the view
        self.setupUi(self)

        self.cbFoo.addItems(['Foo1', 'Foo2'])
        self.cbBar.addItems(['Bar1', 'Bar2'])

        self.layout.addWidget(self.cbFoo)
        self.layout.addWidget(self.cbBar)

        # going to forward private signals to public signals
        self.cbFoo.currentIndexChanged[str].connect(self.sigFooChanged)
        self.cbBar.currentIndexChanged[str].connect(self.sigBarChanged)


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv[1:])
    view = Main()
    view.show()
    sys.exit(app.exec_())
...