Script upgraded from the Py-Qt-MVC written by 'morefigs'. His orignal work can be found there : https://github.com/morefigs/Py-Qt-MVC
. Large parts of the following Readme are copied directly from the orignal.
Script for auto-generating Model-View-Controller application template files for PyQt5 and Python 3.
Manually creating model, view, controller, and application Python files can be tedious, repetitive, and error prone when dealing with a large number of widgets. This script auto-generates templates of these files based on an input file containing a list of widgets names. It generates code for the following classes:
- View class
- imports and builds UI code auto-generated by
pyuic5
- getter/setter style properties for the value each widget
- getter/setter style properties for the enabled state value of each widget
setModel
functions for widget types compatible with Qt models- widget signal connections
- signal event functions
- a function to update widget values upon announced changes to the model data
- Controller class
- signal event functions
- Model class
- getter/setter style properties for the value of each Qt model
- ConfigParser section and options variables
- creation of Qt models for compatible widget types
- variable name placeholders
- functions for subscribing to and announcing changes to the model data
- Application class
- instantiation of model, view, and controller classes
See also this Stack Overflow post: http://stackoverflow.com/a/26699122/1470749
py3_pyqt5_mvc.py widget_names.txt
where widget_names.txt
is a text file containing a widget name on each line, and each widget name starts with the widget type, e.g. pushButton_my_button
.
Given a text file containing the widget name of comboBox_my_combo_box
, the following code would be generated:
#####################
# views\MainView.py #
#####################
from PyQt5 import QtWidgets
from gen.ui_MainView import Ui_MainView
class MainView(QtWidgets.QMainWindow):
#### properties for widget value ####
@property
def my_combo_box(self):
return self.ui.comboBox_my_combo_box.currentIndex()
@my_combo_box.setter
def my_combo_box(self, value):
self.ui.comboBox_my_combo_box.setCurrentIndex(value)
#### properties for widget enabled state ####
@property
def my_combo_box_enabled(self):
return self.ui.comboBox_my_combo_box.isEnabled()
@my_combo_box_enabled.setter
def my_combo_box_enabled(self, value):
self.ui.comboBox_my_combo_box.setEnabled(value)
def __init__(self, model, main_ctrl):
self.model = model
self.main_ctrl = main_ctrl
super(MainView, self).__init__()
self.build_ui()
# register func with model for model update announcements
self.model.subscribe_update_func(self.update_ui_from_model)
def build_ui(self):
self.ui = Ui_MainView()
self.ui.setupUi(self)
#### set Qt model for compatible widget types ####
self.ui.comboBox_my_combo_box.setModel(self.model.my_combo_box_model)
#### connect widget signals to event functions ####
self.ui.comboBox_my_combo_box.currentIndexChanged.connect(self.on_my_combo_box)
def update_ui_from_model(self):
print 'DEBUG: update_ui_from_model called'
#### update widget values from model ####
self.my_combo_box = self.model.my_combo_box
#### widget signal event functions ####
def on_my_combo_box(self, index): self.main_ctrl.change_my_combo_box(index)
###########################
# ctrls\MainController.py #
###########################
from PyQt5 import QtWidgets
class MainController(object):
def __init__(self, model):
self.model = model
#### widget event functions ####
def change_my_combo_box(self, index):
self.model.my_combo_box = index
print 'DEBUG: change_my_combo_box called with arg value:', index
##################
# model\Model.py #
##################
from PyQt5 import QtGui
class Model(object):
#### properties for value of Qt model contents ####
@property
def my_combo_box_items(self):
return self.my_combo_box_model.stringList()
@my_combo_box_items.setter
def my_combo_box_items(self, value):
self.my_combo_box_model.setStringList(value)
def __init__(self):
self._update_funcs = []
self.config_section = 'settings'
self.config_options = (
('my_combo_box', 'getint'),
)
#### create Qt models for compatible widget types ####
self.my_combo_box_model = Qt.QStringListModel()
#### model variables ####
self.my_combo_box = None
def subscribe_update_func(self, func):
if func not in self._update_funcs:
self._update_funcs.append(func)
def unsubscribe_update_func(self, func):
if func in self._update_funcs:
self._update_funcs.remove(func)
def announce_update(self):
for func in self._update_funcs:
func()
##########
# App.py #
##########
import sys
from PyQt5 import Qt
from model.Model import Model
from ctrls.MainController import MainController
from views.MainView import MainView
class App(Qt.QApplication):
def __init__(self, sys_argv):
super(App, self).__init__(sys_argv)
self.model = Model()
self.main_ctrl = MainController(self.model)
self.main_view = MainView(self.model, self.main_ctrl)
self.main_view.show()
if __name__ == '__main__':
app = App(sys.argv)
sys.exit(app.exec_())