简体   繁体   中英

Separating application logic and view in Qt Widgets

I was wondering: what is the 'official' coding style when programming a Qt Widgets application. I'm specifically referring to keeping logic and view code separate.

The default Qt Designer way makes it very tempting to just throw everything in one class. In fact, there's a lot of code examples out there that show you can consider MainWindow.cpp as a 'throw all your globals in here' class.

As a simple example, your application can require a QNetworkAccessManager . You can store this in your MainWindow and then pass it to any window you open.

But this is the start of putting a whole lot of other logic in your MainWindow . If you then want to convert that application to QML, you have a problem. If you had created a controller class that in turn instantiates the Window or widget, or accepts the controller as constructor argument, so that you can connect view and controller with signals and slots, you would have been able to replace the view with something else, yet retain the logic. Seems a lot better to me, yet doesn't seem to be the norm.

Is it still considered bad practice to use widget/window classes (derived from QMainWindow , QWidget ) for logic, even though you see it everywhere?

I think it's not a good idea to bring all of the code in just one class or one even one module. You would encounter many difficulties changing parts because one part is changed specially when your application becomes larger over time.

I personally use Subdirs to separate parts of my code (Logic, GUI). Using Subdirs is a good idea to separate code modules from each other. This way you can have independent software modules which are reusable and able to be changed easily. It also makes the project much cleaner and easier to read.

In this approach the modules can interact with each other through signals and slots which makes different components completely independent and changing one module does not require changing other parts.

Qt Creator provides good automation in liking the parts to each other. You can make a Subdirs project and add your subprojects to its .pro file :

TEMPLATE = subdirs

CONFIG += ordered

SUBDIRS += \
    Component1 \
    Component2 \
    Component3 \
    MainApp \

You should bring the subprojects that others depend on, first in the list. Also notice that the name of the .pro file of the subproject should be the same as it's folder name. This way the subprojects are detected and listed in the Projects pane.

The subprojects Component1 , Component2 and Component3 could be libraries. Part of .pro file for Component1 :

TARGET = Component1
TEMPLATE = lib

DEFINES += COMPONENT1_LIBRARY

SOURCES += ...
HEADERS += ...

The subproject MainApp can be app. Part of .pro file for MainApp :

TARGET = MainApp
TEMPLATE = app

You can use the libraries in each subproject by linking it to the subproject. This can be done by right clicking on the subproject and choosing Add Library and then Internal Library . When you select one library from the list of subprojects, the linking configurations are added to the .pro automatically. It will be like :

win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../Component1/release/ -lComponent1
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../Component1/debug/ -lComponent1
else:unix: LIBS += -L$$OUT_PWD/../Component1/ -lComponent1

INCLUDEPATH += $$PWD/../Component1
DEPENDPATH += $$PWD/../Component1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM