I have attempted the GUI controls creation in a prompt based on data from dictionary. Is this the best way of implementing this?

import sys
from PyQt4 import QtCore, QtGui

class MessageBox(QtGui.QDialog):
    """docstring for MessageBox"""
    def __init__(self, data=None, parent=None):
        super(MessageBox, self).__init__(parent)
        self._data = data

    def buildUi(self):
        self.gridLayout = QtGui.QGridLayout()
        for index, (key, values) in enumerate(self._data.iteritems()):
            getLbl = QtGui.QLabel("Get", self)
            label = QtGui.QLabel(key, self)
            chkBox = QtGui.QCheckBox(self._data[key][0], self)
            chkBox.setToolTip("Click here to get the book")
            version = QtGui.QSpinBox( self)
            version.setRange(self._data[key][-1], 12)
            self.gridLayout.addWidget(getLbl, index, 0)
            self.gridLayout.addWidget(label, index, 1)
            self.gridLayout.addWidget(chkBox, index, 2)
            self.gridLayout.addWidget(version, index, 3)
        self.layout = QtGui.QVBoxLayout()
        self.okBtn = QtGui.QPushButton("OK")
        self.horLayout = QtGui.QHBoxLayout()

class MainWindow(QtGui.QMainWindow):
    """docstring for MainWindow"""
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        # self.widget = FormWidget()
        self._data = {
                'Contact':['Carl Sagan', 2],
                'End of Faith':['Sam Harris', 7],
                'On Mars':['Patrick Moore', 1],

        self.btn = QtGui.QPushButton("Hello", self)


    def _launchMessageBox(self):
        dlg = MessageBox(self._data)

def main():
    app = QtGui.QApplication(sys.argv)
    window =  MainWindow()
    # window.raise_()

if __name__ == '__main__':

This will work, but it may be hard to scale. At a minimum, I'd create a separate class for the work you're doing in the enumerate loop so that the dialog class is only concerned with populating a widget list and the details of what the widgets look like internally are handled in a class that just pops out book widgets - that will make for cleaner code and easier maintenance.

The more 'modern' way to do this is some variant on the MVC (Model-View-Controller) or MVVM (Model -view - viewmodel) patterns. The basic idea is the same - create a factory which produces display widgets for the items in a list of some kind. The main difference its that the MVVM pattern encourages you to split out the different aspects of the problem -- managing the contents of the list, displaying parts of the list, and interactng with the list items -- into distinct parts of the code (the 'model', the 'view' and the 'viewmodel' or 'controller') respectively. (There's a whole lot of programmer-on-programmer controversy about MVC vs MVVM - background here.)

In this example, going with an MV* pattern offers facilities like filtering a list ('show only books from 2013'), enabling/disabling list items ('gray out the books over $50') without lots of tedious looping codes. Plus you could potentially do things like design your widgets in the QT designer for better layout, etc without touching the code directly.

All this lets you decouple the UI functionality (views, filters, appearance) from the data. As your lists get bigger, and the need to manage their contents gets more complex, this is a big help in staying sane.

Yasin from TAO has nice, detailed Youtube tutorial on this approach.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.