2

I am writing a Python Programm that mainly consists of Data organized in a Python object and I want to write a GUI using PyQt for it.

Since I want to be able to use the Python part without the GUI as well, I don't want Qt code in my Data structure. Qt encourages you to separate the data model from the GUI/View part of the program, so I thought this approach should be fairly common in PyQt. However I don't understand how the Data is to be connected and kept persistent with the GUI.

I think I understand the model/view concept - but it seems to me that the model in Qt terms is a Qt object as well and would need to be kept in sync with my pure python object so I don't see the point of it.

I guess there is still something crucial that I don't understand yet. Can anyone give me a hint?

Update 1:

Following Armatita's comment I give the following minimal example:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys
#Python Data:
class car:
    def __init__(self, name, color):
        self.name = name
        self.color = color

#Window:
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(650, 510, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.treeView = QtWidgets.QTreeView(self.centralwidget)
        self.treeView.setGeometry(QtCore.QRect(30, 20, 591, 481))
        self.treeView.setObjectName("treeView")
        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(680, 120, 113, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(630, 120, 46, 13))
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "Apply"))
        self.label.setText(_translate("MainWindow", "Value"))

if __name__ == "__main__":
    #create Data
    blue_car = car("family_car", "blue")
    red_car = car("sports_car", "red")

    #open UI
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

    #now I would like to show the cars and their properties (name, color) in the treeview...

In this Example I would like to show the cars I created in the tree view Widget and manipulate them with the input field an the apply button.

1
  • You can use pyQt as a GUI to your library. You do not need to store anything in Qt objects, you just need to tell pyQt what to show on screen (this is true even for C++ Qt). If a lot of people decide to store information in their Qt classes (i.e. Main Window) it is mostly out of convenience. There is nothing both in pyQt or Python that obliges you to do that. Do you have a specific example of what you are trying to do? Commented Feb 24, 2017 at 9:01

1 Answer 1

1

There are typically two types of interfaces to widgets in Qt. One is the view version, the other is the widget version (which inherits the view). The easiest to use is the widget version, and for what you seem to be trying to do it is what I recommend.

Also, although its possible to software the way you were doing it is generally better to follow the more common conventions. I've adapted your code (including the way you build the MainWindow) to have the small GUI working with a new method (addCar) to add your car class information to the QTreeWidget:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys
#Python Data:
class car:
    def __init__(self, name, color):
        self.name = name
        self.color = color

#Window:
class Ui_MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(Ui_MainWindow, self).__init__()

        self.setupUi()

    def setupUi(self):
        self.setObjectName("MainWindow")
        self.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(self)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(650, 510, 75, 23))
        self.pushButton.setObjectName("pushButton")

        # self.treeView = QtWidgets.QTreeView(self.centralwidget)
        self.treeView = QtWidgets.QTreeWidget(self.centralwidget)
        self.treeView.setColumnCount(1)
        self.treeView.setGeometry(QtCore.QRect(30, 20, 591, 481))
        self.treeView.setObjectName("treeView")

        self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit.setGeometry(QtCore.QRect(680, 120, 113, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(630, 120, 46, 13))
        self.label.setObjectName("label")
        self.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(self)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        self.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(self)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)

        self.retranslateUi()
        QtCore.QMetaObject.connectSlotsByName(self)

    def addCar(self, car, name):
        item = QtWidgets.QTreeWidgetItem([name])
        child1 = QtWidgets.QTreeWidgetItem(["Type: " + car.name])
        child2 = QtWidgets.QTreeWidgetItem(["Type: " + car.color])
        item.addChild(child1)
        item.addChild(child2)
        self.treeView.addTopLevelItem(item)

    def retranslateUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "Apply"))
        self.label.setText(_translate("MainWindow", "Value"))

if __name__ == "__main__":
    #create Data
    blue_car = car("family_car", "blue")
    red_car = car("sports_car", "red")

    #open UI
    app = QtWidgets.QApplication(sys.argv)
    # MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    # ui.setupUi(MainWindow)

    # Add car object
    ui.addCar(blue_car, "Blue Car")
    ui.addCar(red_car, "Red Car")

    ui.show()
    sys.exit(app.exec_())

The result is this:

Main Window and QTree Widget example

Also I recommend you try checking out an online quick tutorial for pyQt5 (arbitrary example: zetcode) since if you start building software now using the methodology it seems to me you were trying to apply you'll end up re-writing most of it in the future (I think...). I've made the same mistake in the past.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.