我有一个应用程序,可以在屏幕上交互地移动从QWidget派生的对象。有时,当我将焦点切换到另一个应用程序时,它们会留下先前几何图形的人工痕迹,但直到此时才停留在屏幕上。QWidgets遗留以前绘画的工件
下面是我看的时候重新调整大小的窗口小部件交互文物的一些例子:
我能够创建可自动复制一个类似的问题相当简单的测试案例(尽管只留下一行厚的文物)。在这个例子中,一个单一的垂直线神器一致的几何形状的每个水平“翻转”后留下的:
#include <QApplication>
#include <QDialog>
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include <QWidget>
class TestWidget : public QWidget
{
Q_OBJECT
public:
explicit TestWidget(QWidget *parent = 0);
private:
void paintEvent(QPaintEvent *e);
QRect thisRect();
void timerEvent(QTimerEvent *t);
};
TestWidget::TestWidget(QWidget *parent) :
QWidget(parent)
{
setGeometry(100,100, 100,100);
startTimer(5);
}
QRect TestWidget::thisRect()
{
return QRect(QPoint(),geometry().size());
}
void TestWidget::timerEvent(QTimerEvent *t)
{
QRect geo = geometry();
static bool growUp = false;
static bool flipUp = false;
static bool flipOver = false;
static bool growOver = false;
static int delta = 1;
static int delta2 = 1;
static int tick = 0;
static int enDelta = 1;
tick++;
if(flipUp)
geo.adjust(0,enDelta * delta,0,0);
else
geo.adjust(0,0,0,enDelta * delta);
if(tick%3==0)
enDelta = 0;
else
enDelta = 1;
if(geo.height()>100)
{
if(growUp)
delta = 1;
else
delta = -1;
growUp = !growUp;
}
if(geo.height() == 0)
flipUp = !flipUp;
if(flipOver)
geo.adjust(delta2 ,0, 0,0);
else
geo.adjust(0,0,delta2 ,0);
if(geo.width()>100)
{
if(growOver)
delta2 = 1;
else
delta2 = -1;
growOver = !growOver;
}
if(geo.height() == 0)
flipOver = !flipOver;
setGeometry(geo);
}
void TestWidget::paintEvent(QPaintEvent *e)
{
QBrush b(QColor(55,200,55,190));
QPainter p(this);
p.setBrush(b);
//p.drawRect(QRect(QPoint,this->geometry().size()));
//p.drawRect(QRect(QPoint,geometry().size()));
if(thisRect().width() != 0 && thisRect().height() != 0)
{
p.drawRect(thisRect());
qDebug() << "painted rect is " << thisRect();
qDebug() << "painted geo is " << geometry();
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//MainWindow w;
//w.show();
QDialog d;
d.show();
int i;
TestWidget *tw;
for(i=0; i<1; i++) //2000; i++)
{
tw = new TestWidget(&d);
tw->show();
}
return a.exec();
}
是否有某种同步我丢失或者这是一个错误的? (我开始研究事件队列和后备存储算法,但是当我将测试应用程序的焦点从Qt Creator转移到Qt Creator时,我可以单步执行,但是这些工件会消失,这使得跟踪起来有点棘手,事实上,它是双缓冲使得它更难看到什么时候项呈现给暂存缓冲器,由于存在,因为它发生没有视觉反馈)
添加添加后:
update();
(并在下面的评论中提到),有显着的改进,但其他方面相同的代码,仍然产生了一个工件,在红色箭头指向的红色圆圈中显示:
如果你尝试调用'更新()'后这一行:'setGeometry(geo);'? – vahancho 2014-11-21 10:09:01
这绝对有帮助。谢谢。我仍然有一个小神器。我添加了上面剩下的神器的图片。 – user3761340 2014-11-21 22:13:52
我找到了解决方案。解决方案是在更改子几何之后更新()parentWidget。 (这对我来说很有意义,因为孩子的几何是相对于parentWidget,而不是孩子本身。我现在认为这很可能不是一个bug,但是如果有一个很好的参考很容易更好地理解渲染内部可用或甚至几句智慧。) – user3761340 2014-11-21 23:55:31