Проблема с рисованием поверх виджета в Qt

Я не имел, в общем-то, опыта разработки на Qt, поэтому чтобы ничего нечаянно не испортить начал с проекта-примера с сайта Qt. Вот сам проект Image Viewer.

Техническая суть проекта: класс ImageViewer населдует QMainWindow, устанавливает своим «центральным виджетом» зону прокрутки QScrollArea, в которой находится QLabel с картинкой.

Исходный код есть на той же страничке в разделе «Files» сверху.

Проблема заключается в следующем: я хотел выполнять некое рисование поверх отображаемой картинки, но для примера сведём задачу к тому, чтобы просто нарисовать линию.

Вооружившись гуглом, я пришёл к такому варианту:

в файле imageviewer.h подключаем библотеку для рисования:
#include <QPainter>


и добавляем обработчик события отрисовки в класс:
protected:
    void paintEvent(QPaintEvent *);


В imageviewer.cpp опишем этот обработчик:
void ImageViewer::paintEvent(QPaintEvent * e)
{
    QPainter p(this);

    p.drawLine(0,0,100,100);
} 


Ожидалось, что в левом верхнем углу появится линия, но… нет.

Мне кажется, что проблема в том, что scrollArea перекрывает линию, поэтому для эксперимента я закомментировал строку
setCentralWidget(scrollArea);

в методе ImageViewer::ImageViewer(). Линия появилась, но картинка, понятно, перестала отображаться.

Пытался рисовать на scrollArea, так же безуспешно (картинка есть, линии нет):
void ImageViewer::paintEvent(QPaintEvent * e)
{
    QPainter p(scrollArea);

    p.drawLine(0,0,100,100);
}

Этот код выдавал в консоль QCreator-а сообщения вида
QPainter::begin: Paint device returned engine == 0, type: 1


Гугление привело к идее рисовать на scrollArea->viewport(), не помогло.

Внимание, вопрос: как сделать то же самое, но правильно?)
  • Вопрос задан
  • 14112 просмотров
Решения вопроса 1
Mezomish
@Mezomish
Унаследуйтесь от QLabel, переопределите его paintEvent, а в нём сначала вызовите QLabel::paintEvent(event);, после чего добавьте ваше собственное рисование.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Mezomish
@Mezomish
Собсна, код:

#include <QMainWindow>
#include <QScrollArea>
#include <QLabel>
#include <QApplication>
#include <QPainter>

class MyLabel : public QLabel {
protected:
	virtual void paintEvent(QPaintEvent* e) {
		QLabel::paintEvent(e);
		
		QPainter p(this);
		
		p.setPen(Qt::green);
		p.drawLine(0, 0, 100, 100);
	}
};

class ImageView : public QMainWindow {
public:
	
	ImageView() : QMainWindow() {
		QScrollArea* scr = new QScrollArea();
		setCentralWidget( scr );
		
		QLabel* label = new MyLabel();
		label->setPixmap(QPixmap("./moon_from_andrey.jpg"));
		scr->setWidget(label);
	}
};


int main(int argc, char* argv[]) {
	QApplication app(argc, argv);
	
	ImageView view;
	view.setGeometry(100, 100, 500, 400);
	view.show();
	
	return app.exec();
}



Результат:

Ответ написан
kulinich
@kulinich
С++ программист
Я как-то рисовал на кнопке так:
void PaintButtonUp::paintEvent(QPaintEvent *event) { QPushButton::paintEvent(event); QPainter paint(this); static const QPointF points[3] = { QPointF(3.0, 25.0), QPointF(10.0, 15.0), QPointF(17.0, 25.0), }; paint.setPen(QPen(Qt::darkGray, 2, Qt::SolidLine, Qt::RoundCap)); paint.setRenderHint(QPainter::Antialiasing, true); paint.setBrush(QBrush(Qt::gray, Qt::SolidPattern)); paint.drawPolygon(points, 3); }

Т.е. сначала вызывался стандартный метод
QPushButton::paintEvent(event);
а затем уже я отрисовывал на кнопке то, что мне было нужно.

Не знаю поможет это Вам или нет.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы