在 X 上拖动的对象下方缓慢重绘... Qt 可以强制拖放操作仅在内部进行吗?

Posted

技术标签:

【中文标题】在 X 上拖动的对象下方缓慢重绘... Qt 可以强制拖放操作仅在内部进行吗?【英文标题】:Slow repaint underneath dragged object on X... Can Qt force drag and drop operations to be internal only? 【发布时间】:2011-11-26 23:07:16 【问题描述】:

我正在跨 WindowsX 实现 Qt 的拖放 API。当我在 X 上运行的应用程序中拾取一个对象并拖动它时,它会在下面的窗口上留下一条白色的幽灵轨迹,好像下面的窗口在重新绘制拖动对象的位置时速度很慢以前会掩盖自身的一部分。

我相信这是 Qt 刚刚用 resizing windows causing flicker in child widgets on X windows 解决的相同问题的症状 - 即被拖动的对象被视为一个单独的本机窗口,因此 X 处理从被拖动对象到下面窗口的剪辑。 因为 X 以与 Qt,我们得到了重影效果。

有没有人遇到过同样的问题?想到的一种解决方案是使用上面链接的博客文章中详述的相同技术,并停止将拖动的对象视为本机窗口,大概以拖放仅限于我的应用程序为代价(我没有这个问题)。有谁知道如何强制拖放操作仅在内部进行?


编辑:我正在使用QDrag::setPixmap 设置被拖动对象的图形表示 - 重要的是我保留它以支持标准拖动光标,因为正在使用此界面触摸屏设备,因此没有可见的光标。

【问题讨论】:

问得好,抱歉我帮不上忙。不过,令人震惊的一件事是,您的实际问题出现在帖子的最后一行。尝试将标题表达为您的问题,然后再解释情况。可能有助于让合适的人看看你的问题。干杯! 干杯@Robin,听从了你的建议:) 【参考方案1】:

我现在认为,如果没有编辑然后编译我自己的 Qt 版本(对我来说不是一个选项),我不能强制拖放操作仅限于内部。

同样,我无法通过调整我的窗口管理器设置或使用合成窗口管理器(无论如何感谢@atomice)来摆脱幽灵踪迹。使用 OpenGL 作为渲染器会略微提高屏幕重绘速度,但并不完美,并且会引入其自身的问题(请参阅Starting a Qt drag operation on X11 w/ OpenGL causes screen flicker)。不过,我仍然很想听听任何想法。

不过,对于我的问题,我有一个解决方法,它适用于 Windows 和 X。这是一个简化版本:

void DoDrag()

  //Prepare the graphical representation of the drag
  mDragRepresenter = new QWidget(QApplication::activeWindow());
  mDragRepresenter->setAttribute(Qt::WA_TransparentForMouseEvents);
  mDragRepresenter->SetPixmap(GenerateDragPixmap());

  RepositionDragRepresenter();
  mDragRepresenter->show();

  QTimer UpdateTimer;
  connect(&UpdateTimer, SIGNAL(timeout()), this, SLOT(RepositionDragRepresenter()));
  UpdateTimer.start(40);

  //Start the drag (modal operation)
  Qt::DropAction ResultingAction = Drag->exec(Qt::CopyAction);

  UpdateTimer.stop();
  delete mDragRepresenter;


void RepositionDragRepresenter()

  mDragRepresenter->move(QApplication::activeWindow()->mapFromGlobal(QCursor::pos()) - mDragRepresenterHotSpot);

【讨论】:

【参考方案2】:

只有当 QDrag::mimeData()->hasImage() 为真时,才会为拖动操作创建 X11 窗口。如果您修改代码使其不使用图像,那么您只会得到一个拖动光标,而不会触发下方窗口的重绘。

您不指定要拖动的对象类型或设置拖动操作的方式。你能添加一些代码来显示吗?

【讨论】:

此界面将在没有光标的触摸屏上使用,因此恐怕需要图像。老实说,该对象无关紧要-我正在以标准方式设置阻力(即new关闭它,设置mimeDatapixmaphotSpot然后调用QDrag::exec())。不过,我没想过尝试setCursor 而不是setPixmap - 我明天就试试。干杯:) 如果这是用于信息亭或设备(而不是通用应用程序),如果硬件支持,您可以尝试使用合成窗口管理器。

以上是关于在 X 上拖动的对象下方缓慢重绘... Qt 可以强制拖放操作仅在内部进行吗?的主要内容,如果未能解决你的问题,请参考以下文章

Flex Spark TitleWindow 在拖动时重绘错误

SVG:拖动矩形仅在缓慢拖动时有效

如何沿固定路径拖动项目? [在 Qt 图形视图中]

qml 中是不是可以重绘 Canvas 对象的内容?

在拖动块时重绘控制流线

android涂鸦工具,笔刷的定义,撤销与重绘