Draw a line with QPainter using QGraphicsView subclass

六眼飞鱼酱① 提交于 2019-12-06 14:48:41

问题


Question: I can't make the GraphicsView's paintEvent be called or in other words I don't know how to make QPainter work altogether.

  • I'm using qtcreator's designer to place a QGraphicsView into the main window.
  • I sub-classed QGraphicsView (class Draw) overriding the paintEvent and hold an instance of this subclass (Draw draw) in the main window (I wanted to move the complicated drawing elsewhere)
  • I created a new QGraphicsScene and assign it to both QGraphicsView's (ui->graphicsView and draw) so when I draw inside the Draw it would visibly take effect in the
    ui->graphicsview as well (I hope).
  • I'm sure when I draw using the new scene object, I get a visible result (however, I don't want to use the scene object for drawing but the QPainter. The reason why is for another question so I hope it's not essential) Therefore I'm trying to subclass the QGraphicsView and override the paintEvent so I get the QPainter p(this) easily.
  • When an event occurs I call MyRepaint() in Window.cpp where I'm trying to invoke paintEvent() on my Draw object - but it's not working.

Main window '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"; 
}

subclassing QGraphicsView, file: Draw.h:

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

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

Draw.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);
}

Output:

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

Maybe I've chosen a completely wrong approach.


回答1:


QGraphicsView is designed to work with QGraphicsScene. If you just want to draw lines, then derive from QWidget and override it's paintEvent. In designer promote QWidget to your derived class.

Also, Qt has a good documentation. I advice you to visit this page.



来源:https://stackoverflow.com/questions/37981512/draw-a-line-with-qpainter-using-qgraphicsview-subclass

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!