Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Incorrect painting or geometry of custom widget
Qt 6.11 is out! See what's new in the release blog

Incorrect painting or geometry of custom widget

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 879 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Kirill GusarevK Offline
    Kirill GusarevK Offline
    Kirill Gusarev
    wrote on last edited by
    #1

    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
    
    JonBJ Pl45m4P 2 Replies Last reply
    0
    • Kirill GusarevK Offline
      Kirill GusarevK Offline
      Kirill Gusarev
      wrote on last edited by Kirill Gusarev
      #7
      This post is deleted!
      1 Reply Last reply
      0
      • Kirill GusarevK Kirill Gusarev

        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
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #2

        @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 from QWidget and defines a member variable named geometry. QWidget has geometry()/setGeometry() methods. Do yourself a favor and rename your geometry 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 GusarevK 1 Reply Last reply
        0
        • JonBJ JonB

          @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 from QWidget and defines a member variable named geometry. QWidget has geometry()/setGeometry() methods. Do yourself a favor and rename your geometry 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 GusarevK Offline
          Kirill GusarevK Offline
          Kirill Gusarev
          wrote on last edited by Kirill Gusarev
          #3

          @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

          JonBJ 1 Reply Last reply
          0
          • Kirill GusarevK Kirill Gusarev

            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
            
            Pl45m4P Offline
            Pl45m4P Offline
            Pl45m4
            wrote on last edited by Pl45m4
            #4

            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-build QGraphicsView, QGraphicsScene and QGraphicsItem (QGraphicsRectItem, QGraphicsEllipseItem... etc)
            These classes already exist as part of Qt's Graphics View Framework

            • https://doc.qt.io/qt-6/graphicsview.html

            BTW:

            @JonB has partly answered your question.
            If YOUR geometry and QWidget's geometry()/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 your Figure items.

            The mouse events are captured all over the widgets "boundings" (doesn't matter what you paint there).
            So if geometry() 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.


            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

            ~E. W. Dijkstra

            1 Reply Last reply
            2
            • Kirill GusarevK Kirill Gusarev

              @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

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #5

              @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 is const, 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 from QWidget. 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....

              1 Reply Last reply
              1
              • Kirill GusarevK Offline
                Kirill GusarevK Offline
                Kirill Gusarev
                wrote on last edited by
                #6
                This post is deleted!
                1 Reply Last reply
                0
                • Kirill GusarevK Offline
                  Kirill GusarevK Offline
                  Kirill Gusarev
                  wrote on last edited by Kirill Gusarev
                  #7
                  This post is deleted!
                  1 Reply Last reply
                  0
                  • Kirill GusarevK Kirill Gusarev has marked this topic as solved on

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved