GUI应用中的QPainter错误

4

我正在尝试用C ++编写一个GUI,将图形绘制在上面。我收到了一系列错误消息,所有错误消息都是这样的: “QPainter :: begin:小部件绘画只能作为paintEvent的结果开始” 似乎没有任何东西被绘制。

main.cpp

#include <QApplication>
#include <QFont>
#include <QPushButton>
#include <iostream>

using namespace std;

#include "skewNormal.h"
#include "ui.h"

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    Window w;
    #if defined(Q_OS_SYMBIAN)
    w.showMaximized();
    #else
    w.show();
    #endif
    return app.exec();
}

ui.h

#ifndef UI_H_INCLUDED
#define UI_H_INCLUDED
#include <QtGui/QMainWindow>

class Window : public QWidget
{
    public:
    Window();

    void paintEvent ( QPaintEvent * event );
};



#endif // UI_H_INCLUDED

ui.cpp

#ifndef GRAPHPN3670_H
#define GRAPHPN3670_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QPaintEvent>
#include <QtGui/QGraphicsView>
#include <QtGui/QHeaderView>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QStatusBar>
#include <QtGui/QWidget>
#include <QtCore/QRect>
#include <iostream>

using namespace std;

#include "ui.h"
#include "skewNormal.h"

Window::Window()
{
    cout<<"Hello1";
}

void Window::paintEvent ( QPaintEvent * event ){
    cout<<"Hello from paint event";
    QPainter p(this);
    int xL = -width() / 2;
    int yL = 0;
    for(int x = -width() / 2; x < width() / 2; x++)
    {
        int y = getSkewNormal(0.5, x);
        p.drawLine(xL + width() / 2, height() - yL, x + width() / 2, height() - y);
        xL = x;
        yL = y;
    }
}

#endif // GRAPHPE3488_H

@LoSciamano 我该怎么修复这个问题? - Ryan Amos
是的,偏斜代码可行。我已经单独测试过了。我会将其删除。我只是想把所有东西都放在那里以防万一。编辑:完成了! :D - Ryan Amos
不,我的意思是甚至不要调用它。将你的paintEvent更改为除了从小部件的一个角落绘制一条线到对角线以外什么都不做,看看是否有效。 - Steve S
我尝试添加一个填充矩形:http://pastie.org/private/vewpsv5mjmj2dkvdcbwva。但它不起作用。 - Ryan Amos
2
默认画刷(您似乎正在使用)的样式为 Qt::NoBrush - Steve S
显示剩余5条评论
4个回答

4

来自Qt文档:

警告:当绘制设备是一个窗口部件时,QPainter只能在paintEvent()函数内或由paintEvent()调用的函数中使用;除非设置了Qt::WA_PaintOutsidePaintEvent窗口部件属性。在Mac OS X和Windows上,无论此属性的设置如何,您只能在paintEvent()函数中进行绘制。

注意:本文中的“绘制设备”指的是绘制目标,例如QWidget、QPixmap等。

好的,这修复了错误。但它仍然没有绘制。paintEvent会自动触发吗?还是需要手动调用?编辑:是的,它会自动触发。我会发布我的代码,稍等一下。编辑2:已发布。 - Ryan Amos
@Somanayr:这是自动的。请查看http://doc.qt.nokia.com/4.7/qwidget.html#paintEvent。 - Steve S
好的,但它仍然没有绘制 :( 我对绘画做错了一些设置吗? - Ryan Amos
setAttribute(Qt::WA_PaintOutsidePaintEvent, true); 解决了问题。谢谢! - Md. Minhazul Haque

3

你没有正确地进行小部件绘制。

正确的方法是这样的:

// Add this method to your widget class
virtual void paintEvent(QPaintEvent * e)
{
   QPainter p(this);
   // Add all calls to p.drawPoint(), etc here
}

...这是你应该使用QPainter的唯一地方。每当你想让你的小部件重新绘制自己时,调用小部件上的update()方法,Qt会在此后不久为你调用paintEvent()。


QPainter没有构造函数QPainter(PaintEvent *e)。你需要使用一个QPaintDevice的QWidgit。我已经在原始帖子中更新了修复方法。 - Ryan Amos
糟糕 - 这就是我从记忆中编写代码的后果。我会修复我的帖子。 - Jeremy Friesner

2
你需要显示窗口。
Window w;
w.show()
return app.exec();

尝试从构造函数中删除 show() 并像 @Martin 建议的那样调用它。 - yasouser
是的,我尝试过了并在原帖中指出了。结果是在窗口关闭后才调用构造函数和主方法的其余部分。 - Ryan Amos
我把更新后的代码放在原帖中。然后我遇到了一堆错误,都是"QPainter::begin: Widget painting can only begin as a result of a paintEvent"。 - Ryan Amos

2

首先,按照Martin Beckett的建议调用show()。其次,你不能自己调用paintEvent()。你需要重写paintEvent()并在那里进行绘图。请参见我在这个答案中提供的示例。


你能看一下我提供的修复吗?我没有覆盖paintEvent,而是简单地修改了我的绘制方法。 - Ryan Amos
那样做不行。运行程序应该能够证明这一点。你不能在小部件的构造函数中绘制。 - Arnold Spence
好的,让我再试一次 :) 你不仅不能在构造函数中进行绘图,除了重写paintEvent()方法外,也不能从任何其他位置或方法进行绘图。 - Arnold Spence
是的,有人刚刚解释了那个。我不理解那部分。现在它可以工作了,没有错误。但是它没有绘制 :(. 我已经更新了原始帖子以反映这些更改。 - Ryan Amos
1
也许你可以在paintEvent()中做一些简单的事情,比如从0,0画一条线到100,100,以排除几何计算问题。也许尝试设置笔的颜色。 - Arnold Spence
我尝试了这两个方法。结果是一样的:一个灰色的窗口。这是方法:http://pastie.org/private/vewpsv5mjmj2dkvdcbwva。我不知道哪里出了问题,虽然我敢打赌这是一些非常愚蠢的错误。我知道它进入了该方法,因为有控制台输出。 - Ryan Amos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接