【问题标题】:Draw a line with QPainter using QGraphicsView subclass使用 QGraphicsView 子类用 QPainter 画一条线
【发布时间】:2016-06-23 02:49:09
【问题描述】:

问题: 我无法调用 GraphicsView 的 paintEvent,或者换句话说,我不知道如何让 QPainter 完全工作。

  • 我正在使用 qtcreator 的设计器将 QGraphicsView 放置到主窗口中。
  • 我将 QGraphicsView (class Draw) 子类化为覆盖 paintEvent 并在主窗口中保存此子类 (Draw draw) 的实例(我想将复杂的绘图移至其他位置)
  • 我创建了一个new QGraphicsScene 并将其分配给QGraphicsView'sui->graphicsViewdraw),所以当我在Draw 内绘图时,它也会在
    ui->graphicsview 中明显生效(我希望)。
  • 我确定当我使用新的scene 对象进行绘图时,我会得到一个可见的结果(但是,我不想使用scene 对象进行绘图,而是使用QPainter。原因是另一个问题,所以我希望它不是必需的)因此我试图继承QGraphicsView并覆盖paintEvent,以便我轻松获得QPainter p(this)
  • 当事件发生时,我在Window.cpp 中调用MyRepaint(),我试图在我的Draw 对象上调用paintEvent() - 但它不起作用。

主窗口“Window.cpp”:

Window::Window(QWidget* parent) :
    QMainWindow(parent),
    ui(new Ui::Window),
    draw(*this)  //my own QGraphicsView instance (see class below)
{
    ui->setupUi(this);
    //assigning a new scene to draw and to window's graphicsView
    this->scene = new QGraphicsScene(this);
    this->draw.setScene(scene);
    this->ui->graphicsView->setScene(scene);
}

void Window::MyRepaint()
{
    qInfo() << "Repaint - start" << this->draw.scene();
    this->draw.scene()->update(this->draw.sceneRect());
    this->draw.repaint();
    this->draw.viewport()->update();
    /*only the following line made the paintEvent executed eventually but without a visible result and with an error in the output*/
    this->draw.paintEvent(NULL);
    qInfo() << "Repaint - end"; 
}

子类化 QGraphicsView,文件:Draw.h:

class Window;
class Draw : public QGraphicsView{
private:
    Window& parent;

public:
    Draw(Window &parent);
    void paintEvent(QPaintEvent*e) override;
};

绘制.cpp

void Draw::paintEvent(QPaintEvent *e)
{
    qInfo() << "trying to draw";
    QPainter p(this);
    p.setPen(QPen(Qt::black, 12, Qt::DashDotLine, Qt::RoundCap));
    p.drawLine(0, 0, 200, 200);
}

输出:

Repaint - start QGraphicsScene(0x15c7eca8)
trying to draw
QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
QPainter::viewport: Painter not active
QPainter::end: Painter not active, aborted
Repaint - end

也许我选择了一个完全错误的方法。

【问题讨论】:

    标签: c++ qt qgraphicsview qpainter


    【解决方案1】:

    QGraphicsView 旨在与 QGraphicsScene 一起使用。如果你只想画线,那么从 QWidget 派生并覆盖它的paintEvent。在设计器中将 QWidget 提升为您的派生类。

    另外,Qt 有一个很好的文档。我建议你访问this页面。

    【讨论】:

    • 是的,我用谷歌搜索了那个页面,这是一篇不必要的太长的文章。我需要一个最小的示例和教程如何做到这一点。现在我在看你提到的“促销活动”,我不知道。
    • bitbucket.org/K117/qtlineexample/src 我能写的最简单的行示例。
    • 促销。在 Designer 中单击小部件上的 RMB 并选择“Promote to...”,输入派生类的名称。您可以将小部件提升到派生自它的类。
    • QPainter 是比较低级的工具,你得自己把它弄白。 painter.fillRect(rect(), Qt::white); 在任何其他绘图之前。
    【解决方案2】:

    简而言之,您可以使用QGraphicsLineItem *QGraphicsScene::addLine(...)

    这是画线的Graphics View Framwork方式,而接受的答案是QWidget方式

    QGraphicsView 是图形视图框架的一部分。通常通过调用 update(),小部件能够触发paintEvent()。但是,据我所知,在 Graphics View Framework 中,QGraphicsView 不可能通过调用 update() 来触发paintEvent()

    还有一件事,你应该知道,根据qt文档:

    警告:当paintdevice是一个widget时,QPainter只能在paintEvent()函数内部或者由paintEvent()调用的函数中使用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-31
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 2016-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多