Incorrect painting or geometry of custom widget
-
I'm trying to make my widgets moveable within a parent widget. But for some reason, a click on the widget is registered even when the cursor is located significantly above the widget. For a long time I can’t understand what the reason is. Help please :C
canvas.h
#ifndef CANVAS_H #define CANVAS_H #include <QObject> #include "figures.h" #include <functional> class Canvas : public QFrame { Q_OBJECT public: Figure *elements; // Array of figures explicit Canvas(QWidget *parent = nullptr); ~Canvas(); protected: virtual void mousePressEvent(QMouseEvent *event) override; private: bool onAddingFigure; bool onAddingLink; bool onMoving; bool onDeleting; signals: void addingFigureFinished(FigureType figureType); }; #endif // CANVAS_H
canvas.cpp
#include "canvas.h" #include <QDebug> Canvas::Canvas(QWidget *parent) : QFrame{parent} { this->setFrameShape(StyledPanel); this->setFrameShadow(Sunken); } Canvas::~Canvas() { // delete[] elements; } // For adding new figures into canvas void Canvas::mousePressEvent(QMouseEvent *event) { qDebug() << "canvas mouse press"; // Конец #define figureTypeId (FigureType::Rectangle) // заглушка emit addingFigureFinished(figureTypeId); #undef figureTypeId // заглушка }
figures.h
#ifndef FIGURE_H #define FIGURE_H #include <QObject> #include <QRect> #include <QSet> #include <QWidget> #include <QStyle> #include <QStyleOption> #include <QPainter> #include <QMouseEvent> enum class FigureType { Rectangle, Triangle, Ellipse }; class Figure : public QWidget { Q_OBJECT protected: // int x, y, w, h; QRect geometry; // Figure *linkedTo; QSet<Figure*> linkedFigures; virtual void mousePressEvent(QMouseEvent *event) override; virtual void mouseMoveEvent(QMouseEvent *event) override; public: Figure(int left, int top, int width, int height, QWidget *parent = nullptr); // explicit Figure(QWidget *parent = nullptr); void connect(Figure *figure); signals: }; class Rectangle : public Figure { Q_OBJECT public: Rectangle(int left, int top, int width, int height, QWidget *parent); // explicit Rectangle(QObject *parent = nullptr); protected: virtual void paintEvent(QPaintEvent *event) override; signals: }; class Triangle : public Figure { Q_OBJECT public: Triangle(int left, int top, int width, int height, QWidget *parent); // explicit Triangle(QObject *parent = nullptr); signals: }; class Ellipse : public Figure { Q_OBJECT public: Ellipse(int left, int top, int width, int height, QWidget *parent); // explicit Ellipse(QObject *parent = nullptr); signals: }; class Link// : public Figure { // Q_OBJECT public: Figure *figure1, *figure2; // explicit Link(QObject *parent = nullptr); //signals: }; #endif // FIGURE_H
figures.cpp
#include "figures.h" //void Figure::paintEvent(QPaintEvent *event) //{ // QStyleOption opt; // opt.initFrom(this); // QPainter painter(this); // style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this); //} void Figure::mousePressEvent(QMouseEvent *event) { this->raise(); } void Figure::mouseMoveEvent(QMouseEvent *event) { QPoint pos = event->scenePosition().toPoint(); this->move(pos); } Figure::Figure(int left, int top, int width, int height, QWidget *parent) : QWidget(parent) { this->geometry = QRect(left, top, width, height); // this->setGeometry(left, top, width, height); this->setGeometry(geometry); this->setStyleSheet("background-color: #999999"); } void Figure::connect(Figure *figure) { linkedFigures.insert(figure); figure->linkedFigures.insert(this); } Rectangle::Rectangle(int left, int top, int width, int height, QWidget *parent) : Figure(left, top, width, height, parent) { } void Rectangle::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setPen(QPen(Qt::gray, 1, Qt::SolidLine, Qt::FlatCap)); // painter.setPen(QPen(Qt::NoPen)); painter.setBrush(QBrush(0xEEEE00, Qt::SolidPattern)); qDebug() << this->geometry; painter.drawRect(this->geometry); } Triangle::Triangle(int left, int top, int width, int height, QWidget *parent) : Figure(left, top, width, height, parent) { } Ellipse::Ellipse(int left, int top, int width, int height, QWidget *parent) : Figure(left, top, width, height, parent) { } //Link::Link(QObject *parent) // : QObject{parent} //{ //}
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "canvas.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); bool addingRectangle; bool addingTriangle; bool addingEllipse; private slots: void on_figure_added(FigureType figureType); void on_pushButton_rectangle_clicked(); void on_pushButton_triangle_clicked(); void on_pushButton_ellipse_clicked(); void on_pushButton_connection_clicked(); void on_pushButton_move_clicked(); void on_pushButton_delete_clicked(); void on_pushButton_load_clicked(); void on_pushButton_save_clicked(); private: Ui::MainWindow *ui; Canvas *canvas; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); ui->graphicsView_canvas->hide(); canvas = new Canvas(this); canvas->setGeometry(10, 50, 771, 361); canvas->setStyleSheet("background-color: white;"); // These figures are just for testing. I know about memory leak :) Figure *figure1 = new Rectangle(5, 20, 200, 100, canvas); Figure *figure2 = new Rectangle(10, 10, 12, 12, canvas); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_figure_added(FigureType figureType) { } void MainWindow::on_pushButton_rectangle_clicked() { this->addingRectangle = true; } void MainWindow::on_pushButton_triangle_clicked() { this->addingTriangle = true; } void MainWindow::on_pushButton_ellipse_clicked() { this->addingEllipse = true; } void MainWindow::on_pushButton_connection_clicked() { } void MainWindow::on_pushButton_move_clicked() { } void MainWindow::on_pushButton_delete_clicked() { } void MainWindow::on_pushButton_load_clicked() { } void MainWindow::on_pushButton_save_clicked() { }
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>791</width> <height>457</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QPushButton" name="pushButton_rectangle"> <property name="geometry"> <rect> <x>10</x> <y>10</y> <width>101</width> <height>24</height> </rect> </property> <property name="text"> <string>Прямоугольник</string> </property> </widget> <widget class="QPushButton" name="pushButton_triangle"> <property name="geometry"> <rect> <x>120</x> <y>10</y> <width>81</width> <height>24</height> </rect> </property> <property name="text"> <string>Треугольник</string> </property> </widget> <widget class="QPushButton" name="pushButton_ellipse"> <property name="geometry"> <rect> <x>210</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Эллипс</string> </property> </widget> <widget class="QPushButton" name="pushButton_connection"> <property name="geometry"> <rect> <x>310</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Связь</string> </property> </widget> <widget class="QPushButton" name="pushButton_move"> <property name="geometry"> <rect> <x>410</x> <y>10</y> <width>91</width> <height>24</height> </rect> </property> <property name="text"> <string>Переместить</string> </property> </widget> <widget class="QPushButton" name="pushButton_delete"> <property name="geometry"> <rect> <x>510</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Удалить</string> </property> </widget> <widget class="QPushButton" name="pushButton_load"> <property name="geometry"> <rect> <x>630</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Загрузить</string> </property> </widget> <widget class="QPushButton" name="pushButton_save"> <property name="geometry"> <rect> <x>710</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Сохранить</string> </property> </widget> <widget class="QGraphicsView" name="graphicsView_canvas"> <property name="enabled"> <bool>true</bool> </property> <property name="geometry"> <rect> <x>10</x> <y>50</y> <width>771</width> <height>361</height> </rect> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>791</width> <height>22</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.setWindowTitle("Visio"); w.show(); return a.exec(); }
Visio.pro
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ canvas.cpp \ figures.cpp \ main.cpp \ mainwindow.cpp HEADERS += \ canvas.h \ figures.h \ mainwindow.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
-
This post is deleted!
-
I'm trying to make my widgets moveable within a parent widget. But for some reason, a click on the widget is registered even when the cursor is located significantly above the widget. For a long time I can’t understand what the reason is. Help please :C
canvas.h
#ifndef CANVAS_H #define CANVAS_H #include <QObject> #include "figures.h" #include <functional> class Canvas : public QFrame { Q_OBJECT public: Figure *elements; // Array of figures explicit Canvas(QWidget *parent = nullptr); ~Canvas(); protected: virtual void mousePressEvent(QMouseEvent *event) override; private: bool onAddingFigure; bool onAddingLink; bool onMoving; bool onDeleting; signals: void addingFigureFinished(FigureType figureType); }; #endif // CANVAS_H
canvas.cpp
#include "canvas.h" #include <QDebug> Canvas::Canvas(QWidget *parent) : QFrame{parent} { this->setFrameShape(StyledPanel); this->setFrameShadow(Sunken); } Canvas::~Canvas() { // delete[] elements; } // For adding new figures into canvas void Canvas::mousePressEvent(QMouseEvent *event) { qDebug() << "canvas mouse press"; // Конец #define figureTypeId (FigureType::Rectangle) // заглушка emit addingFigureFinished(figureTypeId); #undef figureTypeId // заглушка }
figures.h
#ifndef FIGURE_H #define FIGURE_H #include <QObject> #include <QRect> #include <QSet> #include <QWidget> #include <QStyle> #include <QStyleOption> #include <QPainter> #include <QMouseEvent> enum class FigureType { Rectangle, Triangle, Ellipse }; class Figure : public QWidget { Q_OBJECT protected: // int x, y, w, h; QRect geometry; // Figure *linkedTo; QSet<Figure*> linkedFigures; virtual void mousePressEvent(QMouseEvent *event) override; virtual void mouseMoveEvent(QMouseEvent *event) override; public: Figure(int left, int top, int width, int height, QWidget *parent = nullptr); // explicit Figure(QWidget *parent = nullptr); void connect(Figure *figure); signals: }; class Rectangle : public Figure { Q_OBJECT public: Rectangle(int left, int top, int width, int height, QWidget *parent); // explicit Rectangle(QObject *parent = nullptr); protected: virtual void paintEvent(QPaintEvent *event) override; signals: }; class Triangle : public Figure { Q_OBJECT public: Triangle(int left, int top, int width, int height, QWidget *parent); // explicit Triangle(QObject *parent = nullptr); signals: }; class Ellipse : public Figure { Q_OBJECT public: Ellipse(int left, int top, int width, int height, QWidget *parent); // explicit Ellipse(QObject *parent = nullptr); signals: }; class Link// : public Figure { // Q_OBJECT public: Figure *figure1, *figure2; // explicit Link(QObject *parent = nullptr); //signals: }; #endif // FIGURE_H
figures.cpp
#include "figures.h" //void Figure::paintEvent(QPaintEvent *event) //{ // QStyleOption opt; // opt.initFrom(this); // QPainter painter(this); // style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this); //} void Figure::mousePressEvent(QMouseEvent *event) { this->raise(); } void Figure::mouseMoveEvent(QMouseEvent *event) { QPoint pos = event->scenePosition().toPoint(); this->move(pos); } Figure::Figure(int left, int top, int width, int height, QWidget *parent) : QWidget(parent) { this->geometry = QRect(left, top, width, height); // this->setGeometry(left, top, width, height); this->setGeometry(geometry); this->setStyleSheet("background-color: #999999"); } void Figure::connect(Figure *figure) { linkedFigures.insert(figure); figure->linkedFigures.insert(this); } Rectangle::Rectangle(int left, int top, int width, int height, QWidget *parent) : Figure(left, top, width, height, parent) { } void Rectangle::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setPen(QPen(Qt::gray, 1, Qt::SolidLine, Qt::FlatCap)); // painter.setPen(QPen(Qt::NoPen)); painter.setBrush(QBrush(0xEEEE00, Qt::SolidPattern)); qDebug() << this->geometry; painter.drawRect(this->geometry); } Triangle::Triangle(int left, int top, int width, int height, QWidget *parent) : Figure(left, top, width, height, parent) { } Ellipse::Ellipse(int left, int top, int width, int height, QWidget *parent) : Figure(left, top, width, height, parent) { } //Link::Link(QObject *parent) // : QObject{parent} //{ //}
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "canvas.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); bool addingRectangle; bool addingTriangle; bool addingEllipse; private slots: void on_figure_added(FigureType figureType); void on_pushButton_rectangle_clicked(); void on_pushButton_triangle_clicked(); void on_pushButton_ellipse_clicked(); void on_pushButton_connection_clicked(); void on_pushButton_move_clicked(); void on_pushButton_delete_clicked(); void on_pushButton_load_clicked(); void on_pushButton_save_clicked(); private: Ui::MainWindow *ui; Canvas *canvas; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); ui->graphicsView_canvas->hide(); canvas = new Canvas(this); canvas->setGeometry(10, 50, 771, 361); canvas->setStyleSheet("background-color: white;"); // These figures are just for testing. I know about memory leak :) Figure *figure1 = new Rectangle(5, 20, 200, 100, canvas); Figure *figure2 = new Rectangle(10, 10, 12, 12, canvas); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_figure_added(FigureType figureType) { } void MainWindow::on_pushButton_rectangle_clicked() { this->addingRectangle = true; } void MainWindow::on_pushButton_triangle_clicked() { this->addingTriangle = true; } void MainWindow::on_pushButton_ellipse_clicked() { this->addingEllipse = true; } void MainWindow::on_pushButton_connection_clicked() { } void MainWindow::on_pushButton_move_clicked() { } void MainWindow::on_pushButton_delete_clicked() { } void MainWindow::on_pushButton_load_clicked() { } void MainWindow::on_pushButton_save_clicked() { }
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>791</width> <height>457</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QPushButton" name="pushButton_rectangle"> <property name="geometry"> <rect> <x>10</x> <y>10</y> <width>101</width> <height>24</height> </rect> </property> <property name="text"> <string>Прямоугольник</string> </property> </widget> <widget class="QPushButton" name="pushButton_triangle"> <property name="geometry"> <rect> <x>120</x> <y>10</y> <width>81</width> <height>24</height> </rect> </property> <property name="text"> <string>Треугольник</string> </property> </widget> <widget class="QPushButton" name="pushButton_ellipse"> <property name="geometry"> <rect> <x>210</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Эллипс</string> </property> </widget> <widget class="QPushButton" name="pushButton_connection"> <property name="geometry"> <rect> <x>310</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Связь</string> </property> </widget> <widget class="QPushButton" name="pushButton_move"> <property name="geometry"> <rect> <x>410</x> <y>10</y> <width>91</width> <height>24</height> </rect> </property> <property name="text"> <string>Переместить</string> </property> </widget> <widget class="QPushButton" name="pushButton_delete"> <property name="geometry"> <rect> <x>510</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Удалить</string> </property> </widget> <widget class="QPushButton" name="pushButton_load"> <property name="geometry"> <rect> <x>630</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Загрузить</string> </property> </widget> <widget class="QPushButton" name="pushButton_save"> <property name="geometry"> <rect> <x>710</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Сохранить</string> </property> </widget> <widget class="QGraphicsView" name="graphicsView_canvas"> <property name="enabled"> <bool>true</bool> </property> <property name="geometry"> <rect> <x>10</x> <y>50</y> <width>771</width> <height>361</height> </rect> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>791</width> <height>22</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.setWindowTitle("Visio"); w.show(); return a.exec(); }
Visio.pro
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ canvas.cpp \ figures.cpp \ main.cpp \ mainwindow.cpp HEADERS += \ canvas.h \ figures.h \ mainwindow.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
@Kirill-Gusarev
I would suggest this is way too much code to ask other people to look at. Reduce to a minimal, standalone example, preferably without a.ui
file.I do not know what your behaviour or issue is. But I would suggest clearing up something in your code: your
Figure
derives fromQWidget
and defines a member variable namedgeometry
.QWidget
hasgeometry()
/setGeometry()
methods. Do yourself a favor and rename yourgeometry
variable to something else, you are just asking for confusion the way you have it, especially given you are asking about a geometry issue. -
@Kirill-Gusarev
I would suggest this is way too much code to ask other people to look at. Reduce to a minimal, standalone example, preferably without a.ui
file.I do not know what your behaviour or issue is. But I would suggest clearing up something in your code: your
Figure
derives fromQWidget
and defines a member variable namedgeometry
.QWidget
hasgeometry()
/setGeometry()
methods. Do yourself a favor and rename yourgeometry
variable to something else, you are just asking for confusion the way you have it, especially given you are asking about a geometry issue.@JonB yes I know about QWidget::geometry(), but if I use this method, the error will be different - the shapes will change in position AND SIZE when moved...
I will try to minify the above code
-
I'm trying to make my widgets moveable within a parent widget. But for some reason, a click on the widget is registered even when the cursor is located significantly above the widget. For a long time I can’t understand what the reason is. Help please :C
canvas.h
#ifndef CANVAS_H #define CANVAS_H #include <QObject> #include "figures.h" #include <functional> class Canvas : public QFrame { Q_OBJECT public: Figure *elements; // Array of figures explicit Canvas(QWidget *parent = nullptr); ~Canvas(); protected: virtual void mousePressEvent(QMouseEvent *event) override; private: bool onAddingFigure; bool onAddingLink; bool onMoving; bool onDeleting; signals: void addingFigureFinished(FigureType figureType); }; #endif // CANVAS_H
canvas.cpp
#include "canvas.h" #include <QDebug> Canvas::Canvas(QWidget *parent) : QFrame{parent} { this->setFrameShape(StyledPanel); this->setFrameShadow(Sunken); } Canvas::~Canvas() { // delete[] elements; } // For adding new figures into canvas void Canvas::mousePressEvent(QMouseEvent *event) { qDebug() << "canvas mouse press"; // Конец #define figureTypeId (FigureType::Rectangle) // заглушка emit addingFigureFinished(figureTypeId); #undef figureTypeId // заглушка }
figures.h
#ifndef FIGURE_H #define FIGURE_H #include <QObject> #include <QRect> #include <QSet> #include <QWidget> #include <QStyle> #include <QStyleOption> #include <QPainter> #include <QMouseEvent> enum class FigureType { Rectangle, Triangle, Ellipse }; class Figure : public QWidget { Q_OBJECT protected: // int x, y, w, h; QRect geometry; // Figure *linkedTo; QSet<Figure*> linkedFigures; virtual void mousePressEvent(QMouseEvent *event) override; virtual void mouseMoveEvent(QMouseEvent *event) override; public: Figure(int left, int top, int width, int height, QWidget *parent = nullptr); // explicit Figure(QWidget *parent = nullptr); void connect(Figure *figure); signals: }; class Rectangle : public Figure { Q_OBJECT public: Rectangle(int left, int top, int width, int height, QWidget *parent); // explicit Rectangle(QObject *parent = nullptr); protected: virtual void paintEvent(QPaintEvent *event) override; signals: }; class Triangle : public Figure { Q_OBJECT public: Triangle(int left, int top, int width, int height, QWidget *parent); // explicit Triangle(QObject *parent = nullptr); signals: }; class Ellipse : public Figure { Q_OBJECT public: Ellipse(int left, int top, int width, int height, QWidget *parent); // explicit Ellipse(QObject *parent = nullptr); signals: }; class Link// : public Figure { // Q_OBJECT public: Figure *figure1, *figure2; // explicit Link(QObject *parent = nullptr); //signals: }; #endif // FIGURE_H
figures.cpp
#include "figures.h" //void Figure::paintEvent(QPaintEvent *event) //{ // QStyleOption opt; // opt.initFrom(this); // QPainter painter(this); // style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this); //} void Figure::mousePressEvent(QMouseEvent *event) { this->raise(); } void Figure::mouseMoveEvent(QMouseEvent *event) { QPoint pos = event->scenePosition().toPoint(); this->move(pos); } Figure::Figure(int left, int top, int width, int height, QWidget *parent) : QWidget(parent) { this->geometry = QRect(left, top, width, height); // this->setGeometry(left, top, width, height); this->setGeometry(geometry); this->setStyleSheet("background-color: #999999"); } void Figure::connect(Figure *figure) { linkedFigures.insert(figure); figure->linkedFigures.insert(this); } Rectangle::Rectangle(int left, int top, int width, int height, QWidget *parent) : Figure(left, top, width, height, parent) { } void Rectangle::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setPen(QPen(Qt::gray, 1, Qt::SolidLine, Qt::FlatCap)); // painter.setPen(QPen(Qt::NoPen)); painter.setBrush(QBrush(0xEEEE00, Qt::SolidPattern)); qDebug() << this->geometry; painter.drawRect(this->geometry); } Triangle::Triangle(int left, int top, int width, int height, QWidget *parent) : Figure(left, top, width, height, parent) { } Ellipse::Ellipse(int left, int top, int width, int height, QWidget *parent) : Figure(left, top, width, height, parent) { } //Link::Link(QObject *parent) // : QObject{parent} //{ //}
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "canvas.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); bool addingRectangle; bool addingTriangle; bool addingEllipse; private slots: void on_figure_added(FigureType figureType); void on_pushButton_rectangle_clicked(); void on_pushButton_triangle_clicked(); void on_pushButton_ellipse_clicked(); void on_pushButton_connection_clicked(); void on_pushButton_move_clicked(); void on_pushButton_delete_clicked(); void on_pushButton_load_clicked(); void on_pushButton_save_clicked(); private: Ui::MainWindow *ui; Canvas *canvas; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); ui->graphicsView_canvas->hide(); canvas = new Canvas(this); canvas->setGeometry(10, 50, 771, 361); canvas->setStyleSheet("background-color: white;"); // These figures are just for testing. I know about memory leak :) Figure *figure1 = new Rectangle(5, 20, 200, 100, canvas); Figure *figure2 = new Rectangle(10, 10, 12, 12, canvas); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_figure_added(FigureType figureType) { } void MainWindow::on_pushButton_rectangle_clicked() { this->addingRectangle = true; } void MainWindow::on_pushButton_triangle_clicked() { this->addingTriangle = true; } void MainWindow::on_pushButton_ellipse_clicked() { this->addingEllipse = true; } void MainWindow::on_pushButton_connection_clicked() { } void MainWindow::on_pushButton_move_clicked() { } void MainWindow::on_pushButton_delete_clicked() { } void MainWindow::on_pushButton_load_clicked() { } void MainWindow::on_pushButton_save_clicked() { }
mainwindow.ui
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>791</width> <height>457</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QPushButton" name="pushButton_rectangle"> <property name="geometry"> <rect> <x>10</x> <y>10</y> <width>101</width> <height>24</height> </rect> </property> <property name="text"> <string>Прямоугольник</string> </property> </widget> <widget class="QPushButton" name="pushButton_triangle"> <property name="geometry"> <rect> <x>120</x> <y>10</y> <width>81</width> <height>24</height> </rect> </property> <property name="text"> <string>Треугольник</string> </property> </widget> <widget class="QPushButton" name="pushButton_ellipse"> <property name="geometry"> <rect> <x>210</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Эллипс</string> </property> </widget> <widget class="QPushButton" name="pushButton_connection"> <property name="geometry"> <rect> <x>310</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Связь</string> </property> </widget> <widget class="QPushButton" name="pushButton_move"> <property name="geometry"> <rect> <x>410</x> <y>10</y> <width>91</width> <height>24</height> </rect> </property> <property name="text"> <string>Переместить</string> </property> </widget> <widget class="QPushButton" name="pushButton_delete"> <property name="geometry"> <rect> <x>510</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Удалить</string> </property> </widget> <widget class="QPushButton" name="pushButton_load"> <property name="geometry"> <rect> <x>630</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Загрузить</string> </property> </widget> <widget class="QPushButton" name="pushButton_save"> <property name="geometry"> <rect> <x>710</x> <y>10</y> <width>71</width> <height>24</height> </rect> </property> <property name="text"> <string>Сохранить</string> </property> </widget> <widget class="QGraphicsView" name="graphicsView_canvas"> <property name="enabled"> <bool>true</bool> </property> <property name="geometry"> <rect> <x>10</x> <y>50</y> <width>771</width> <height>361</height> </rect> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>791</width> <height>22</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.setWindowTitle("Visio"); w.show(); return a.exec(); }
Visio.pro
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ canvas.cpp \ figures.cpp \ main.cpp \ mainwindow.cpp HEADERS += \ canvas.h \ figures.h \ mainwindow.h FORMS += \ mainwindow.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target
Hi @Kirill-Gusarev ,
I don't want to question your project, but what's the idea behind this?
It seems that you are trying to re-buildQGraphicsView
,QGraphicsScene
andQGraphicsItem
(QGraphicsRectItem
,QGraphicsEllipseItem
... etc)
These classes already exist as part of Qt's Graphics View FrameworkBTW:
@JonB has partly answered your question.
If YOURgeometry
andQWidget
'sgeometry()
/setGeometry()
are not the same, the size of your widget will be different from what you actually see, due to:painter.drawRect(this->geometry);
in the
paintEvent
of yourFigure
items.The mouse events are captured all over the widgets "boundings" (doesn't matter what you paint there).
So ifgeometry()
returns a larger rectangle than the size of your visible area, you know why you receive clicks from outside the painted area.Use the in-built geometry as suggested by @JonB or make sure you update your
geometry
variable on every geometry change.
And I would rename it slightly, because it's really confusing.In case you are not aware of
QGraphicsView
and its items, take a look at it. -
@JonB yes I know about QWidget::geometry(), but if I use this method, the error will be different - the shapes will change in position AND SIZE when moved...
I will try to minify the above code
@Kirill-Gusarev said in Incorrect painting or geometry of custom widget:
yes I know about QWidget::geometry()
Then why do you define a member variable with the same name as the base class has for a public method?
but if I use this method, the error will be different
QWidget::geometry()
simply returns the current geometry of a widget. It isconst
, has no side-effects and does not cause errors.I suggested you rename your member variable from
geometry
to anything else you like, which does not clash with a public symbol fromQWidget
. And change all your calls to use the new name you pick. If that causes any change of behaviour at all you have a real problem.... -
This post is deleted!
-
This post is deleted!
-
K Kirill Gusarev has marked this topic as solved on