Qt Application with QTabWidget, QGraphicsScene and QPushButton - c++

I want to create a Qt application with a QTabWidget, where each tab contains a QGraphicsView and a QGraphicsScene to draw a polygon on a Cartesian plane. example: first tab for a triangle, second for square, etc...
So, I create my qt application and then:
- inside my class derived from QDialog, I create a QVBoxLayout, I've added my widget to this, and I've inserted it into my QTabWidget, created with QDesigner: I repeat this operation for each tab of QTabWidget.
I want to know if it's a bad practice to add a QGraphicsScene into a tab in this way or to redefine all the classes from qwidget, view, and scene.
out of the QTabwidget, i have some QPushButtons that do some operations on the QGraphicsScene's polygons: when i click on a polygon, i want to do some operations through the QpushButton, like sum the angles (only on the polygon that I've clicked).
How do I communicate to the QPushButton (out of the QTabWidget) that I've clicked a polygon and which one I've clicked(inside QTabWidget)?
the private data field of my_scene contains a QList of triangles (derived from QGraphicsPolygonItem)
https://i.stack.imgur.com/Pu329.jpg

I want to know if it's a bad practice
Generally speaking no, it isn't.
If you are ok with the functionality of some class you should use this class. If you need to extend it in any way you should subclass from this class and add everything you need.
It's true not only for Qt classes but for any other classes written by you or somebody else. It's one of the basic principles of inheritance.

Related

Qt QGraphicsScene dynamic GUI elements like containers

I'm using QGraphicsScene and I want to create gui elements.
How do I/should I create a list container i.e. inventory in a game context.
See HERE
For an example of what I mean. There is an inventory widget at the bottom that can be dynamically populated.
Are there any container classes like the standard list widgets but for QGraphicsScene instead?
Right now the only way I can see is to draw a 'rectangle' and manually draw and manage 'squares' on top of it... which wouldn't be a container.
Every QGraphicItem is effectively a container because every item can be optionally parented to a QGraphicsItem. When you do that, the parent affects all its children...if the parent is moved, the children move with it. If a transform, visibility, or opacity are set on the parent, those changes apply to the children as well.
Basically, your understanding is correct; you would create a parent QGraphicsItem that draws a container outline, and then you would have children that each draw their icons or whatever is appropriate.
Alternately, you can use widgets in a QGraphicsScene, so all of the widget-based containers are available. If that's the route you want to go, then look at the QGraphicsWidget class.
This is a complex subject, but hopefully this will get you started.

How to hide/show a QLabel and QTextEdit at the same time in my Qt application?

I am working on a hide/show feature for my console in my Qt GUI application. The console consists of 2 widgets; QLabel and QTextEdit. Do I need to add the QLabel and QTextEdit to a QWidget in order to show/hide them, or is there a better way?
So basically I am looking for a container such as 'JPanel' in Java...
Do I need to add the QLabel and QTextEdit to a QWidget in order to show/hide them, or is there a better way?
Multiple methods are possible here. You can, as you suggest, create a parent QWidget and add the QLabel and QTextEdit to a QWidget. Calling show and hide on the parent widget will affect its children.
Another method would be to have a slot function, which when an action is called, the slot calls show / hide on the 2 widgets.
Neither is right or wrong and depends upon the overall design of your application.
Ok, I think you need to use a layout (horizontal / vertical):
The simplest way to arrange objects on a form is to place them in a
horizontal or vertical layout. Horizontal layouts ensure that the
widgets within are aligned horizontally; vertical layouts ensure that
they are aligned vertically.
Horizontal and vertical layouts can be combined and nested to any
depth. However, if you need more control over the placement of
objects, consider using the grid layout.

qt create simple rectangular board

I want to create a rectangular board using QT. This board will be updated when a step is performed. For example on step x, the text in cell 5,6 updates from "not explored" to "explored".
I have looked through the QT documentation and found the class QGraphicsView. How can i use QGraphicsItem to simulate a cell where text can be written?
I am also open for alternatives.
Technically this could also be done by customizing a QTableView/Widget, but QGraphicsScene is more robust for custom graphics and performance.
From a high level view, you can either create a composite object representing a "Cell" item, or you can subclass a QGraphicsItem and do all the custom painting yourself.
When creating a composite object, that would just be a QGraphicsItem "Cell" subclass which contains maybe a QGraphicsRectItem and a QGraphicsTextItem as members, set to the cell instance as a parent. This will keep the child items translating with the parent cell item.
When creating a completely custom QGraphicsItem, you would define all the painting inside of the paint() method, which would draw a rectangle, and text taken from a value set on the instance.

How should I use a QGraphicsScene with layouts and widgets

I'm creating some graphic data displaying widget in Qt4 and I was tempted to use the QGraphicsScene for it, create QGraphicsItems for the data items etc.
However, I wanted to add some layer of controls (eg. scrollbars, zoom+other buttons - I want to make it in a similar style as eg. Google Maps, that is, the data would be displayed all over the widget, and the buttons would be shown atop of them) to the widget. So I thought it might be feasible to add them to the scene (perhaps as a child of a QGraphicsGroupItem that would be shown over the data). But I want them to move & resize when I resize the whole widget, so I should use a QGraphicsLayout for managing them. But at this point, I discovered things are pretty complicated.
The problem is that when using QGraphicsLayout, the following constraints hold:
Only a QGraphicsWidget can be managed by a layout
QGraphicsLayout can only be used to manage children of a QGraphicsWidget
Which means that I would have to create my controls as QGraphicsWidgets, add a top level QGraphicsWidget to the data widget, and manage the size of this top level widget myself.
So I want to ask:
Wouldn't a classic approach (ie. use plain old widgets for all controls, and use QGraphicsScene only for displaying the data) be more reasonable?
Is there any advantage in using QGraphicsScene in this case (performance or simplicity...)?
How should I use QGraphicsScene to exploit its strengths?
Since Qt 4.4 you can embed classic widgets in a QGraphicsScene by using QGraphicsProxyWidget :
QWidget *widget = new QWidget;
QGraphicsScene scene;
QGraphicsProxyWidget *proxy = scene.addWidget(widget);
If you think that QGraphicsScene (or whatever other widget you have) is appropriate for most of your display, use that. What we have done in the past for somewhat similar things is to make a custom widget that inherits (one way or another) from QWidget, and put the control widgets in a layout on top of that widget. This means that the whole widget is drawing whatever it is you want drawn, and the control widgets are on top of that, resizing as the whole widget is resized.
Alternatively, a couple of times we've had layouts that were just a bit too complicated for the layout widgets to easily handle. Rather than create a custom layout, we just positioned them with no layout, and moved them in code on the resize event. It works just as well.

How do i cause a qtabwidget instance to automatically resize when child tabs are added to it?

I am trying to get the QTabWidget automatically resized to fit the child tab when the child is added but have been unable to do so. I have created a form using Qt Designer and have inherited this using the single inheritance approach as follows.
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = 0);
private:
Ui::MyForm ui;
};
I have a QTabWidget and I am adding the instance of the object to my QTabWidget using the addTab(). When I display the QTabWidget, I notice that it hasn't resized to fit the MyWidget instance. What do I need to do to ensure that the QTabWidget instance gets automatically resized?
In designer, make sure you add a layout to your widget. Click on the widget's background so that way when you apply a layout, it applies to the whole widget. The trick is that the base (parent) widget that your form is built on needs a layout, and not just the items in the form.
Grid's are generally pretty easy to use. But sometimes the other ones are better. Designer can be tricky to use and takes a while to get used to. Basically every widget should probably have a layout applied to it. Strange things can happen when you don't.
I believe this is a bug of the Creator (at least for V4.7.4 opensource).
My solution is as following.
Do not create the QTabWidget object in the main project.
Create it independently (by creating Qt-> Form-class).
Then, copy the 3 files (.h, ,cpp, .ui) into the project, and add them to the project.
The result is: it resizes as the mainwindow resizing.
To fit any widget into its parent widget, you need to use a particular layout (grid, horizontal, vertical etc).