How to manage seperate layouts for each customer
-
I´ve just recently joined a group, which develops HMIs (human machine interface). And so far, most of the time I programmed something else than the GUI part (and never dealt with GUIs before). The company mostly does construction work, software development (and management) is not their strong suit.
So far, for every new customer a new software project was created, based on the last one.
Me, and the new group leader, are now trying to unify the codebase, at least for the current, and all coming projects (and maybe include the latest one, which still gets support/updates).
The GUI has several different screens (around ten), but not all are used in every project. And of course while they are all similar to a certain degree, they are different for every customer. Customers are not people, but other companies.Now a new project is about to begin, and we are thinking about a good way on how to handle the different GUI layouts (and the corresponding .cpp files. We still use Qt 5.12 with widgets, upgrading to qml is not in the picture at the moment.
So the idea is to have a master branch, let´s call it hmi_base_2023, and we make separate branches for every new project. the master branch contains the business logic (which is the same in all cases).
The main question now is, what to do with the ui files? We could make an empty main window, so the hmi_base_2023 branch does at least compile. But it won´t display anything, and therefore you can not really do or test much.
Every project will have it´s own images, ui/gui files, and link the business logic code from the main branch.
Often, symbols for certain conditions look different for every customer, or sometimes they just want another color/size. How to handle the different images per project is still open for discussion - currently we think about just keeping all of them in one images folder - but it will grow quite large over time, with every new set of symbols - so I do not really like that idea. But I have not found a better one.Currently, every screen has it´s own class, which is different for each customer (but the class names/files stay the same, like MainWindow.h, ...). The best solution I can come up is some base class for every screen, which displays information all projects have in common, in a generic way (not sure what that is for each screen). Derived classes can get their own design thanks to polymorphism, but I am not sure if it can cover every single - and specialized - customers request.
So, any idea on how to manage this in a smart way? We are also bound to svn as version control.
-
-
-
@CHoelzl I've actually done this, kinda. Not for customers but a different application for mobile and another for desktop with a 3rd for a embedded device (close to tablet form-factor) and different functionality.
The first thing is that I have a (static) library of all the shared code. Which is 90%. It is most useful to have a static library because that makes unit tests easier too, they just link to the static lib just like the front-ends do.
Then your front-end can have customer specific code in files specific for that customer. I did put effort into having one main.cpp for all, but some compile-time hacks to make the behavior of certain functions different for each. For instance the Android one doesn't process a lot of command line arguments, so that code is moved to a c-method and I have one android file which has an empty implementation of that method and a different file with actual code for the other customer.
Last,
you should aim to have shared widgets somehow. It will help enormously with maintenance. Just because the actual screens are different doesn't mean that specific functions and widgets are not shared between multiple implementations.
Naturally, the best way to determine that is when you actually get the requirements and then you can move a widget from one customer dir to a common dir and just reuse it for both.I used QML for all this which I think it very useful for any such effort since it is much stronger on separation of layout and backing code. Making the amount of code written for each front-end (or customer) minimal. But I'm sure with QtWidgets you can pull this off too.
Have fun!
-
@TomZ Thanks for your reply, while I have set everything up in a way suggested by JoeCFD, I currently have only one project to work with. So it is good to know this really works and I am on the right track with this project setup.
I also aim for a general main for all versions, and even when it is the same plattform in all cases, customer wishes are often so different, I´m sure I do also need some compile-time hacks to make it all work, but that is expected anyhow.
Unfortunately I am currently very busy with the current project, so getting the older, seconds project into this new setup, to finally see how well it will work, is a few months away I guess.
Cheers and thanks to both of you!