Evgenij LegotskojSept. 1, 2019, 9:15 a.m.

Qt/C ++ - Tutorial 089. Buttons with absolute positioning inside QGraphicsView

Considering the number of questions on the forum related to how to add buttons inside QGraphicsView, I decided to write a small tutorial on this topic. Moreover, there are various variations of the question. It can be a regular button, or even a mini-map, if the main QGraphicsView acts as a large map. In general, what exactly is a similar widget is not important. The bottom line is that there is the main QWidget, inside which the rest of the QWidget objects are located, which have absolute positioning inside this widget.

It will look like this.

QGraphicsView, внутри которого располагаются кнопки QPushButton с абсолютным позиционированием.


Introduction

QGraphicsView will be located in the widget of the main window and will be added through Qt Designer.

Whereas the remaining buttons will be added only through the program code. This is just one of those cases when I consider the use of a graphic designer is not the most convenient. Since in any case, you will often have to change the position of the buttons. Namely, with every resizing of the application window.

In general, the program code is quite simple, so immediately consider the header file of the application window, as well as the implementation file.

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class QPushButton;

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

    virtual void resizeEvent(QResizeEvent *event) override;

private:
    void updateButtonsPosition();

    Ui::Widget *ui;

    // Buttons with absolute positioning
    QPushButton* m_topLeftButton;
    QPushButton* m_topRightButton;
    QPushButton* m_bottomLeftButton;
    QPushButton* m_bottomRightButton;
};

#endif // WIDGET_H

Widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    // Create all buttons with absolute positioning
    m_topLeftButton = new QPushButton("Top Left", ui->graphicsView);
    m_topRightButton = new QPushButton("Top Right", ui->graphicsView);
    m_bottomLeftButton = new QPushButton("Bottom Left", ui->graphicsView);
    m_bottomRightButton = new QPushButton("Bottom Right", ui->graphicsView);
    // Update button positions
    updateButtonsPosition();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);
    // We update the button positions for each resize event of the main window
    updateButtonsPosition();
}

void Widget::updateButtonsPosition()
{
    // The logic of changing the absolute positions of buttons inside QGraphicsView
    QRect graphicsViewGeometry = ui->graphicsView->geometry();
    m_topLeftButton->setGeometry({25,
                                  25,
                                  m_topLeftButton->geometry().width(),
                                  m_topLeftButton->geometry().height()});
    m_topRightButton->setGeometry({graphicsViewGeometry.width() - m_topRightButton->geometry().width() - 25,
                                   25,
                                   m_topRightButton->geometry().width(),
                                   m_topRightButton->geometry().height()});
    m_bottomLeftButton->setGeometry({25,
                                     graphicsViewGeometry.height() - m_bottomLeftButton->geometry().height() - 25,
                                     m_bottomLeftButton->geometry().width(),
                                     m_bottomLeftButton->geometry().height()});
    m_bottomRightButton->setGeometry({graphicsViewGeometry.width() - m_bottomRightButton->geometry().width() - 25,
                                      graphicsViewGeometry.height() - m_bottomRightButton->geometry().height() - 25,
                                      m_bottomRightButton->geometry().width(),
                                      m_bottomRightButton->geometry().height()});
}

Conclusion

Thus, you can set the absolute positioning for any other widgets in your program.

The important point is that you need to transfer the widget as the parent, inside which the created widget should be located. In this case, the parent object serves not only as a controller of memory leaks, that is, to automatically delete nested objects, but also to indicate the nesting of widgets in the application GUI.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
- company blog
Support the author Donate

Евгений, добрый день.
Вопрос не совсем по теме.
А почему вы объявили класс QPushButton в заголовочном файле таким образом, а не через include? Зачем include переносить в cpp?
В чём смысл?
Вопрос без "подковырки" - действительно интересно.

Добрый день, Александр.
Это Forward Declaration - Предварительное объявление. Позволяет объявить класс без подключения заголовочного файла в заголовочном файле другого класса.
Такое объявление может использоваться как для шаблонных аргментов, так и для указателей. Если переменная объявляется на стеке в заголовочном файле, то тогда да, приходится с использованием include объявлять.

По большей части Forward Declaration преследует две основные цели:

  • Оптимизация подключения заголовочных файлов при компиляции (ну тут всё понятно)
  • Разрешение циклических зависимостей, когда один класс имеет объявленные указатели на другой класс, а второй класс в свою очередь имеет указатели на первый класс. Если в обоих классах подключать заголовочный файлы через include в заголовочных файлах, то ничего не скомпилируется. А вот подключение заголовочных файлов в cpp и с Forward Declaration позволяют разрулить такую ситуацию.

Ну и у меня уже как-то на автомате такое делается, позволяет подключать в заголовочных файлах только самое необходимое, остальное уже в cpp файлах оставлять.

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Fornex

Let me recommend you a great European Fornex hosting.

Fornex has proven itself to be a stable host over the years.

For Django projects I recommend VPS hosting

Following the link you will receive a 5% discount on shared hosting services, dedicated servers, VPS and VPN

View Hosting
YL

C++ - Test 001. The first program and data types

  • Result:66points,
  • Rating points-1
k
  • korsar
  • Nov. 23, 2022, 8:57 a.m.

C++ - Test 005. Structures and Classes

  • Result:50points,
  • Rating points-4
TM

C++ - Тест 003. Условия и циклы

  • Result:78points,
  • Rating points2
Last comments
b

GameDev on Qt - Tutorial 5. The explosion of bullets using sprite images

Если вдруг кто-то прочитает.... Скачал проект, скомпилил, запустил. Всё красиво и объектно ориентировано, но вот FPS дико страдает, когда появляется 10+ врагов. Может есть какие-то надстрой…
  • juvf
  • Nov. 25, 2022, 12:14 a.m.

Qt/C++ - Lesson 051. QMediaPlayer – simple audio player

Добрый день. Подскажите, как можно перехватить в Qt или Qml уровень воспроизводимого звука? Т.е. требуется сделать виртуальный винтажный индикатор (стрелочный или светодиодный), который бы …
  • juvf
  • Nov. 3, 2022, 3:20 a.m.

QML - Lesson 007. ListView. Dynamic creation and deletion of elements

Добрый день. Очень полезная статья. Спасибо. Вопрос такой: 1) нужно "взять" кнопку 2 пальцем (прикаснулись пальцем к кнопке 2, держим, через 2-3 кнопка оторвалась от ListView) и пере…

PyQt5 - Lesson 007. Works with QML QtQuick (Signals and slots)

А можно ли из QML сделать привязку свойства к свойству пайтоновского объекта? Ну, т.е. , например, у нашего объекта Calculator обхвялем свойства sumresult и subresult c с декоратором @pyqtProp…
MA

Python Image Recognition with TensorFlow and Keras

А что собственно выводит программа, как вывести то что она смогла распознать?
Now discuss on the forum
AB

Sorting the added QML elements in the ListModel

I am writing an alarm clock in QML, I am required to sort the alarms in ascending order (depending on the date or time (if there are several alarms on the same day). I've done the sorting …
AM

Как добавить в скрипт размер каждого файла в Мб ?

IDLE (Python 3.10 64-bit) Win 10 Есть такой скрипт: Поиск перечня файлов в папке и запись списка: import ospath = 'E:\Мой Python\__Видеокурсы Python'rez = sorted(os.listdir(pa…
n
  • nkly
  • Oct. 18, 2022, 9:14 a.m.

Как сохранить данные древовидной модели на основе QStandardItemModel в файл

Вы меня неправильно поняли. Допустим я собираю кулинарные рецепты и один из них - рецепт супа Харчо. Структура файла данных такова: { node:Рецепт супа Харчо parent:Вкусные блюда, …

Вопрос по Qt Creator

Добрый день. Не знаю, подобную проблему я не решал.

Задать другой класс div-у

Добрый день. Попробуйте использовать Selenium. Это библиотека есть в виде Python модуля и она позволяет загружать страницу и манипулировать html элементами. Как я понимаю, в ней можно…
About
Services
© EVILEG 2015-2022
Recommend hosting TIMEWEB