在 QToolBar 的工具提示中显示快捷方式

Show shortcut in tooltip of QToolBar

我使用 addAction()QActions 添加到 QToolBar

我希望工具栏按钮工具提示显示快捷方式。例如复制 (Ctrl+C)。 当然,我可以静态设置

action->setTooltip(QString("%1 (%2)").arg(action.toolTip(), action->shortcut().toString(QKeySequence::NativeText)));

然而,这非常麻烦,因为有很多操作,用户可以修改快捷方式,因此我必须跟踪并相应地更新。如果我可以通过子类化 QToolBar 类似于 http://doc.qt.io/qt-5/qtwidgets-widgets-tooltips-example.html.

来简单地修改 QToolBar 工具提示行为,那就更好了

不幸的是,事情并没有那么简单。工具提示不是由 QToolBar 本身生成的,而显然是由使用 addAction() 时在内部创建的 QToolButton 生成的。所以理想情况下,我会注入我自己的 QToolButton 子类。但这似乎是不可能的,因为工具按钮的实际实例化是在我无法访问的私有 QToolBarLayout 中完成的。

有什么解决办法吗?

我无法通过子类化 QToolBar 或任何相关内容找到解决方案。因此,我采用了覆盖 QAction 的工具提示。这是最终的样子:

我已经为 add/remove 快捷方式信息编写了函数,因此更改是可逆的(例如,如果行为应该是可切换的,则需要)。如果不需要删除,addShortcutToToolTip()可以简化一点。

/* guesses a descriptive text from a text suited for a menu entry
   This is equivalent to QActions internal qt_strippedText()
*/
static QString strippedActionText(QString s) {
    s.remove( QString::fromLatin1("...") );
    for (int i = 0; i < s.size(); ++i) {
        if (s.at(i) == QLatin1Char('&'))
        s.remove(i, 1);
    }
    return s.trimmed();
}


/* Adds possible shortcut information to the tooltip of the action.
   This provides consistent behavior both with default and custom tooltips
   when used in combination with removeShortcutToToolTip()
*/
void addShortcutToToolTip(QAction *action)
{
    if (!action->shortcut().isEmpty()) {
        QString tooltip = action->property("tooltipBackup").toString();
        if (tooltip.isEmpty()) {
            tooltip = action->toolTip();
            if (tooltip != strippedActionText(action->text())) {
                action->setProperty("tooltipBackup", action->toolTip());  // action uses a custom tooltip. Backup so that we can restore it later.
            }
        }
        QColor shortcutTextColor = QApplication::palette().color(QPalette::ToolTipText);
        QString shortCutTextColorName;
        if (shortcutTextColor.value() == 0) {
            shortCutTextColorName = "gray";  // special handling for black because lighter() does not work there [QTBUG-9343].
        } else {
            int factor = (shortcutTextColor.value() < 128) ? 150 : 50;
            shortCutTextColorName = shortcutTextColor.lighter(factor).name();
        }
        action->setToolTip(QString("<p style='white-space:pre'>%1&nbsp;&nbsp;<code style='color:%2; font-size:small'>%3</code></p>")
                           .arg(tooltip, shortCutTextColorName, action->shortcut().toString(QKeySequence::NativeText)));
    }
}


/* Removes possible shortcut information from the tooltip of the action.
   This provides consistent behavior both with default and custom tooltips
   when used in combination with addShortcutToToolTip()
*/
void removeShortcutFromToolTip(QAction *action)
{
    action->setToolTip(action->property("tooltipBackup").toString());
    action->setProperty("tooltipBackup", QVariant());
}