【问题标题】:How to make a canvas QWidget that can be zoomed and drawn on?如何制作可以缩放和绘制的画布 QWidget?
【发布时间】:2019-09-23 09:15:57
【问题描述】:

我正在尝试创建一个画布以使用鼠标进行绘制,类似于大多数数字绘画应用程序,我也可以放大(放大绘制的图像)

到目前为止,我已经创建了一个使用 QWidget 的类并将其添加到 ui 中,然后使用鼠标事件和 QPaintEvent 来绘制这个有效的小部件。但是我不确定如何放大这个问题?我尝试将 QWidget 放在可滚动区域内,但它阻止它注册点击事件。我也尝试从 QGraphicsViewer 而不是 QWidget 扩展,但这也阻止了我绘画。

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

我主要是在寻找有关如何在同一个小部件上使用鼠标滚动和绘图的建议(可能带有滚动条,但肯定只是滚轮滚动) 谢谢

【问题讨论】:

标签: c++ qt qwidget qpainter


【解决方案1】:

如果您遵循 QWidget 方式,您可能需要仔细查看 Qt 文档中包含的 scribble example。在这个例子中,绘图是在 QImage 对象上进行的,然后由小部件绘制。问题是缩放图像。

我更喜欢您的第二种方式:QGraphicsView 具有 scale() 功能以及许多其他出色的功能。您可以执行类似于涂鸦示例的操作:在 QPixmap 图像上绘制屏幕外,该图像被设置(每次更改图像)到属于 QGraphicsScene 的 QGraphicsPixmapItem。我已经实现了这个粗略的例子,从 scribble 例子中借用了一些元素。使用鼠标滚轮缩放图像(它有点拧紧滚动,抱歉)。

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();
}

主窗口.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

主窗口.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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-06
    • 2014-05-14
    • 2015-03-06
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多