如何使用 Qt 将可折叠元素(QMenu、QComboBox)渲染到位图缓冲区?
Posted
技术标签:
【中文标题】如何使用 Qt 将可折叠元素(QMenu、QComboBox)渲染到位图缓冲区?【英文标题】:How can collapsible elements (QMenu, QComboBox) be rendered to a bitmap buffer with Qt? 【发布时间】:2017-09-03 16:30:15 【问题描述】:在 Qt 中有多种方法可以将 QWidgets 渲染到位图缓冲区(例如 QImage) 这些方法可以是:
QWidget.render(QPainter, ...)
QWidget.grab()
QPixmap::grabWidget(QWidget)
QPixmap::grabWindow( ID )
有很多可能的变体。但是,它们似乎都没有呈现可折叠元素,例如(子)菜单或组合框。
我还在 Qt 中发现了一个可能与之相关的错误报告 QTBUG-10683(如果这是一个错误)
那么,如何将扩展的 QComboBox 或 QMenu 等元素呈现为 QImage 或任何其他位图形式,如 Byte-Array。它应该适用于渲染不可见的屏幕外内容,因此不能通过操作系统捕获当前桌面。我很高兴收到所有提示,不管是 C++、Python 还是只是解释这里发生的事情的文字。
【问题讨论】:
【参考方案1】:这里的问题是:弹出窗口是独立的窗口。
您可以迭代子窗口并捕获所有子窗口。然后将它们混合成最终图像或只是放入列表中。
要查找小部件是否为独立窗口,您可以使用isWindow 函数。
要捕获隐藏的 UI 元素,您可以使用 qt 元系统:
void captureHiddenItems(QWidget* widget, QList<QImage>& list)
if(auto* comboBox = qobject_cast<QComboBox*>(widget))
comboBox->showPopup();
captureChildWindows(comboBox, list);
comboBox->hidePopup();
else if(auto* menubar = qobject_cast<QMenuBar*>(widget) )
capturePopUpMenus(menubar->actions(), list);
void capturePopUpMenus(QList<QAction*> actions, QList<QImage>& list)
for(auto* action : actions)
if(auto* menu = action->menu())
captureWidget(menu, list);
capturePopUpMenus(menu->actions(), list);
【讨论】:
感谢您到目前为止的帮助 - 知道如何确定子窗口的正确相对渲染位置吗? '父位置加父高度'适用于 QComboBox,但我想在 QMenuBar 子菜单中也有更优雅的工作方式?以上是关于如何使用 Qt 将可折叠元素(QMenu、QComboBox)渲染到位图缓冲区?的主要内容,如果未能解决你的问题,请参考以下文章
Qt 5.4 OS X 如何在 QMenu 和 QToolBar 中使用 QAction,但仅在 QToolbar 中显示图标
如何在 Qt Designer 中删除 QMenu 分隔符?
QPushButton.setMenu (self, QMenu menu) 使用从 Qt Designer 生成的代码