繁体   English   中英

Qt如何将小部件绘画重定向到父小部件?

[英]Qt how to redirect widget painting to parent widget?

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

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

一切都很好,只是当一个小部件(A)覆盖另一个小部件(B)时,用户无法轻松选择小部件B。

为了解决这个问题,我正在尝试做:

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

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

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

在此处输入图片说明

您在这里弄乱了。

每个小部件都应对自己的图形负责。 这就是Qt设计的工作方式。

您可以将单个窗口小部件用作某些对象的管理器,并绘制它们,但随后这些对象不必是窗口小部件,它们可以是简单的数据表示形式。 在这种情况下,对象将不会与任何绘画有关,而将由管理器小部件来完成。

但是,该方法效率较低。 因为当您具有多个独立的小部件时,绘制引擎可以轻松地检测到更改并仅有效地重新绘制需要更新的零件。

在您的情况下,您要么必须做大量的重复粉刷,要么实施更复杂的项目管理,这将是一项复杂的任务,即使您一开始就愿意这样做,这绝对是不值得的。你可能不是。

您当前的方法非常糟糕。 我建议只坚持使用实际大小的常规小部件进行实际绘画。 您可以轻松实现和管理它,并且计算机可以轻松绘制它。

至于在重叠的窗口小部件之间进行选择, QWidget设计并不是为了真正做到这一点。 小部件应该放置在布局中,而不要重叠。 这就是为什么其childAt()函数只能在给定坐标处返回单个小部件的原因。

您真正应该做的是使用QGraphicsSceneQGraphicsViewQGraphicsItem 与窗口小部件类似,图形项将有效地处理其自己的图形,不同之处在于该API是为图形设计的,并且当您有重叠项时, QGraphicsScene::items()会为您提供该位置所有项的列表,因此您可以选择最顶层以外的其他项目。

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

您在Qt Designer中重用的功能很少,可以很容易地分解到一个单独的项目中。 对您来说唯一有价值的是属性检查器窗格。

对于其他所有方面,使用小部件是实现它的最复杂方法。 使用QGraphicsSceneQGraphicsView并从已经实现并准备就绪的功能的90%开始。

QGraphicsScene实现基本的矢量插图系统是一项下午的工作。 几天之内就可以完成Windows 2.x上具有Corel Draw早期功能的功能。 总体而言,这证明了场景框架和现代开发框架的强大功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM