Implementation of gui designer - c++

I'm interested in making my own small gui designer for learning purposes in Qt. Just basic drag and drop from left panel which would have controls, to right panel on which they could be selected, moved, resized and have their properties changed (name and such) and eventually (if selected) be lined up.
I would use QGraphicsScene as the right panel cause it already has selecting and moving implemented. But how would I implement resizing? And then how would I generate a QWidget class with controls at same positions? Or is there an easier way?
What would be the best way to implement all of this? All suggestions are welcome and keep in mind that it won't be complex as Qt designer.

You need to define some widgets, which are going to be dragged from the left panel -maybe a tree view with icons- and dropped to the scene.
These widgets should inherit from QGraphicsWidget. You can also inherit QWidget and put the widgets into scene via QGraphicsProxyWidget. They can be resized by highlighting corners and overloading the mouse events. Please check out corner grabbers and sizable box examples. Also check out QSizeGrip. It is the resizing grip of any QStatusBar.
Property panel is the easiest, you should list the properties of the clicked item. To line up, you can reinvent the wheel and write a layout maker class, or simply use QGraphicsLayout and highlight the layout on your interface. Ctrl+left click should select multiple widgets, a layout button should layout them programmatically, and a bounding rectangle item should be drawn.

Related

Qt - How to put existing widgets and qscrollbar inside a QScrollArea

I'm a newbie in Qt.
I'm making a notepad with a ribbon:
And I wanted to make appear a QScrollBar when I resize the Window and I know that I have to use a QScrollArea for it.
My question is, how do I add existing widgets to a QScrollArea and make appear a QScrollBar when needed?
It doesn't look to me like your widgets are aligned in any form of layout. From designer, these button at the top allow you to put widgets in layouts:
Once your widgets are in their necessary layouts, make a new QScrollArea (either by doing QScrollArea *myArea = new QScrollArea() and adding it to a layout manually, or by dragging and dropping it in the designer). It should be as drag and drop as everything else you've encountered so far. You will want to set the vertical scroll policy to never scroll and set the contents margins of the scroll area's widget to 0.
But this begs the question, how savvy are you with GUI programming outside of Qt? You will run into a lot of obstacles from here on out if you can't grasp the concept of layouts and so on.
In case you don't know how layouts work, I suggest you look at the documentation. It's a good rule of thumb to check the docs and look for existing questions before asking. Manually setting the X and Y of widgets is a long-gone practice.

Is there a way to attach or anchor two QWidgets together?

I'm getting started with Qt and decided to build a full-screen text editor. I want to have a button (button with arrow in screenshot) attached to a QDockWidget which opens and closes it so the button is always visible to the right side of the screen and stay anchored to it when dock is visible or resized.
My current app is a simple fullscreen textEdit set to centeralwidget in Mainwindow.
I haven't found a way to do this yet with layouts or existing addAnchor() functions so any help or direction is appreciated.
You can achieve what you want by using a container for your text edit and the button. A QWidget instance can be used as an "invisible"*** container for other widgets.
So in Qt Designer you add a widget as a central widget of the main-window, inside this widget you add the text edit and the button, then you set a vertical layout for this container widget.
Don't forget to restrict the docking widget to only dock to the right side, you can do that with: dock->setAllowedAreas(Qt::DockWidgetArea::RightDockWidgetArea); //assuming dock is the pointer to your QDockWidget.
In case you want the dockWidget to be able to dock to any side and the button to follow, you can do that too, but it get a little bit more complicated. Basically you need to connect a slot to dockLocationChanged of your dockWidget and based on where it's docked you need to set-up a new layout for the container widget to be vertical or horizontal and the order of the textEdit and the button based on the side the dock happened.
LE:*** you will most likely need to set the margins you want, since both the widget and it's layout can have them and the actual content might have higher spacing than you want.

Multiple Layers in Widget

I currently need a small ImageViewer in my project, where you can zoom in and go to next or previous image. These buttons should be fixed at right bottom corner like in this picture:
In this case I have q QLabel which has a Layout with some buttons. But now it should be zoomable, so I need QScrollArea, like explained here. But how I add my buttons again in this example? It is possible to archive this view just with QtDesigner?
Maybe QToolBar will suite your needs. It will make a floating panel over your graphics view. An example. If you need to achieve the background of the toolbar transparent while its buttons are semi-transparent then it is doable as well. But first you need to decide if toolbar works for you.

Qt window resize problem

I am having a problem redrawing a QWidget window after its size has been adjusted. I have tried update(), repaint(), adjustSize(), but all seem to suffer from the same thing: only part of the window is redrawn, resulting in the window frame on the bottom and right sides to not show. The window is also not resized entirely.
Just in case it makes a difference, the window is in a QMdiArea.
Thanks.
// ... some subwidget resizing and moving.
calibrationWindowUIs[activeWindow].layoutWidget2->move(QPoint(oldXLeft, 30 + height + 21));
calibrationWindowUIs[activeWindow].layoutWidget1->move(QPoint(oldXRight, 30 + height + 21));
// Set window size.
calibrationWindows[activeWindow]->setMinimumSize(calibrationWindowUIs[activeWindow].tabWidget->geometry().width() + 40, calibrationWindowUIs[activeWindow].tabWidget->geometry().height() + 40);
calibrationWindows[activeWindow]->update();
Note: I'm new to Qt; perhaps I'm doing something wrong with layouts?
Edit: I may have not given enough information. Alright, to be quite honest, I still have to delve deeper into layouts and related material. What I had tried to do here was to use Qt Designer in order to design the window. I've done what perhaps amounts to a stupid mistake: I didn't use an overall parent layout for the entire window, but hacked it with a couple of smaller layouts that I therefore have to move about and resize individually. See the Qt Designer screen (the red rectangles are the sole layouts): .
What is happening is that in the frame to the right, I am playing a video clip that can be of various resolutions. I want the frame to resize depending on this resolution, which also means that the buttons and window have to move/resize accordingly. That is where the window resize comes in. I'm sure there is a more elegant solution than what I am doing here, but I am trying to handle several other scenarios here and hence the lack of quality of code.
The result is that when I load a clip, the window attempts to resize, but does so badly; the following is the result:
If the window is dragged, it 'pops' into its correct size; in the meantime, however, it just looks ugly.
A couple further questions: do you use the Qt Designer to design your UIs? I found that programmatically you can achieve much better control of your interfaces. One thing which I could not do in the designer was to have a layout parented by the main widget, i.e. the equivalent of having the following bit of code:
QVBoxLayout* layout = new QVBoxLayout;
this->setLayout(layout);
A layout placed in the designer always seems to create this 'layoutWidget' subwidget, which the layout you placed is then parented to. Any way around that?
We use a mix of designer and code to create layouts, the Qt layout system can be very unintuitive at times. But I would probably not layout a full series of tabs in one designer ui file, i would make each tab each own widget and then assemble them either through code or in the designer by promoting to custom classes. This gives you better separation of responsibilities, by putting all the functionality of all the tabs into one file you almost guarantee a large unwieldy class.
When a widget has child widgets in designer you can assign a layout to it by adding it from the context menu. Make sure nothing is selected and click on the background of the widget in which you want to create a layout, select the layout and all of the widgets children will be assigned the layout.
What does help is creating hierarchies of layouts. Looking at your first screenshot, i would probably use a vertical layout with spacers on top and bottom for the items on the right, an horizontal layout with spacers left and right for the button bar and a grid layout for all the items together. Without the spacers your items will extend when the window grows. The spacers will let you control the behavior under resizing better.
you are calling setMinimumSize(). That's fine, but you should also call resize()

Displaying a popup widget in QT over application border

Let's say that I have an application frame, and I want to show a popup QCalendarWidget over on the right side of the frame. Normally, QT will clip the edges of the QCalendarWidget, cutting it in half and not displaying the rest, as it would be over the right side border.
Is there a way to work around this limitation without resorting to implementing a QDialog?
I want the widget to be visible outside the bounds of it's container.
If you'd show your Calendar, let's say, after a button click, as QDateTimeEditor does, it's contents will not be clipped, cause it do not belong to frame. It will be just a widget, that shows in a dialog manner. And maybe you should even place it in QDialog, that is modal and provides some convenience methods, rather then simple QWidget.
Btw, why don't you want to use QDatetimeEditor?