如何在更改文本后调整 QWidgetAction 显示的 QLabel 的大小
How to resize a QLabel displayed by a QWidgetAction after changing it's text
我使用 QWidgetAction
将 header 添加到上下文菜单(这也会显示在 Windows 上,无论使用什么样式,与 addSection()
,实际上并不总是显示标题)。
该操作的小部件是 QLabel
。每次调用上下文菜单都会更改其文本。菜单是在我的 class 的构造函数中设置的,QWidgetAction
是这样添加的(所有 m_
变量都是在 header 中声明的成员变量):
m_contextMenu = new QMenu(this);
m_menuTitle = new QLabel;
m_menuTitle->setAlignment(Qt::AlignCenter);
m_menuTitle->setMargin(4);
QWidgetAction *titleAction = new QWidgetAction(m_contextMenu);
titleAction->setDefaultWidget(m_menuTitle);
m_contextMenu->addAction(titleAction);
m_contextMenu->addSeparator();
当菜单被请求时,标签的文本被改变,菜单显示如下:
m_menuTitle->setText(tr("%1 „%2“").arg(some_variable, some_other_variable));
...
m_contextMenu->exec(place_to_display);
第一次设置标签文本时(标签文本设置为短文本),一切正常:
但是当它设置为一些更长的文本时,大小保持不变并且文本被裁剪:
我试图解决这个问题,但我找到的唯一可行的解决方案是定义 QAction
在构造函数的菜单中显示,由 this
拥有,设置标签的文本,清除菜单并再次添加操作,如下所示:
m_contextMenu->clear();
m_menuTitle->setText(tr("%1 „%2“").arg(some_variable, some_other_variable));
m_contextMenu->addAction(m_menuTitleAction);
m_contextMenu->addSeparator();
m_contextMenu->addAction(m_editAction);
m_contextMenu->addAction(m_deleteAction);
m_contextMenu->exec(place_to_display);
有没有办法在每次不重建菜单的情况下调整标题的大小?
解决方案是改为发送调整大小事件:
m_menuTitle->setText(tr("%1 „%2“").arg(some_variable, some_other_variable));
...
QResizeEvent re(new_size, m_contextMenu->size());
qApp->sendEvent(m_contextMenu, &re);
这将设置 QMenu 的内部 itemsDirty
标志,并在显示菜单时强制重新计算几何图形。 请注意,事件中的新大小并不重要,因为菜单会根据其 sizeHint()
!
调整大小
此答案扩展了 。
如果您更改隐藏的小部件操作的大小(例如,因为它的菜单当前已折叠),几乎不需要付出更多的努力。
创建一个公开派生自 QWidget
的新 class ActionWidget
。
然后覆盖 showEvent
方法并像这样实现它:
void ActionWidget::showEvent(QShowEvent* event)
{
QResizeEvent resize_event(QSize(), parentWidget()->size());
parentWidget()->adjustSize();
qApp->sendEvent(parentWidget(), &resize_event);
QWidget::showEvent(event);
}
请注意,必须在操作小部件的父小部件上调用 adjustSize
,并且必须将事件发送到父小部件。
当然,您还必须重新实现 QWidgetAction::createWidget
,使其 returns 成为 ActionWidget
-class 的一个实例,并确保 ActionWidget
报告适当的(更新的)尺寸提示。
QResizeEvent
解决方案对我来说并不适用(使用更复杂的小部件),我通过阅读 QMenu
和 QAction
源代码找到了通用解决方案。
m_widget->installEventFilter(this);
// and in my case m_widget->layout()->setSizeConstraint(QLayout::SetFixedSize);
bool SomeClass::eventFilter(QObject* watched, QEvent* event)
{
if (watched == m_widget && event->type() == QEvent::Resize) {
// Force QMenu to recalculate the geometry of this item
QActionEvent e(QEvent::ActionChanged, this);
qApp->sendEvent(m_contextMenu, &e);
}
...
}
QActionEvent
触发我们在 QMenu
中需要的一切:重新计算几何图形、将菜单调整为新大小(如果可见)等。
我使用 QWidgetAction
将 header 添加到上下文菜单(这也会显示在 Windows 上,无论使用什么样式,与 addSection()
,实际上并不总是显示标题)。
该操作的小部件是 QLabel
。每次调用上下文菜单都会更改其文本。菜单是在我的 class 的构造函数中设置的,QWidgetAction
是这样添加的(所有 m_
变量都是在 header 中声明的成员变量):
m_contextMenu = new QMenu(this);
m_menuTitle = new QLabel;
m_menuTitle->setAlignment(Qt::AlignCenter);
m_menuTitle->setMargin(4);
QWidgetAction *titleAction = new QWidgetAction(m_contextMenu);
titleAction->setDefaultWidget(m_menuTitle);
m_contextMenu->addAction(titleAction);
m_contextMenu->addSeparator();
当菜单被请求时,标签的文本被改变,菜单显示如下:
m_menuTitle->setText(tr("%1 „%2“").arg(some_variable, some_other_variable));
...
m_contextMenu->exec(place_to_display);
第一次设置标签文本时(标签文本设置为短文本),一切正常:
但是当它设置为一些更长的文本时,大小保持不变并且文本被裁剪:
我试图解决这个问题,但我找到的唯一可行的解决方案是定义 QAction
在构造函数的菜单中显示,由 this
拥有,设置标签的文本,清除菜单并再次添加操作,如下所示:
m_contextMenu->clear();
m_menuTitle->setText(tr("%1 „%2“").arg(some_variable, some_other_variable));
m_contextMenu->addAction(m_menuTitleAction);
m_contextMenu->addSeparator();
m_contextMenu->addAction(m_editAction);
m_contextMenu->addAction(m_deleteAction);
m_contextMenu->exec(place_to_display);
有没有办法在每次不重建菜单的情况下调整标题的大小?
解决方案是改为发送调整大小事件:
m_menuTitle->setText(tr("%1 „%2“").arg(some_variable, some_other_variable));
...
QResizeEvent re(new_size, m_contextMenu->size());
qApp->sendEvent(m_contextMenu, &re);
这将设置 QMenu 的内部 itemsDirty
标志,并在显示菜单时强制重新计算几何图形。 请注意,事件中的新大小并不重要,因为菜单会根据其 sizeHint()
!
此答案扩展了
如果您更改隐藏的小部件操作的大小(例如,因为它的菜单当前已折叠),几乎不需要付出更多的努力。
创建一个公开派生自 QWidget
的新 class ActionWidget
。
然后覆盖 showEvent
方法并像这样实现它:
void ActionWidget::showEvent(QShowEvent* event)
{
QResizeEvent resize_event(QSize(), parentWidget()->size());
parentWidget()->adjustSize();
qApp->sendEvent(parentWidget(), &resize_event);
QWidget::showEvent(event);
}
请注意,必须在操作小部件的父小部件上调用 adjustSize
,并且必须将事件发送到父小部件。
当然,您还必须重新实现 QWidgetAction::createWidget
,使其 returns 成为 ActionWidget
-class 的一个实例,并确保 ActionWidget
报告适当的(更新的)尺寸提示。
QResizeEvent
解决方案对我来说并不适用(使用更复杂的小部件),我通过阅读 QMenu
和 QAction
源代码找到了通用解决方案。
m_widget->installEventFilter(this);
// and in my case m_widget->layout()->setSizeConstraint(QLayout::SetFixedSize);
bool SomeClass::eventFilter(QObject* watched, QEvent* event)
{
if (watched == m_widget && event->type() == QEvent::Resize) {
// Force QMenu to recalculate the geometry of this item
QActionEvent e(QEvent::ActionChanged, this);
qApp->sendEvent(m_contextMenu, &e);
}
...
}
QActionEvent
触发我们在 QMenu
中需要的一切:重新计算几何图形、将菜单调整为新大小(如果可见)等。