如何在QMainWindow中绘画?

时间:2014-03-14 13:49:22

标签: qt qpainter qmainwindow

我有一个非常奇怪的QPainter行为。在我的' MainWindow :: paintEvent()'它工作正常:

QPainter painter(this);
qDebug() << "painter adress in paintEvent: " << (&painter);
painter.setBrush(Qt::red);
painter.drawRect(100, 100, 100, 100);

到目前为止,这么好。但我实际上想要使用我写的类的函数来绘制,所以我的绘制事件()&#39;看起来像这样:

QPainter painter(this);
qDebug() << "painter adress in paintEvent: " << (&painter);
painter.setBrush(Qt::red);
painter.drawRect(100, 100, 100, 100);
instance_of_my_class->paint(&painter);
painter.drawRect(150, 150, 100, 100);

上面提到的&#39; paint(QPainter * painter)&#39;看起来像这样:

qDebug() << "painter adress in paint: " << painter;
painter->setBrush(QColor(0, 0, 80));
painter->drawRect(0, 0, 1000, 1000);

显然,我现在希望看到一个带有一个红色矩形的深蓝色背景(第二个,第一个应该在#39; paint&#39;内)重叠。但是,我看到两个红色矩形,在我的工具栏中,所有图标都有深蓝色背景。此外,&#39; qDebug()&#39;的输出。看起来如下:

painter adress in paintEvent:  0xbfd43b54
painter adress in paint:  0xbfd43b54

它绝对是同一个QPainter,但在我的课堂上它是在我的工具栏中的图标下方绘画!?!

1 个答案:

答案 0 :(得分:3)

QMainWindow绘画事件中绘制任何内容通常是错误的。主窗口可以具有各种子窗口小部件。你的画家很乐意干扰那些 - 你没有显示任何列举停靠窗口和子窗口的代码等。

要在主窗口中绘制某些内容,您需要在单独的窗口小部件中绘制它,并且该窗口小部件必须通过setCentralWidget提供给主窗口。

如果您不需要其全部功能,则绝对不需要使用QMainWindow。这意味着:如果您不关心菜单栏和停靠小部件,请不要使用QMainWindow

这有效:

screenshot

#include <QApplication>
#include <QMainWindow>
#include <QPainter>

class Bottom {
public:
    void paint(QPainter * p) {
        p->setBrush(Qt::blue);
        p->drawRect(0, 0, 1000, 1000);
    }
};

class Top : public QWidget {
    Bottom * m_bottom;
    void paintEvent(QPaintEvent *) {
        QPainter p(this);
        p.setPen(Qt::NoPen);
        p.setBrush(Qt::red);
        p.drawRect(0, 0, 100, 100);
        m_bottom->paint(&p);
        p.setBrush(Qt::green);
        p.drawRect(50, 50, 100, 100);
    }
public:
    Top(Bottom * bottom, QWidget * parent = 0) :
        QWidget(parent), m_bottom(bottom) {}
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QMainWindow w;
    Bottom b;
    Top t(&b);
    w.setCentralWidget(&t);
    w.setMinimumSize(200, 200);
    w.show();
    return a.exec();
}