如何在QMainWindow中绘画?

3

我有一个非常奇怪的QPainter行为。在我的“MainWindow :: paintEvent()”中,它可以正常工作:

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

到目前为止,一切都很好。但实际上我想使用我写的类的函数来绘画,所以我的 'paintEvent()'看起来像这样:

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

而上面调用的'paint(QPainter *painter)'看起来像这样:

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

很明显,我现在期望看到一个深蓝色的背景和一个红色矩形(第二个,第一个应该被覆盖)。然而,我看到了两个红色矩形,在我的工具栏中所有图标都有深蓝色的背景。此外,“qDebug()”的输出如下所示:
painter adress in paintEvent:  0xbfd43b54
painter adress in paint:  0xbfd43b54

这肯定是同一个QPainter,但在我的类中它绘制的位置在我的工具栏图标下面!?!

1个回答

3
通常在 QMainWindow 的绘制事件中绘制任何内容都是错误的。主窗口可以有各种子小部件,你的绘图器会干扰它们 - 你没有展示任何枚举停靠窗口和子窗口等的代码。
如果要在主窗口中绘制某些东西,需要在单独的小部件中进行绘制,并通过 setCentralWidget 方法将该小部件设置为主窗口的中心小部件。
如果不需要菜单栏和停靠小部件的全部功能,则绝对不需要使用 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();
}

谢谢您的建议,但不幸的是它并没有解决我的问题。我编写了一个新类继承自QWidget,在我的MainWindow上设置了一个实例作为中央小部件,并将绘画内容移动到小部件的paintEvent()中。但仍然存在问题:只有paintEvent()中的绘画命令被执行,我的子类中的绘画被忽略了(现在它不再覆盖工具栏)。 - Bianfable
@Bianfable,你没有展示任何代码,这是不利于解决问题的。你必须提供一个完整的、单一的文件,最小化的例子来展示你正在做什么。为什么这很重要?因为我可以在这里发布一个测试用例来证明它是有效的,而我所做的只是按照我的指示操作。你的问题在于你没有展示所有的内容。这里有成百上千个像你这样的问题:他们坚持不展示自包含、最小化的代码,每次我发布反例时,他们总会说“哦,这是我其他某段代码中出现的”。别这样了,展示你的代码吧。 - Kuba hasn't forgotten Monica
1
你的例子是最简单易懂的。谢谢! - kuzavas

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