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
Forum Updated to NodeBB v4.3 + New Features

Incorrect painting or geometry of custom widget

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 408 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