Idomatic QT architecture for simple forms? - c++

I am currently working on a medium-sized project that will need to utilize many form-like dialogs. I am developing this application using Qt5 widgets. (I am trying to implement a debugging tool for a class-based network protocol). Most of the logic behind the forms is very simple.
The view for a form would look like this:
Basically, when send is pressed it just constructs a packet using the data in the form, and would insert it into the message buffer to be sent out when appropriate later in the program. I want to utilize proper coding idioms when I develop this because I'm using this project to familiarize myself with GUI programming.
What concerns me, is that I don't know how to idiomatically structure my code in a way that is extensible, testable, and robust. I don't want my dialog to be directly responsible for inserting the data into the send stream, nor should it have to handle any business logic associated with it.
Naively I would imagine that the view should do very little logic other than communicate to some other part of the process that the user has edited something or pressed a button, perhaps it could validate that the text is in a proper format. The other part of the process would be what I imagine to be the 'model', therefore (I believe) following an MV architecture. This leads to several questions:
Most tutorials like this seem to want the user to implement a QAbstractListModel or a QAbstractTableModel, or perhaps even a QAbstractItemModel, but none of these seem needed or relevant to the type of data I am working with, furthermore, their interface seems to be very heavy-handed for what I think is simple data flow -- do I need to subclass one of these in order to properly fulfill the MV architecture or could I just manage the connections myself? If I manage the connections myself, should I create a presenter class to handle this and therefore implement an MVP architecture?
How should data be passed from this form to the rest of the application? I would prefer to avoid any/all global/static designs if plausible/correct. On send a packet should be constructed and inserted into the send buffer, but should that be done in the model for this dialog? Should a reference to the buffer or its controlling interface be provided and manipulated by this model? Should the relevant data be passed or returned to some outside model that would handle the buffer manipulation?
The data in these forms are basically 1 to 1 with the information needed to construct the messages for the send buffer, to the point that you could reasonably use or adapt the existing interfaces to be a functional model, however, I feel that this would be a code smell -- is that correct? Should I create a new class that basically mirrors my message class in order to have better separation of concerns?
Thank you all for any insight or resources that can be provided. Much of this is me overthinking the problem, but I would like to be sure that my design philosophy is sound before I implement 60+ dialogs so that this application can fully cover the protocol's standard.

I don't want my dialog to be directly responsible for inserting the data into the send stream
Exactly. And it should only be responsible for passing the data on to some service which is responsible for sending the message i.e., Separation of concern and single responsibility.
Most tutorials like this seem to want the user to implement a QAbstractListModel or a QAbstractTableModel, or perhaps even a QAbstractItemModel, but none of these seem needed or relevant to the type of data I am working with,
Is your data going to be represented in a table / list / tree. If yes, then you can use one of these / subclass them. Alternatively, you can use the QListWidget / QTreeWidget etc which don't use the model-view design. If no, then these are not for you obviously. It depends on the data and how you want to present it, and only you know about the data so you have to make that decision.
How should data be passed from this form to the rest of the application?
Using signal / slot mechanism. Take the form in the picture for example. The send button above shouldn't send anything. It should just accept the data entered into the form and then pass that data via a signal to some other service for example a MessageSender service or a ValidationService. That is all the form should do.
I would prefer to avoid any/all global/static designs if plausible/correct.
That is good and you should avoid them unless there is no other way. For example, a logging service is something that is needed everywhere in the program throughout the lifetime of a program, I would make it a singleton.
On send a packet should be constructed and inserted into the send buffer, but should that be done in the model for this dialog? Should a reference to the buffer or its controlling interface be provided and manipulated by this model?
Use signal / slots. A dialog should just take input, it shouldn't be sending data around or doing other things. It should take input and pass it on. Design your classes / objects with this in mind.

Related

Qt QML: UI with dynamic number of images provided by c++ code

I am designing an application that, in essence, gets a number of images (which change - think of several videos consisting of many images each, displayed in sequence) which I want to display in a grid pattern. This pattern should be extensible, I want to be able to control row and column count dynamically.
A C++ core application provides these images at varying speeds. It needs to know where to send them.
My team and I have already created a prototype which fits some of those requirements: we are able to instance a C++ based object, derived from QQuickPaintedItem, which paints its image in the overwritten paint(QPainter *painter) method. In QML, several of these are then instanced and they display their images as I would expect. However, the image content is hard-coded and as these objects are instanced in QML, I'm unsure as to how I would control their contents from my core application in C++. Furthermore, the way we dynamically arrange them is an extremely dirty hack derived from trial and error and works only marginally close to how it is intended: the instances are simply destroyed and recreated whenever the "add one more" button is pressed.
My question is probably a matter of design principle. Even after examining a few examples and further research I am unsure what's the best way to combine the core application and the QML code to achieve what I want.
What is the right approach here? I suspect Models and Views might be the way to go, as I believe I could be able to add the Player components to the model via C++ and therefore have access to them there, while QML would ... somehow ... handle the displaying and arranging.
I'm sorry for the rather vague question, I hope you can help me with a few pointers into the right direction, as to which mechanics I could use to combine QML and C++ for my purposes.
QPaintedItem is unnecessary and will likely constitute performance overhead.
As already mentioned, what you really need to do is implement a QQuickImageProvider which can allow you to do C++ / QML image interop.
Then regardless of whether you need rows, columns or grids, those are all driven by models, you don't necessarily have to implement a C++ mode, QML's ListModel will suffice, as all you really need is a list model of strings, representing the image sources for the custom image provider.
Every time you have a new image coming from C++, you can emit a signal from the C++ side with the image source string, to which you connect a handler on the QML side to add a list item to the model. Expose the emitting object to QML as a context property. As soon as a signal is emitted, the new image source is added to the model and automatically shown in the view. That's pretty much it.

Automatic PyQt GUI generation according to REST schema

TL;DR: I'd like to have a tool that receives an RESTful schema as input and provides a pyqt dialog/UI as output. Preferably with automatic submission/validation.
I'm working on a PyQt5 application that interacts with a remote Django server using django-rest-framework.
I find that I define most of my models/views/serializers quite quickly as they neatly extend one another. After writing a proper model, generating serializer and view is very easy and I end up with fully functioning server-side fast.
The client/GUI side is a different matter. I have to define the available fields again, their type and order. I have to define widgets for viewing a single object and a list of objects. I have to define edit interfaces and handle permissions.
This all seems like it could use some sort of automation.
Ideally, I could point a smart widget or form to a REST endpoint, and it'll automatically fetch the schema and allowed actions. Automatically create a GUI and the necessary error handling.
Ideally, this shouldn't depend on server side technology, and simply use a schema.
I've googled and couldn't find anything like that. Can someone point me at something similar? Is there a deeper issue with creating such a tool I'm missing?
Thanks!

How do I integrate a finite state machine into my application?

Hi and sorry advance if this has already been covered.
I'm mainly preoccupied with writing numerical software but I'm a bit of a noob when it comes to application design.
I've written a library that essentially takes input from different data streams or static files, performs some data analysis and outputs the data to screen or file etc and I've decided to write a gui application to make it a bit more user friendly.
The sequence in which library calls must be made is fairly simple but there are some constraints on which events should be handled depending on the state the application is in. I.e. I don't want the user to start grabbing from a data source whilst they are already processing from another.
So I've decided to use a finite state machine. However, I was wondering on what the best practice for integrating a finite state machine into your application is. Should I make it the public interface to my library or should I essentially use it as the controller in an MVC framework, with the library being the model and GUI being the view? Or is there a better way of controlling the flow of your application?
Thanks for your help.
You got it right. Gui = View, FSM=Controller, Library+ Static data + Database + Model.
Having said that, see if you can further split the FSM into two parts. The state transition definition itself should be made declarative so that you can easily change the state rules. The FSM should be a simple state transitor which uses the rules in the state rule base.
you can store the rules declaratively using PMML, a variant of XML.
Take a look at this, it will explain what I tried to say, more eloquently:
http://en.wikipedia.org/wiki/ADAPA
(not related to ADAPA)

REST vs RPC for a C++ API

I am writing a C++ API which is to be used as a web service. The functions in the API take in images/path_to_images as input parameters, process them, and give a different set of images/paths_to_images as outputs. I was thinking of implementing a REST interface to enable developers to use this API for their projects (independent of whatever language they'd like to work in). But, I understand REST is good only when you have a collection of data that you want to query or manipulate, which is not exactly the case here.
[The collection I have is of different functions that manipulate the supplied data.]
So, is it better for me to implement an RPC interface for this, or can this be done using REST itself?
Like lcfseth, I would also go for REST. REST is indeed resource-based and, in your case, you might consider that there's no resource to deal with. However, that's not exactly true, the image converter in your system is the resource. You POST images to it and it returns new images. So I'd simply create a URL such as:
POST http://example.com/image-converter
You POST images to it and it returns some array with the path to the new images.
Potentially, you could also have:
GET http://example.com/image-converter
which could tell you about the status of the image conversion (assuming it is a time consuming process).
The advantage of doing it like that is that you are re-using HTTP verbs that developers are familiar with, the interface is almost self-documenting (though of course you still need to document the format accepted and returned by the POST call). With RPC, you would have to define new verbs and document them.
REST use common operation GET,POST,DELETE,HEAD,PUT. As you can imagine, this is very data oriented. However there is no restriction on the data type and no restriction on the size of the data (none I'm aware of anyway).
So it's possible to use it in almost every context (including sending binary data). One of the advantages of REST is that web browser understand REST and your user won't need to have a dedicated application to send requests.
RPC presents more possibilities and can also be used. You can define custom operations for example.
Not sure you need that much power given what you intend to do.
Personally I would go with REST.
Here's a link you might wanna read:
http://www.sitepen.com/blog/2008/03/25/rest-and-rpc-relationship/
Compared to RPC, REST's(json style interface) is lightweight, it's easy for API user to use. RPC(soap/xml) seems complex and heavy.
I guess that what you want is HTTP+JSON based API, not the REST API that claimed by the REST author
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Best way to keep the user-interface up-to-date?

This question is a refinement of my question Different ways of observing data changes.
I still have a lot of classes in my C++ application, which are updated (or could be updated) frequently in complex mathematical routines and in complex pieces of business logic.
If I go for the 'observer' approach, and send out notifications every time a value of an instance is changed, I have 2 big risks:
sending out the notifications itself may slow down the applications seriously
if user interface elements need to be updated by the change, they are updated with every change, resulting in e.g. screens being updated thousends of times while some piece of business logic is executing
Some problems may be solved by adding buffering-mechanisms (where you send out notifications when you are going to start with an algorith, and when the algorithm is finished), but since the business logic may be executed on many places in the software, we end up adding buffering almost everywhere, after every possible action chosen in the menu.
Instead of the 'observer' aproach, I could also use the 'mark-dirty' approach, only marking the instances that have been altered, and at the end of the action telling the user interface that it should update itself.
Again, business logic may be executed from everywhere within the application, so in practice we may have to add an extra call (telling all windows they should update themselves) after almost every action executed by the user.
Both approaches seem to have similar, but opposite disadvantages:
With the 'observer' approach we have the risk of updating the user-interface too many times
With the 'mark-dirty' approach we have the risk of not updating the user-interface at all
Both disadvantages could be solved by embedding every application action within additional logic (for observers: sending out start-end notifications, for mark-dirty: sending out update-yourself notifications).
Notice that in non-windowing applications this is probably not a problem. You could e.g. use the mark-dirty approach and only if some calculation needs the data, it may need to do some extra processing in case the data is dirty (this is a kind of caching approach).
However, for windowing applications, there is no signal that the user is 'looking at your screen' and that the windows should be updated. So there is no real good moment where you have to look at the dirty-data (although you could do some tricks with focus-events).
What is a good solution to solve this problem? And how have you solved problems like this in your application?
Notice that I don't want to introduce windowing techniques in the calculation/datamodel part of my application. If windowing techniques are needed to solve this problem, it must only be used in the user-interface part of my application.
Any idea?
An approach I used was with a large windows app a few years back was to use WM_KICKIDLE. All things that are update-able utilise a abstract base class called IdleTarget. An IdleTargetManager then intercepts the KICKIDLE messages and calls the update on a list of registered clients. In your instance you could create a list of specific targets to update but I found the list of registered clients enough.
The only gotcha I hit was with a realtime graph. Using just the kick idle message it would spike the CPU to 100% due to constant updating of the graph. Use a timer to sleep until the next refresh solved that problem.
If you need more assistance - I am available at reasonable rates...:-)
Another point I was thinking about.
If you are overwhelmed by the number of events generated, and possibly the extra-work it is causing, you may have a two phases approach:
Do the work
Commit
where notifications are only sent on commit.
It does have the disadvantage of forcing to rewrite some code...
You could use the observer pattern with coalescing. It might be a little ugly to implement in C++, though. It would look something like this:
m_observerList.beginCoalescing();
m_observerList.notify();
m_observerList.notify();
m_observerList.notify();
m_observerList.endCoalescing(); //observers are notified here, only once
So even though you call notify three times, the observers aren't actually notified until endCoalescing when the observers are only notified once.