Should this be in model or view? - c++

I am using QFileSystemModel to populate my tree view. User can right click on a tree node (a folder) and perform an operation (exports all certain data files under this folder).
I have this export under the on_tree_clicked() but I feel like this operation belongs to model.
Will it be better if I derive my own QFileSystemModelWithExportfrom QFileSystemModeland added the export function? From on_tree_clicked(), I then just call it?
Is there another way to do this nicely? I want my on_tree_clicked() to be shorter and cleaner.
Also I am quite new to Qt, how do we derive from Qt core class like QFileSystemModel? When I am adding class, it lets me derive from QObject, QWidget etc but not from any model class.

Your UI should only deal with UI problems. i.e. button presses, user interaction.
This should then send it through to your model which actually executes the code.
Think of it this way, if your export to file takes, lets say 5 seconds, that's 5 seconds you can't use your UI for because that thread is doing the write to file. IF you have this model you have the opportunity to multi thread that particular event and keep your UI responsive whilst performing actions.
Code wise:
onTreeClicked() can be fairly short. It could perform the following:
myModel->writeDataFromNodeToFile();
& then inside that function you can have all the functionality you need to write to file. Open/Close/stream data etc

Related

c++ application save and apply preference pattern (may be boost or something)

Typical situation: you have an application, that save and load preferences
(save and load handled by class Config).
Imagine there's such a preference for fonts of some GUI elements.
So we have
struct Font;
struct Config {
const Font& getFontForSpecificGUIElement() const;
//save to disk if Font changed
void setFontForSpecificGUIElement(Font);
};
Whenever the font is changed I need to inform all instances of class SpecificGUIElement of that change.
How can achieve such notification functionality?
To keep Config simple I want to decouple that functionality. Besides, there will many properties like this (30-50 of them).
So in general I want:
Not require implementing virtual interfaces
I don't need thread safety
Convenient registration of event handlers
I need notification for new subscribed receivers, with last recent
notification if were any (I mean, as in my example Font changed, and when new GUI elements subscribe on such event, they receive, event automatically triggered for them, and they receive last variant of Font)
Convenient registration of event type (I mean in item above
we create some kind of value cache, so it should be simple add new one)
I suppose this is common enough requirements, so may be there already solution,
in popular C++ libraries, like boost ?
Update:
Why Qt not suitable for me. I see two approaches
with Qt, QEvent subsystem. But because of it is impossible
send event to unknown listeners it is no go. Why not signal/slots, first you need inherit QObject, second to implement (4), I have to create MessageBus class to cache last values, and adding new events starts require to much work:
add data field, add new signal, add function(X) to emit new signal, because of signal actually protected functions,
plus in (X) i need compare last value with new one.
Yes, this alsready exists in e.g.:
Boost Signals2
http://www.boost.org/doc/libs/1_59_0/doc/html/signals2.html
There are many samples that should get you going.
Signals2 does offer thread safety, but I guess that doesn't harm.
Alternatively,
Qt
Qt does have a signals/slots implementation, as do many other UI frameworks:
http://doc.qt.io/qt-4.8/signalsandslots.html

Refactoring / partitioning of Qt GUI widget source file

I have created a traditional Qt (widget based) GUI, something like this: MainWindow::MainWindow(parent) : QMainWindow(parent)
This is designed by Qt Creator as forms (mainwindow.ui), aka Design Mode. Everything works fine. But the GUI code with all widgets, initializing the corresponding models, and functionality gets quit long. I'd like to refactor to small units. Things I came up with:
I tried using specialized (derived) widgets. Example: A created MyTableView::QTableView contains the specialized model, as well the signal/slot handling between model and widget. This reduces the amount of code in MainWindow. However, I do loose the capability to design the GUI via Qt Creator's Design mode.
The best thing I came up with so far, was to spilt the source code (multiple cpp files). It still represents one class, but less code in one file.
So, how could I better partition my GUI class?
If you still want to uncouple the initialization of widgets by derived widgets, you can use "promote to ..." option in Qt designer. Steps:
class MyTableView : public QTableView {}, and so initialization of table view is moved to the constructor of MyTableView.
In Qt Designer, open the ui form (MainWidow.ui), and drag and drop a QTableView on it;
Right mouse click the QTableView, in prompt menu, there's a "promote to" option, open it
In the dialog of "promoting widget", specify your custom QTableView's class name and header file, say MyTableView, MyTableView.h. This step requires existing custom class and header file.
Borrowed a picture:
You could create your own Qt widgets and register them with QtDesigner. Then will you be able to use them on forms as mere QLabels and friends. See this link
In a recent project, we had pretty restrictive uncoupling requirements (especially not to be too strongly linked to Qt). What we used to do based on MVC-like pattern is:
Implement a controller that controls the application workflow
Add a GUI "adapter" class per screen that communicates with the controller. Let's say HomeScreen class, SecondScreen class
Each adapter class contains a given number of widgets: TimelineWidget, FormWidget
Each widget is composed of a ui member (Ui::TimelineWidget ui) that is generated from a .ui file designd with Qt designer
Note that this structure might not be suitable for small projects.

QT Creating many complex widgets

I have a QT application that allows a user to define a list of models. Each model defined has a fairly complex widget class that is created. Currently this is all being done in the main (GUI) thread. The program works fine for normal use, but I tried to stress test it by creating 200 to 1000 models and the creation of the GUI took a VERY long time (20 seconds to many minutes).
I tried a couple attempts at threading out the work using QtConcurrent::run, but the program always complained because "Widgets must be created in the GUI thread."
I found this answer on SO: How do I create a Window in different QT threads?. But this doesn't seem to be doing much in the new thread except telling the main thread to create a new widget. This does not distribute the workload, as far as I can tell.
With all of that, I have a couple direct questions:
1) Is there a better design (faster performance) than looping through my list of models and serially creating each widget?
2) If this process is possible to be multithreaded, can someone point me in the direction of a simple example?
There really is no way to put widget stuff to other threads. OpenGL rendering or some data processing for a widget to show when ready, stuff like that can easily use other thread, but not the actual widgets.
Better design would be to create the widget when you need it. Or just have one widget and update the data it displays (unless widgets for different items are actually different).
If you are worried about performance when scrolling, then one solution to that is to switch widget only after current one has been visible for some minimum time (say, 500ms if user keeps scrolling, or 200ms after last scroll event, some logic like that) note that this is not delay for reacting to user selection, this is delay after selection and visible widget change, so if user just changes to next item, GUI is updated immediately. But in scrolling the widget is not updated for every item briefly selected, and things don't slow down. Use QTimer or two to send signal when widget should be updated.

Unable to understand Undo Redo Framework in Qt

I am learning to use Qt for my application development & I am pretty successfull in developing my Application. Now I want to implement Undo Redo Functionality for my Application. The doc for this topic has little information. I have even tried understanding from the 2 examples in the SDK. But I am having a tough time understanding how it works.
Can somebody please take the trouble of explaining me how to implement it?
There are various state's in my application for which I want to provide this functionality.
So can the explaination be from the general point of view?
If there are already articles on the internet explaining the same then please notify me about them. That would be very helpful.
Thank You.
There are 2 core classes: QUndoCommand and QUndoStack;
QUndoCommand is the base class of your command class. You have to implement undo() and redo() yourself.
QUndoStack is basically a container of QUndoCommand objects, with extra methods like creating QAction, query undo/redo text of current QUndoCommand(Simple functionalities which you can implemented yourself easily)
What you need to do is:
Implement your commands. You need to decide how to implement redo/undo yourself according to your need. class AppendText is a good example: http://qt-project.org/doc/qt-5.0/qtwidgets/qundocommand.html
Keep a QUndoStack instance for each document(Or one instance if there is only one document in the application).
Say you have an "AppendText" command class, and an "Append" button in the UI. If "Append" button is clicked, you need to create an AppendText command instance, and call QUndoStack::push(appendCmd). QUndoStack::push() will call AppendText::redo() first, and then put it into the container for undo.
That's it.

How to divide program - Qt, C++ using mvc logic

At the beginning I want to tell that I just started learning QT so my knowledge about this is really not deep. I wrote simple tasks management it's a console application of course. I used logic which resembles MVC pattern (controllers, views, actions, models).
For example let's take user login. I create instance of LoginController class, then LoginController creates instance of LoginView who is waiting for user to enter data - login, password. Login and password is saved as LoginView members. Then in LoginController I read this data and passes them as parameters to UserVerificationAction constructor. Constructor of this class saved this data as members of their class. Next in LoginController I calls method of class UserVerification - action() which validates login and password. Then depending on the result of validation I create instance of MenuController or instance of LoginFailiedView. This mechanism is user throughout the program (CreateUserController, AddTaskController) etc. I used virtual methods so MenuController consists of about 20 lines of code and is very easy to read.
I want to use Qt to implement a GUI to be more precise I want to use signals and slots mechanism but I have a dilemma. Maybe it would by better to create a slot in the LoginView class and then creates action instance instead passes entered data to LoginView members and then in LoginController creates instance od action class. maybe there is a better way to do this. I want you to give me some tips on how I should do it properly
p.s.
Sorry for my English
In Qt, the concept of a "controller" is slightly blurred. It tends to be part of both the model and view. This does not mean that you can't write a controller to link a model and view logic.
Normally what you will see is a view that emits signals for its actions. And then you wire these either directly into compatible slots on a model or a subclass where you have written your own slots.
If for instance you have a main window. This window might create a model and a view as children. And it may then define slots on the window subclass that wire between the model and view. This means your window is a view and a controller.
Qt provides Model/View architecture.
It introduces 3 classes: Model, View and Delegate to store, present and edit data.
I believe that is what you are looking for.