chwi chwi - 3 months ago 16
Python Question

Connecting signals to slots up the directory tree with PySide

I am trying to separate UI components from functional code as much as I can, so my PySide is application structured like this

main.py
package\
app.py
__init__.py
ui\
mainwindow.py
__init__.py


Main is just a simple starter

if __name__ == '__main__':
import sys
from package import app
sys.exit(app.run())


and app is where all the functionality should reside. I start the UI from app.py

from PySide import QtCore, QtGui

@QtCore.Slot()
def start_button_clicked():
print "started"

def run():
import sys
from ui.mainwindow import Ui_MainWindow
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())


Now, from the user interface I want to connect the emitted signals up to the app.py to avoid having a lot of functionality cluttering the mainwindow file, but the UI file is not aware of app.py. How should I go forth to do this and avoid all slots being in mainwindow.py? app.py should easily be able to do stuff on the UI since it has a object reference to it, but I have no clue on the other way around.

Answer

Create a subclass for the top-level widget from Qt Designer. Using this approach, all of child widgets from Qt Designer will become attributes of the subclass:

import sys
from PySide import QtCore, QtGui
from ui.mainwindow import Ui_MainWindow

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.start_button.clicked.connect(self.start_button_clicked)

    def start_button_clicked(self):
        print "started"

if __name__ == '__main__':

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