【发布时间】:2017-10-08 17:43:19
【问题描述】:
我正在创建一些用于绘图的自定义 qt 设计器小部件插件。通过这些小部件,用户可以像 Microsoft Visio 一样使用 qt Designer 进行绘图(希望如此)。
如下截图所示,有一个SvPage对象page_0作为容器,它包含一个SvArc小部件和一个SvCircle小部件。
一切都很好,除了当一个小部件 (A) 覆盖另一个小部件 (B) 时,用户无法轻松选择小部件 B。
为了解决这个问题,我正在尝试做:
将每个绘图小部件(例如SvArc、SvCircle)的大小设置为非常小(40px * 40 px);
将绘图小部件的内容直接绘制到其父小部件 (SvPage)。在
SvPage::PaintEvent(QPaintEvent <em>event)</em>中,它会迭代所有子绘图部件,并调用每个子对象的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);
}
【问题讨论】:
-
我认为从 UX 的角度来看,使用对象树(“Object Inspector”)使小部件可以选择会更有效和实用,因为您可能会遇到完全覆盖的小部件的情况覆盖。