Как сделать холст QWidget, который можно увеличивать и рисовать? - PullRequest
0 голосов
/ 23 сентября 2019

Я пытаюсь создать холст для рисования с помощью мыши, аналогично большинству приложений для цифровой рисования, которые я также могу увеличивать (увеличивать нарисованное изображение)

Пока что я создалкласс, который использует QWidget и добавил его к пользовательскому интерфейсу, затем использует события мыши и QPaintEvent, чтобы рисовать на этом виджете, который работает.Однако проблема, я не уверен, как мне увеличить это тоже?Я попытался разместить QWidget внутри прокручиваемой области, но он не позволяет регистрировать события щелчка.Я также попытался расширить QGraphicsViewer вместо QWidget, но это также мешает мне рисовать.

//Class definition
PaintArea::PaintArea(QWidget *parent) : QWidget(parent)
{
    this->setMouseTracking(true);
}

Я в основном ищу рекомендации о том, как прокручивать и рисовать с помощью мыши.виджет (возможно, с полосой прокрутки, но просто прокруткой колесика) Спасибо

1 Ответ

0 голосов
/ 23 сентября 2019

Если вы следуете пути QWidget, вы можете внимательно посмотреть на пример scribble , который включен в Qt docs.В этом примере рисунок выполняется за пределами экрана на объекте QImage, который затем рисуется виджетом.Проблема в том, чтобы увеличить изображение.

Я предпочитаю второй способ: QGraphicsView имеет функцию scale () среди многих других замечательных функций.Вы можете сделать что-то похожее на пример наброска: рисовать за пределами экрана на изображении QPixmap, которое устанавливается (каждый раз, когда вы меняете изображение) в QGraphicsPixmapItem, который принадлежит QGraphicsScene.Я реализовал этот грубый пример, позаимствовав некоторые элементы из примера каракулей.Используйте колесо мыши, чтобы увеличить изображение (оно немного прокручивает прокрутку).

test.pro

QT += core gui widgets
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
    drawablescene.cpp \
    main.cpp \
    mainwindow.cpp
HEADERS += \
    drawablescene.h \
    mainwindow.h

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "drawablescene.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);
    void wheelEvent(QWheelEvent *event) override;

private:
    QGraphicsView *m_view;
    DrawableScene *m_scene;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include <QGraphicsView>
#include <QWheelEvent>
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      m_view(new QGraphicsView(this)),
      m_scene(new DrawableScene(this))
{
    setCentralWidget(m_view);
    m_scene->setSceneRect(0,0,640,480);
    m_view->setScene(m_scene);
}

void MainWindow::wheelEvent(QWheelEvent *event)
{
    qreal delta = 1 + (event->delta() > 0 ? 0.1 : -0.1);
    m_view->scale(delta, delta);
    event->accept();
}

drawablescene.h

#ifndef DRAWABLESCENE_H
#define DRAWABLESCENE_H

#include <QObject>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>

class DrawableScene : public QGraphicsScene
{
public:
    explicit DrawableScene(QObject *parent = nullptr);

private:
    void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
    void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
    void drawLineTo(const QPointF &endPoint);

    bool m_modified;
    bool m_scribbling;
    int m_penWidth;
    QColor m_penColor;
    QPointF m_lastPoint;
    QPixmap *m_image;
    QGraphicsPixmapItem *m_item;
};

#endif // DRAWABLESCENE_H

drawablescene.cpp

#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include "drawablescene.h"

DrawableScene::DrawableScene(QObject *parent)
    : QGraphicsScene(parent),
      m_modified(false),
      m_scribbling(false),
      m_penWidth(3),
      m_penColor(Qt::blue)
{
    m_image = new QPixmap(640, 480);
    m_image->fill(Qt::white);
    m_item = addPixmap(*m_image);
}

void DrawableScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if ((event->buttons() & Qt::LeftButton) && m_scribbling) {
        drawLineTo(event->scenePos());
        event->accept();
    }
    else QGraphicsScene::mouseMoveEvent(event);
}

void DrawableScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_lastPoint = event->scenePos();
        m_scribbling = true;
        event->accept();
    }
    else QGraphicsScene::mousePressEvent(event);
}

void DrawableScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && m_scribbling) {
        drawLineTo(event->scenePos());
        m_scribbling = false;
        event->accept();
    }
    else QGraphicsScene::mouseReleaseEvent(event);
}

void DrawableScene::drawLineTo(const QPointF &endPoint)
{
    QPainter painter(m_image);
    painter.setPen(QPen(m_penColor, m_penWidth, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin));
    painter.drawLine(m_lastPoint, endPoint);
    m_modified = true;
    m_lastPoint = endPoint;
    m_item->setPixmap(*m_image);
}
...