Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Design pattern for GUI and NON GUI mode.



  • I am trying to create an QT application which can run in GUI and NON-GUI mode.

    The goal is all the work that has to be done in GUI mode should also be done in Non-GUI mode but in NON-GUI mode I will not have overhead of creating the instance of GUI and so my code works faster.

    Can anyone please suggest me good design pattern for this ?

    In GUI mode I need to have abstraction with GUI in GUI mode and in NON-GUI mode the GUI mode should be replaced by empty stub something like that ?

    Please provide some suggestions.


  • Lifetime Qt Champion

    @Ayush-Gupta said in Design pattern for GUI and NON GUI mode.:

    all the work that has to be done

    What kind of work is that?
    The simple solution is to put this work in gui independant modules (cpp files) and use these modules in both modes to do the actual work.



  • It will be dll which will be called by other applications. In Non-gui mode it should process all the data (without intialising the UI component) and in GUI mode it should process all the data but present information in form of GUI to the user and user can able to input it manually.



  • @Ayush-Gupta
    Unless @jsulm says otherwise: my thought would be to provide two DLLs, one uses no UI stuff at all, the other does use UI and makes calls into the non-UI for services.



  • The problem is I am already having code implemented but the code of GUI is tightly coupled with code with NON-GUI.

    I want to run application in both GUI and NON-GUI mode. In NON-GUI mode there should be no overhead of creating instance of GUI components (forms etc) but in GUI all instances of form etc should be created.

    I need to refactor my existing code without doing much over head.

    And the GUI components should be initialised and created in GUI mode only.

    Is any design pattern can be pushed for abstraction ?



  • Looks like you can do what you want using QApplication.

    Check this out, there is even detailed information on how to do it, although I've never tried it, looks promising.

    https://doc.qt.io/qt-5/qapplication.html#details

    Here is an excerpt:

      QCoreApplication* createApplication(int &argc, char *argv[])
      {
          for (int i = 1; i < argc; ++i)
              if (!qstrcmp(argv[i], "-no-gui"))
                  return new QCoreApplication(argc, argv);
          return new QApplication(argc, argv);
      }
    
      int main(int argc, char* argv[])
      {
          QScopedPointer<QCoreApplication> app(createApplication(argc, argv));
    
          if (qobject_cast<QApplication *>(app.data())) {
             // start GUI version...
          } else {
             // start non-GUI version...
          }
    
          return app->exec();
      }
    

  • Lifetime Qt Champion

    Hi
    This is the classic pattern where you want to separate the data and presentation.
    So you want to move all code to from Mainwindow to a separate non-gui class
    that handles the data and its processing as a unit.
    Then change Mainwindow to simply call methods of this data handler class both to alter data and
    to get data to show.

    For the non gui application, you would then simply call the methods of the data handler class
    as needed.

    so basically the first task is to decouple all data processing from MainWindow to
    own class.



  • @Ayush-Gupta Have you looked into Hexagonal Architecture? Netflix Tech Blog has a good explanation: https://netflixtechblog.com/ready-for-changes-with-hexagonal-architecture-b315ec967749
    A way to apply to a Qt application means your DLL exposes only "business logic classes", that communicate by means of signal and slots. You can think the classes in the DLL being Lego pieces.
    Then in the main (a.k.a. composition root a.k.a the one that assembles Lego pieces together to create a sculpture) you wire DLL classes together and to your GUI (if you have one) in order to make them act as you would.
    Bear in mind that I am not speaking in theory, most of software that was developed [at least in part] by me follows this structure and has proven to be {fully AND easily} testable, easy to adapt/change and rock solid.



  • @mrjj In the case shoukd I not create instance of MainWindow class for non-gui mode?

    In GUI mode how can I connect signal/slots of core with GUI?


  • Lifetime Qt Champion

    @Ayush-Gupta

    Exactly. Structure the code so all logic, data processing and handling is with the classes so it can do the same with and without a MainWindow.

    If you let core classes inherit QObject ( and add the macro also)
    then you can directly use signal and slot regardless of gui / non gui.



  • @mrjj Would this be good desgin to inherit Q_OBJECT to core class?
    And if we do not intialise GUI in non-gui mode but still signal will be sent to core.
    Won't that extra burden to the core application where emitting signal not required for non-gui application?


  • Lifetime Qt Champion

    @Ayush-Gupta
    Hi
    The price is not that high for normal designs,
    as you won't have a thousand instances of core class etc .

    Also signal and slots are a core design element in Qt
    so even non-GUI classes like network use signals & slots so
    if your goal is to have the same code work with both a GUI on top and via command line, i
    would surely use signals and slots with "core"

    Its only if you wanted core to be 100% clean of any Qt so it could also be used without any Qt at all, i would resort to use callback etc.

    The signal and slot system is just much better than classic callbacks.


  • Lifetime Qt Champion

    Hi,

    I think I have at least partly answered on your other thread with regard to that.

    From your description, it feels like you are currently trying to couple these two modes too much in one single application.

    I'd recommend taking some time to do a bit of design so you can really cleanly separate the functionalities which belongs to each type of application.

    This makes me think a bit of linux daemons. Many of them are running in the background as they should be have an API that you can use to talk with them for example using DBus. With that you can write a GUI that's completely decoupled from the "core" part that keeps running its life.



  • @SGaist said in Design pattern for GUI and NON GUI mode.:

    DBus

    What if I need to update the GUI in seperate thread ?



  • My GUI and core will be called by other application and it will provided in one dll application.
    So I need to communicate between core and GUI with one dll and update the GUI in seperatee thread,

    Below is the flow which I need to design.

    Application <-----> Get Data <----->
    QT Application ----> Core
    <------>Set Data<-----> -----> Gui ( The data in GUI should be
    updated in seperate thread
    but data should come from
    core)


  • Lifetime Qt Champion

    @Ayush-Gupta said in Design pattern for GUI and NON GUI mode.:

    What if I need to update the GUI in seperate thread ?

    This is not supported!
    If you need to update the UI from other thread then simply emit signals from that thread and update UI in the slots in main thread.



  • @jsulm Slot will be in GUI part only and signal will emitted from core.
    so should I do event processing in diffrent thread?


  • Lifetime Qt Champion

    @Ayush-Gupta said in Design pattern for GUI and NON GUI mode.:

    so should I do event processing in diffrent thread?

    Events are not related to signals/slots



  • There are lot of lag in my system which involved this QT application also.

    I need to reduce lags by creating a headless mode application (without GUI). and also if GUI is launched then it should be updated in a diffrent thread.

    I understand that seperating core and GUI works here. with signal/slots core and GUI can communicate.

    I also know that processEvents() should be called to keep GUI alive if we dont call app->exec(),

    How can I update GUI in seperate thread ? Is the processEvents() is causes lag which I need to call and process in extra thread?

    Or signal/slots are also burder?


  • Lifetime Qt Champion

    @Ayush-Gupta said in Design pattern for GUI and NON GUI mode.:

    How can I update GUI in seperate thread ?

    Again: you do NOT update GUI from another thread as GUI thread! This is simply not supported.
    Your other thread should only tell GUI thread to update.

    "Or signal/slots are also burder?" - in what way?

    "Is the processEvents() is causes lag" - if you're using processEvents then your design is most likely broken. It should not be used. Simply start event loop, this is how Qt applications work.



  • starting event loop means here calling app->exec() ? But it makes the application blocking.


  • Lifetime Qt Champion

    @Ayush-Gupta said in Design pattern for GUI and NON GUI mode.:

    starting event loop means here calling app->exec()

    No.
    Please read documentation: https://doc.qt.io/qt-5/qthread.html
    " QThread object manages one thread of control within the program. QThreads begin executing in run(). By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread."



  • Yes I have read this,

    My QT application launches two forms (main window) then I called app->exec.

    Then other application use to update data in my QT application using dll interface functions.

    But if call app->exec() there in no update in GUI.

    I need to call processEvents() for that


  • Lifetime Qt Champion

    @Ayush-Gupta said in Design pattern for GUI and NON GUI mode.:

    But if call app->exec() there in no update in GUI.

    Where do you call this? In this DLL?
    I'm confused a bit with your description.
    Is this other app a completely different app (other process)?



  • Yes other app is different app (Non QT C++ application) which will call my QT application as dll application and will process the data from it and fetch the data using interface applications.


  • Lifetime Qt Champion

    @Ayush-Gupta said in Design pattern for GUI and NON GUI mode.:

    which will call my QT application

    In this case your Qt application is not an application but a DLL.
    In this case you can run your DLL in another thread where you call app->exec().
    But I'm still confused: is this other app a non-gui (console) app? If so why does it load a DLL which opens a GUI?
    It should be other way around: you have a GUI application (Qt) which uses a DLL. This DLL does the data processing and passes the data from/to Qt application.



  • Yes other app is non-gui console app.

    It opens other GUI to show and process the data sended by non-gui console app.

    But now I have to make my QT (DLL) in both headless mode (non-gui) and GUI mode in same DLL.

    Actually QT (DLL) is simulator of system and the other non-gui console app sends the data to QT dll app and QT DLL app also send data to non-gui console app


  • Lifetime Qt Champion

    Can you describe exactly the architecture of your system ?
    Because you are sending mixed messages here.
    At one point you wanted to have an application that you could run either with GUI or not.
    Now you have a console application that has some sort of DLL interface to drive an application and get fed by another one and one should support two different modes. That make everything unclear.

    If you could add a drawing of your design, that might also be of great help.



  • Here is some prototype I tried to draw
    ProtoType.PNG


  • Lifetime Qt Champion

    As I already suggest, you really should consider using IPC rather making your console application drive a GUI application by hand which will make it not a console application. Apply the Unix mantra: one tool that does its job well.

    See the various possibilities for inter-process communication. Missing there (fix under way), there's also QLocalServer/Socket.



  • @jsulm said in Design pattern for GUI and NON GUI mode.:

    But I'm still confused: is this other app a non-gui (console) app? If so why does it load a DLL which opens a GUI?
    It should be other way around: you have a GUI application (Qt) which uses a DLL. This DLL does the data processing and passes the data from/to Qt application.

    console application I need to keep as it is since it part of system.

    I need to work QT application (DLL).
    So you mean here two launch core and GUI as two different process and make the code in seperate DLL?


  • Lifetime Qt Champion

    @Ayush-Gupta Yes, starting GUI from console application makes it a GUI application. Look at what @SGaist suggested.



  • sorry it is so confusing for me.

    I have to create a QT application (in both GUI and NON-GUI) mode.... and my QT application should be in dll which will launch by other console application.

    So means creating two dlls for core and GUI and (core dll should launch) GUI dll ?

    and in NON-GUI mode the core dll should not launch GUI dll?

    and the commuincation between core dll and GUI dll will be using IPC?



  • @SGaist Can you please explain a little bit more?



  • @Ayush-Gupta your design is hopelessly broken and it won't work, you were told that many times (see above posts). And this is not Qt specific (on .NET platform it would be the same, for example). Actually, it could work in a "lite" version, but will break horribly later on, so please FORGET that. Please.
    Please take time to learn about how GUI works in general (message pumps, GUI threads, ...). Completely unrelated to Qt, but studying Win32 API will make you understand A LOT. GUI thread is usually the "main" thread, OS-speaking, so do not mess with displaying GUI in a worker thread.
    So, forget to have a "GUI DLL"; what you mean by this term has no sense whatsoever. Forget completely to have a "application DLL" (means the same as a "white black" or a "near place far, far away").
    Let's recap:

    • You have an existing "console" application that can load a DLL, plugin-like.
    • You want to exchange data between that application and some processing code, bidirectionally.

    One (of many) solution is making a DLL that exposes a socket interface (you could go first by TCP, because is easy to make bidirectional and lossless) and then develop an application (which can run on its own process and do not ever know what application is talking to) that connects to that socket and exchange messages with the other application. You could look into other IPC (inter-process communication) means and select the most suitable for you, since we do not know what application you want talk to, what it does, and what data exchanges, neither we know what you want to do on the other side (headless/GUI).

    Ah, completely forget updating the GUI every 25 ms with a retained mode GUI like Qt (or GTK, or WPF, or Windows Forms, or most GUI frameworks) on a "consumer" system. Your brain does not react so fast to structured information anyway.

    And... better if you pretend threads do not exists. It pays off a lot.



  • @jsulm @mrjj @Astrinus Still I am struggling with this.
    The requirement is that I have one C++ console application (Non-qt based) which needs to load the DLL (where I should have all business logic of my core application) and I can create a QT GUI application as different process.

    So I am struggling with now if my DLL (which is having business logic) will be loaded an console application (C++) so how can I launch QT GUI application from my DLL application and how can communicate between DLL and my QT GUI application (there will be lot of widgets in my QT application like forms, button, combo box etc.) Every changes in GUI should report to DLL (business logic instantly).


  • Lifetime Qt Champion

    @Ayush-Gupta said in Design pattern for GUI and NON GUI mode.:

    So I am struggling with now if my DLL (which is having business logic) will be loaded

    Simply link your console application and the GUI application to this DLL, no need to have GUI in business logic DLL.
    "how can communicate between DLL and my QT GUI application" - like you do with any other library.

    https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application
    https://doc.qt.io/qtcreator/creator-project-qmake-libraries.html



  • @jsulm Sorry If I am not clear.
    My console application will load the business logic during run time (Run time linking). Then I need to launch GUIApplication.exe from DLL.

    Then DLL and GUIApplication.exe should communicate.


  • Lifetime Qt Champion

    @Ayush-Gupta said in Design pattern for GUI and NON GUI mode.:

    Then I need to launch GUIApplication.exe from DLL

    So, the GUI is NOT part of the DLL, but a stand alone application, right?

    I don't know why you want to load the library at runtime, but if you really need/have to do so then check https://doc.qt.io/qt-5/qlibrary.html

    For IPC (Inter Process Communication) there are many solutions, check https://doc.qt.io/qt-5/ipc.html



  • Yes GUI is not part of DLL.
    The console C++ application loads the DLL during its initialization of class.
    If I create GUI as part of DLL then I need to call processEvents from Console Application using DLL interfaces of DLL which cause lot of lags in processing GUI events.

    I am struggling since lot of days with this design since I am not QT expert I did not find a good relevant design.

    Basically flow should be like

    Console application will first load the DLL (having business logic)
    Then DLL when load and console application will send input to DLL to load the GUI Application.exe
    And data will be exchange between DLL and console application.
    And DLL should communicate with GUI application.


Log in to reply