问:如何将小部件绘制重定向到父小部件?

时间:2017-05-10 07:40:35

标签: c++ qt widget

我正在为绘图目的创建一些自定义qt设计器小部件插件。使用这些小部件,用户可以使用qt设计器进行绘制,就像Microsoft Visio一样(希望如此)。

如下面的屏幕截图所示,有一个SvPage对象page_0作为容器,它包含一个SvArc小部件和一个SvCircle小部件。

除了当一个小部件(A)覆盖其他小部件(B),用户无法轻松选择小部件B时,每件事情都很好。

为了解决这个问题,我试图这样做:

  1. 将每个绘图小部件(例如SvArc,SvCircle)的大小设置为非常小(40px * 40 px);

  2. 将绘图窗口小部件的内容直接绘制到其父窗口小部件(SvPage)。在SvPage::PaintEvent(QPaintEvent event) 中,它会迭代所有绘制小部件的子项,并调用每个子项的doPaint(QPainter painter)方法。

  3. 第3。要自动刷新绘图窗口小部件(例如,当移动SvArc窗口小部件时,其在SvPage上的绘图应自动更新),在绘图窗口小部件的SvArc::PaintEvent(QPaintEvent *event)中,它将触发SvPage以更新其绘图。 /强>

    但是在第3步中,存在导致递归重绘问题的问题: 因为SvArc :: PaintEvent()触发SvPage :: PaintEvent(),然后SvPage :: PaintEvent()将再次触发SvArc :: PaintEvent(),因为SvArc小部件是SvPage小部件的子窗口小部件。

    所以,问题是将窗口小部件绘制重定向到父窗口小部件是个好主意吗?如果是,如何解决递归重绘问题?如果不是,那么好的是什么?

    代码(简化):

    void SvPage::paintEvent(QPaintEvent *event)
    {
        initPainter();
        QList<SvWidget*> widgets = this->findChildren<SvWidget*>();
        for (int i = 0; i < widgets.count(); i++)
        {
            SvWidget* w = widgets.at(i);
            w->doPaint(this->painter);
        }
        destoryPainter();
    }
    
    void SvWidget::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
        emit signalDoPaint();
    }
    
    void SvArc::doPaint(QPainter* painter)
    {
        painter->drawArc(x, y, w, h, a alen);
    }
    

    enter image description here

2 个答案:

答案 0 :(得分:4)

你在搞乱这里。

每个小部件都应该负责自己的绘图。这就是Qt的设计方式。

您可以使用单个窗口小部件作为某些对象的管理器,并绘制它们,但是这些对象不需要是窗口小部件,它们可以是简单的数据表示形式。在这种情况下,对象不会涉及任何绘画,它将是管理器小部件。

然而,这种方法的效率会降低。因为当您有多个独立小部件时,绘制引擎可以轻松检测更改并有效地重新绘制需要更新的部分。

在你的情况下,你要么必须进行大量的冗余重新绘制,要么实施更复杂的项目管理,这将是一项复杂的任务,如果你能够开始,那将是绝对不值得的。和,你可能不是。

您目前的做法非常糟糕。我建议只是坚持常规的小工具,以实际的尺寸,做他们的实际绘画。您可以更轻松地实现和管理它,并且计算机绘制它会更容易。

至于在重叠小部件之间进行选择,QWidget并未真正设计用于促进这一点。小部件应该放在布局中,而不是重叠。这就是为什么它的childAt()函数只能返回给定坐标的单个小部件。

您应该使用QGraphicsSceneQGraphicsViewQGraphicsItem。与小部件类似,图形项目将有效地处理他们自己的绘图,区别在于API是为图形设计的,当您有重叠项目时,QGraphicsScene::items()将为您提供该位置的所有项目的列表,因此您可以选择了除最顶层以外的项目。

答案 1 :(得分:0)

  

我正在为绘图目的创建一些自定义Qt Designer小部件插件。使用这些小部件,用户可以使用Qt Designer进行绘制,就像Microsoft Visio一样(希望如此)。

您在Qt Designer中重复使用的功能很少,可以轻松地分解到单独的项目中。对您而言唯一有价值的是属性检查器窗格。

对于其他一切,使用小部件是最复杂的实现方式。使用QGraphicsSceneQGraphicsView并开始使用已经实施的90%的功能并准备就绪。

QGraphicsScene中实施一个基本的矢量插图系统是下午的工作。您可以在几天内完成早期Corel Draw的功能,从Windows 2.x开始。它总体上证明了场景框架和现代发展框架的力量。