3

I have QActions added to a QToolBar using addAction().

I want the toolbar button tooltips to show the shortcuts. e.g. Copy (Ctrl+C). Of course, i could statically set

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

However, this is quite cumbersome because there are lots of actions and the user can modify the shortcuts so that I would have to keep track of that and update accordingly. It would be much nicer if I could simply modify the QToolBar tooltip behavior by subclassing QToolBar similar to http://doc.qt.io/qt-5/qtwidgets-widgets-tooltips-example.html.

Unfortunately, it's not that simple. The tooltip is not generated by the QToolBar itself, but apparently by a QToolButton which is created internally when using addAction(). So ideally I would inject my own subclass of QToolButton. But that seems imposible because the actual instantiation of the toolbutton is done inside the private QToolBarLayout which I cannot access.

Any ideas how to solve this?

4

1 回答 1

4

我无法通过子类化QToolBar或任何相关的方法找到解决方案。因此,我采取了覆盖QAction. 这就是它最终的样子:

例子

我编写了添加/删除快捷方式信息的函数,以便更改是可逆的(例如,如果行为应该是可切换的,则需要)。如果不需要移除,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());
}
于 2017-03-05T13:57:05.237 回答