Рисование подкласса основного класса в Qt

Я создал основной класс с именем widget.cpp, который наследует QFrame. А из widget.cpp я создаю подкласс с именем frame.cpp, в котором я переопределяю метод paintEvent () для рисования изображения. Проблема в том, что когда я пытаюсь нарисовать изображение напрямую через widget.cpp, создав для него метод paintEvent, он работает нормально. Но в другом случае, когда я реализую его в подклассе frame.cpp, он не работает нормально. Есть ли что-то, что я делаю не так здесь?

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QFrame>
#include <QPainter>
#include "frame.h"
class frame;
namespace Ui {
class Widget;
}
class Widget : public QFrame
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
frame * f;
};
#endif // WIDGET_H

введите описание изображения здесь

widget.cpp

#include "widget.h"#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QFrame(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
f = new frame(ui->frame);
f->show();
}

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

frame.h

#ifndef FRAME_H
#define FRAME_H

#include <QObject>
#include <QWidget>
#include <QPainter>

class frame : public QWidget
{
Q_OBJECT
public:
explicit frame(QWidget *parent = 0);

protected:
void paintEvent(QPaintEvent *p);

signals:

public slots:
};

#endif // FRAME_H

frame.cpp

#include "frame.h"
frame::frame(QWidget *parent) : QWidget(parent)
{

}

void frame::paintEvent(QPaintEvent *p)
{
QPainter* pPainter = new QPainter(this);
QImage img(":/left.png");
Q_ASSERT(!img.isNull());
QRect source(0,0,20,10);
QRect target(50,50,20,10);
pPainter->drawImage(target, img,source);
QWidget::paintEvent(p);
QWidget::update();
}

Если я использую цель QRect (0,0,20,10) в приведенном выше коде, изображение рисуется.

testImage.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = testImage
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += main.cpp\
widget.cpp \
frame.cpp

HEADERS  += widget.h \
frame.h

FORMS    += widget.ui

RESOURCES += \
src.qrc

DISTFILES +=

widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>823</width>
<height>468</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>200</x>
<y>60</y>
<width>420</width>
<height>300</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>420</width>
<height>300</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>420</width>
<height>306</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

0

Решение

Если вы хотите заменить виджет класса X, вы должны создать класс, который наследуется от этого класса, в вашем случае фрейм должен наследовать от QFrame а не прямо из QWidget, так как Qt Designer будет использовать QFrame методы, которые QWidget не имеет, вместо этого класс, который наследует от QFrame если будет их.

Таким образом, вы должны изменить следующую часть в вашем коде.

frame.h

class frame : public QFrame
{
...

frame.cpp

frame::frame(QWidget *parent) : QFrame(parent)
{

}

Другая ошибка, которая наблюдается в вашем коде, это то, что вы звоните update() внутри paintEvent(), это может генерировать бесконечный цикл, так как update() звонки paintEvent() косвенно. Также виджет вашего пространства для рисования, это пространство мы можем получить через метод rect(), если вы рисуете за пределами этого пространства ничего не нарисовано. Другой плохой практикой является создание указателя на QPainter поскольку он будет постоянно вызываться для этого метода, и вы будете создавать память в дополнение к тому, что вы удаляете ее правильно. Из вышесказанного предлагаю следующий код:

void frame::paintEvent(QPaintEvent *p)
{
QWidget::paintEvent(p);
QPainter pPainter(this);
QImage img(":/left.png");
Q_ASSERT(!img.isNull());
QRect source(0,0,20,10);
QRect target(50,50,20,10);
pPainter.drawImage(target, img, source);
}

И самое главное, когда вы бежите f = new frame(ui->frame); вы создаете новый виджет, который по умолчанию занимает позицию относительно родителя, поэтому вы видите изображение, но это не подходит, вам нужно продвигать виджет.

Для продвижения правой кнопкой мыши на QFrame это в QtDesigner, и будет отображаться меню, выберите «Продвигаемые виджеты», открыв диалоговое окно, в котором вы должны указать в названии «Продвигаемого класса» имя класса, который вы создали, в вашем случае Рамка , и в заголовочном файле .h файл вашего класса, в вашем случае frame.h, затем нажмите кнопку добавления, а затем кнопку продвижения. Как показано на следующих изображениях:

введите описание изображения здесь

введите описание изображения здесь

После компиляции вашего проекта в качестве окончательной рекомендации измените имя виджета в Qt Designer фрейма на другое, например, myFrame, чтобы не было путаницы с именем класса.

введите описание изображения здесь

Полный пример можно найти в следующем ссылка на сайт

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]