首页 > 解决方案 > 如何禁用 Qt 按钮标签上的 & 特殊处理?

问题描述

我继承了一个带有一系列按钮的虚拟键盘系统,每个按键一个。每个按钮的标签都是一个QChar. 显示“符号”键盘时,代码使用“&”QChar作为键标签,但键显示为空白。我确定 Qt 正在处理 '&' 作为快捷键前缀。同样,输入的文本显示在另一个更长的按钮标签上;此标签也将“&”字符作为加速键处理。输入“ABC&DEF”显示为“ABCDEF”,“D”下划线。

我曾尝试使用QT_NO_SHORTCUT#defined 进行构建,但这并没有什么区别。

有谁知道禁用这种特殊处理“&”的简单方法?

标签: qtkeyboard-shortcutsacceleratorkey

解决方案


答案在 Qt 文档中找到。QAbstractButton::text

如果文本包含 & 字符 ('&'),则会自动为其创建快捷方式。'&' 后面的字符将用作快捷键。如果文本没有定义快捷方式,任何以前的快捷方式都将被覆盖或清除。有关详细信息,请参阅 QShortcut 文档。要显示实际的 & 符号,请使用 '&&'

(由我强调。)

QPushButton源于QAbstractButton继承此行为。

样品testQPushButtonAmp.cc

#include <QtWidgets>

int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  QPushButton qBtn("Text with &&");
  qBtn.show();
  return app.exec();
}

testQPushButtonAmp.pro

SOURCES = testQPushButtonAmp.cc

QT = widgets

在 Windows 10上的cygwin64上编译和测试:

$ qmake-qt5 testQPushButtonAmp.pro

$ make

$ ./testQPushButtonAmp
Qt Version: 5.9.4

testQPushButtonAmp 的快照


关于如何禁用此默认行为

我看了一下 woboq.org QAbstractButton::setText()

void QAbstractButton::setText(const QString &text)
{
    Q_D(QAbstractButton);
    if (d->text == text)
        return;
    d->text = text;
#ifndef QT_NO_SHORTCUT
    QKeySequence newMnemonic = QKeySequence::mnemonic(text);
    setShortcut(newMnemonic);
#endif
    d->sizeHint = QSize();
    update();
    updateGeometry();
#ifndef QT_NO_ACCESSIBILITY
    QAccessibleEvent event(this, QAccessible::NameChanged);
    QAccessible::updateAccessibility(&event);
#endif
}

因此,QT_NO_SHORTCUT禁止从文本中检索快捷方式,必须在从源代码构建 Qt 库时定义它。实际上,恐怕即使禁用了快捷方式,单曲&仍然会在输出中变得不可见。

我深入挖掘woboq.org并发现了一些有前途的候选人,例如:

qt_set_sequence_auto_menmonic()

指定是否应遵守菜单项、标签等的助记符。在 Windows 和 X11 上,此功能默认开启;在macOS上,它是关闭的。当此功能关闭时(即 b 为 false 时),QKeySequence::mnemonic()总是返回一个空字符串。

注意:这个函数没有在任何 Qt 的头文件中声明。要在您的应用程序中使用它,请在调用之前声明函数原型。

和一个样本QProxyStyle

#include "textedit.h"
#include <QApplication>
#include <QProxyStyle>

class MyProxyStyle : public QProxyStyle
{
  public:
    int styleHint(StyleHint hint, const QStyleOption *option = 0,
                  const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const override
    {
        if (hint == QStyle::SH_UnderlineShortcut)
            return 0;
        return QProxyStyle::styleHint(hint, option, widget, returnData);
    }
};

int main(int argc, char **argv)
{
    Q_INIT_RESOURCE(textedit);

    QApplication a(argc, argv);
    a.setStyle(new MyProxyStyle);
    TextEdit mw;
    mw.resize(700, 800);
    mw.show();
    //...
}

我在我的样本中尝试过。

最后,它们都没有达到预期的效果,即只"&&"渲染为&"&"从未渲染。

__


推荐阅读