C++ 如何在更改QWidgetAction显示的QLabel后调整其大小';s文本

C++ 如何在更改QWidgetAction显示的QLabel后调整其大小';s文本,c++,qt,qmenu,C++,Qt,Qmenu,我使用QWidgetAction将标题添加到上下文菜单中(无论使用何种样式,它都会显示在Windows上,而addSection()并不总是实际显示标题) 操作的小部件是一个QLabel。每次调用上下文菜单都会更改它的文本。菜单是在我的类的构造函数中设置的,并且像这样添加了QWidgetAction(所有m变量都是在标题中声明的成员变量): 当请求菜单时,标签文本将更改,菜单显示如下: m_menuTitle->setText(tr("%1 „%2“").arg(some_variable

我使用
QWidgetAction
将标题添加到上下文菜单中(无论使用何种样式,它都会显示在Windows上,而
addSection()
并不总是实际显示标题)

操作的小部件是一个
QLabel
。每次调用上下文菜单都会更改它的文本。菜单是在我的类的构造函数中设置的,并且像这样添加了
QWidgetAction
(所有
m
变量都是在标题中声明的成员变量):

当请求菜单时,标签文本将更改,菜单显示如下:

m_menuTitle->setText(tr("%1 „%2“").arg(some_variable, some_other_variable));
...
m_contextMenu->exec(place_to_display);
首次设置标签文本时(标签文本设置为短文本),一切正常:

但当设置为较长的文本时,大小保持不变,文本将被裁剪:

我试图解决这个问题,但我找到的唯一有效解决方案是定义构造函数中菜单中显示的
QAction
s,它归
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()
调整大小

这个答案扩展了

如果更改隐藏小部件操作的大小(例如,由于其菜单当前已折叠),则不需要多做多少工作。 创建一个新类
ActionWidget
,该类从
QWidget
公开派生。 然后重写
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
,以便它返回
ActionWidget
-类的一个实例,并确保
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没有大小。你需要改写这个问题吗?我希望看到更多的代码。我添加了菜单设置和菜单调用的代码。这是关于QLabel的宽度QWidgetAction显示和QLabel的文本第一次设置后保持不变的QMenu的宽度。答案可能是在黑暗中拍摄,但类似的解决方案曾经对我有效。可能是你需要的。不,这是我尝试的第一件事…就是这样!谢谢:-)这对我没用。请您解释一下这种黑客与
QWidget::adjustSize
QWidget::updateGeometry
有什么不同?在我的例子中,菜单位于
QMenuBar
中,并且在调整大小时隐藏。我觉得答案不是很清楚,但我认为这不应该是个问题。
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);
    }
    ...
}