How to make a QheaderView multilevel? - c++

I am creating an application that saves the data of an object sending service.
I created that with Qt, a model of type QStandardItemModel that I want to display with QtableView.
But QtableView shows me the line level on the left. I want to delete it or hide it if possible.
I also have a problem with a header that I want to divide into two horizontally then divide the corresponding part of the bottom in two vertically. The reason for these division is that I have two headers with similar beginnings (date of correspondence and correspondence number)
Thank you for your reply because it is really important for me.

This type of QHeaderView does not exist, but we can create it for it we must create a class that inherits from QHeaderView and rewrite mainly the method paintSection which is the method in charge of drawing the sections of the QHeaderView.
But to do the generic project for any type of visual design we have to keep the information of the position and size of each section, for this we will create a model, to understand why of the overwritten classes I recommend you read content of the following link.
Explain the logic of each method is extensive so only place the link of the project that implements the above and describe the task of each class:
TableHeaderItem: It is responsible for saving the information of each item, mainly rowspan and columnspan in addition to the label.
GridTableHeaderModel: Model class that provides access to each item so that we can edit and read each item
GridTableHeaderView: This class is the custom QHeaderView where the main methods are overwritten to get the desired look.
GridTableView(optional): is a TableView that has methods to work directly with GridTableHeaderView.
Output:
Note: to hide the vertical header it is only necessary to use the hide() method:
horizontalHeader()->hide();

Related

Turn QGraphicsView or Scene into XML/JSON

I'm looking for an easy way (I think there isn't) to serialize a QGraphicsView or QGraphicsScene into XML or JSON.
I don't know if I'm supposed to save the View or the Scene. XML or JSON are fine I only need one of them. I just want to save a scene in a file to save it/load it
I found few stuff on other websites but it's seems quite complicated, or not really functional.
First of all, check out this very useful tutorial for working with json. Secondly, I think I've read you're working with a model-view based project?
If so, all model info should be saved and then there are two possibilities (depending on your design). Let's say you have created a model class PlayerList and you are showing all players using a PlayerListLayout or PlayerListView, a derived class from QVBoxLayout. Now there are two possibilities:
In each of the view classes, you have a direct reference to the model class. Well, all you need is to ask the model using getters (these getters would exist already, else you don't want to visualize the information). You don't need the json file, as long as you initialize your model first. So, for the PlayerListLayout, all you need to do is ask each Player* of that PlayerList-member and call PlayerLayout::read(Player* player) on all PlayerLayout members of PlayerListLayout. PlayerLayout will initialize it's new player-reference and ask the name, the capital, etc. to visualize it.
In one of the view class, you have no reference to any model class. Then you shall have to pass either the model or the json file to that view class, so you can get/read the information (again). This is a less clean way, which I don't prefer. It happened to me that I was creating large functions to read; that's when I found out something had to change. Reading and writing should be easy (if you divide the responsibilities in multiple classes).
I've had a Monopoly project, where I used this serialization as well, and the tutorial was really helpful. Secondly, I opened the .json file outside the model class (so in the view class), which you might want to consider as well. The disadvantage is that "when you want wo re-use the model classes, but not the view classes", you shall have to reimplement the opening and closing of a file in your new gui.
However, this way you create parallelism throughout your code, because returning true/false will happen in the view class of the main model (MonopolyLayout in my case), so the methods Monopoly::read(...), Board::read(...) all behave in a similar way.

Do I need to redesign my application?

I may be bordering on a discussion type question here so I apologise if the question is not specific enough.
I would like to know if I my current application design is inherently weak/flawed. My background is C so I am not using clever c++ patterns to their fullest extent, of this I am sure.
My application is similar to a 3D modelling package, without geometry creation (e.g setting up animations using existing models). The user imports a geometry and can set various parameters on pre existing geometry, and there are time dependent values that relate to the whole system. The output is a text file to be processed by another application.
I am using a QTreeview to render a QStandardItemModel. I simply store pointers to my core classes in the model's items. These have specific UI for each class type, and are all descended from a common base class. They all have a QWidget which is their "mainwidget"
When the user clicks on part of the treeview, the stored class is retrieved and its mainwidget is displayed on a pane on the UI. So - treeview on the left, pane to the right with the current item's contents, and a 3D view showing the geometry.
Most of my data is stored in the classes UI elements themselves; I don't have a central database which stores anything, and when it's time to save the project, I traverse the tree and let every item write itself to a QSettings file. This feels quite naive but it does work, and the reverse happens on project load. The project class generates new classes based on the type information in the settings file and they then read the contents out of the file themselves.
Similarly when writing the output file, each item knows how to write itself and does so. Where other classes can influence the output of others (for example, start and end times), higher level classes process the children and will set start and end times based on the order and duration of each child.
Should I be storing more data in the QStandardItemModel itself, or defining my own model perhaps? Does it sound like I have set myself up for future problems?
At the moment I have modified this system a couple of times to provide customised applications, but I am about to try and make it more generic. I welcome suggestions for improving my design. Go easy, please!
You should try to avoid creating god objects. Split your tasks and duties into smaller chunks. It makes it much easier to maintain and also much easier to extend if you need to.
Your specific use-case would benefit a lot from a more complete use of the Model-View-Controller pattern.
What doesn't make sense in your design is that your data objects hold a UI element. Since only one item can be shown in the right pane, this seems like a waste of resources. It makes more sense to have a single object that then gets passed a data object to display.
What I suggest for your program is the following:
Splitting your data into classes that only have functions for reporting and modifying values. There should be no knowledge of how to display data or store to a file.
Create separate class that handles the reading and writing from a file. If your model is very simple, you could just use single functions to do this using the method shown in the documentation for QDataStream or QTextStream.
Use your QTreeView and QStandardItemModel as Adaptor class between your data objects and the left pannel.
Create a controller class that gets informed by the QTreeView if data needs to be displayed in the right panel. The controller will then retrieve the data item and pass it to the right panel in order to be displayed.
The right panel should act like another View class with the sole responsibility of graphically displaying the data passed in from the controller class.
One advantage of doing it this way is that, if there are different categories of data that get displayed differently in the right panel, the controller could examine the selected data item, determine what the category is, create a view widget to put in the right panel, and then pass it the data to display.
This pattern is open-ended as far as extendability is concerned because you do not need to change your data classes if you need a new display, you merely need to create a new right-panel widget, and then teach your controller class how to determine when the new view should be used.
Another advantage of this pattern is that you only ever need to have a single widget created to display data in your right panel. If you change your selected item, you can just pass it to the view class that already exists and get it to refresh its display with the newly selected data. You only need to distroy the right-panel view widget if a different category of data object is selected and its data needs to be drawn in a different way. The controller class can determine whether a right-panel view widget can be re-used or whether it needs to be swapped out for a different widget.

How to display a selected date and a number in Qt

I'm currently working with the QCalendarWidget and I need some ideas to accomplish the following.
What would be the best way to add the selecteDate from a QCalendarWidget and a number to some sort of table. What I want is basically to have a list of dates with a number attached to each date, these numbers will be added together and the result will be displayed in a QLabel, I also want to be able to delete rows and again update the QLabel every time a row is deleted.
I also want to be able to save the list to an external file.
Should I use a QStringListModel or a QTableView?
How would you accomplish this?
I'm not expecting any code just a general procedure.
Please see the attached image for more details.
Should I use a QStringListModel or a QTableView?
You may want to familiarize yourself with the model/view framework. To put it simply, a model is the actual data that you have and it is independent of how it should be displayed. A view is a particular display implementation of a model. So you could use a model like the QStandarItemModel to store your String+number data and display the model in a QTableView.
Model/View Tutorial from Qt website here
QStandardItemModel class here. Has a simple example inside there.
And, for writing and reading the data to a file, I suggest you could use the QXmlStreamWriter/Reader classes. Refer to Qt xmlWriter/xmlReader

Howto determine the first and last row qt model/view

I'm building an filebrowser based upon the QAbstractListModel and QListView.
As you know what is displayed can change, by making the window bigger, or by scrolling.
How can I determine the first and the last entry (or index) actually displayed. Do I have to program that myself?
Added later:
see for full description:
http://qt-project.org/forums/viewthread/26497/
Thanks in advance,
Stef Bon
Voorburg
the Netherlands
The reason provided in the comments is not adequate; the model is supposed to call beginInsertRows/endInsertRows at any time, even if the range where you are inserting items is not currently visible in the view. There are multiple reasons for that (proxy models, QPersistentModelIndex instances, selection handling, QAbstractItemView's internal housekeeping, caching of already rendered items etc).
The MVC API in Qt is designed so that the model is not supposed to know about what the view is currently showing. The contracts expressed in the QAbstractItemModel specify that the model "just" has to keep the rest of the world updated by calling the protected methods (which emit the rowsInserted etc signals, among other things). If you ever find yourself in a situation where you start thinking "hey, if only I knew how this model was displayed in the attached view", the correct thing is to make sure you are using the existing API effectively. As an example, a very common problem is that the programmer finds out that their model's data() method is called too often, for each item in a list, for example. The typical reason for this is that the corresponding QListView needs to know how much space to reserve for each item so that the scrollbar size can be determined. A correct way for this is to either return usable data for the SizeHintRole, or set the view's uniformRowSizes to true.

What level of seperation should my UI elements and model objects have?

I'm building a desktop app in QT (although that may be irrelevant) and I'm having a hard time working through the class structure and layout. The data model is fairly simple with a root container with a number of containers of items. Consider the following representation:
Root
+ Parent
+ Child
The UI is fairly simple and follows that data model with a main window with a scrollable area (root), widgets that contain layouts (parents) of custom widgets (children) with some labels and buttons.
My trouble is with handling events that need to go up the chain and then back down like moving a child from one parent to another, moving elements, or updating child meta-data that impacts several to many other widgets.
I'm currently splitting UI widgets and model objects but having each widget and corresponding model object pointing to and from each other feels cumbersome and I think it is leading to too much maintenance.
I'd suggest following a standard MVC pattern and ensure there are no dependencies from the model to the view; in your case this would mean that while there is a widget for every model item, the model items do not reference their corresponding widgets.
While the MVC pattern has many flavours, one way to accomplish this would be to have a view class that monitors the model for any changes and updates the view accordingly (this can be accomplished by connecting a slot in the view class to a signal emitted from the model class). Any changes the user initiates through the view can then be:
1) handled directly by the model
through a simple signal/slot
connection
2) handled
by a controller class which can
direct the model to update accordingly
Either of these would then cause the model to emit an update signal which would cause your view to update. The benefit of this is the ability to change your view (or add additional views) without having to update your model.
I'd recommend reading Qt's Model/View Programming Guide to better understand how MVC works in Qt and to see if there's an existing class or interface (e.g. QAbstractItemModel) that you could use instead of baking your own.
Consider using factory pattern and command pattern. There are plenty of samples. I am just giving a hint here.
http://en.wikipedia.org/wiki/Factory_method_pattern
http://en.wikipedia.org/wiki/Command_pattern
Forgot mention about qt book: cartan-cas-dot-suffolk-dot-edu/oopdocbook/html/