【问题标题】:QSystemTrayIcon notification message with custom icon带有自定义图标的 QSystemTrayIcon 通知消息
【发布时间】:2015-06-25 08:45:42
【问题描述】:

QSystemTrayIcon 有一个功能:

void showMessage(const QString &title, const QString &msg,
                     MessageIcon icon = Information, int msecs = 10000);

有没有办法将其更改为自定义图标,例如这样 -

void showIconMessage(const QString &title, const QString &msg,
                     QIcon icon = QIcon(), int msecs = 10000);

不修改 Qt 源代码

我知道showMessage(d 是 QSystemTrayIconPrivate 的实例,并使用 Q_D(QSystemTrayIcon) 宏调用)

void QSystemTrayIcon::showMessage(const QString& title, const QString& msg,
                            QSystemTrayIcon::MessageIcon icon, int msecs)
{
    Q_D(QSystemTrayIcon);
    if (d->visible)
        d->showMessage_sys(title, msg, icon, msecs);
}

QSystemTrayIconPrivate 调用showMessage_sys,然后所有带有图标的魔法都会发生:

void QSystemTrayIconPrivate::showMessage_sys(const QString &message,
                                             const QString &title,
                                             QSystemTrayIcon::MessageIcon icon,
                                             int msecs)
{
    if (!qpa_sys)
        return;

    QIcon notificationIcon;
    switch (icon) {
    case QSystemTrayIcon::Information:
        notificationIcon = QApplication::style()-   >standardIcon(QStyle::SP_MessageBoxInformation);
        break;
    case QSystemTrayIcon::Warning:
        notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
        break;
    case QSystemTrayIcon::Critical:
        notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
        break;
    default:
        break;
    }
    qpa_sys->showMessage(message, title, notificationIcon,
                     static_cast<QPlatformSystemTrayIcon::MessageIcon>(icon), msecs);
}

现在看来,我需要在两个类中重新实现这两个函数,我准备好了,但是.. 似乎 QSystemTrayIcon 与 QSystemTrayIconPrivate 密切相关。 QSystemTrayIconPrivate 的实例仅在 QSystemTrayIcon 构造函数中创建(如果我打算创建继承 QSystemTrayIcon 和 QSystemTrayIconPrivate 的类并重新实现 showMessage 函数,我无法真正更改):

QSystemTrayIcon::QSystemTrayIcon(QObject *parent)
: QObject(*new QSystemTrayIconPrivate(), parent)
{
}

QSystemTrayIcon::QSystemTrayIcon(const QIcon &icon, QObject *parent)
: QObject(*new QSystemTrayIconPrivate(), parent)
{
    setIcon(icon);
}

那么我有什么遗漏吗?还是有其他方法可以简单地显示带有自定义图标的通知消息?

【问题讨论】:

标签: qt qt5 system-tray


【解决方案1】:

您可以尝试的方法(不确定它是否适用于系统托盘)与this 答案中描述的相同,并覆盖SP_MessageBoxWarning / SP_MessageBoxCritical / SP_MessageBoxInformation 图标,但正如我所说我'不确定系统托盘是否仅使用消息框图标的缩小版本,或者系统托盘图标是否是单独的。在后者的情况下,我想你将不得不修补 QT 源,也许在QSystemTrayIcon 中添加一个新项目并修补开关以调用你提供的某些函数以返回所需的图标。比如:

void QSystemTrayIconPrivate::showMessage_sys(const QString &message,
                                             const QString &title,
                                             QSystemTrayIcon::MessageIcon icon,
                                             int msecs)
{
    if (!qpa_sys)
        return;

    QIcon notificationIcon;
    switch (icon) {
    case QSystemTrayIcon::Information:
        notificationIcon = QApplication::style()-   >standardIcon(QStyle::SP_MessageBoxInformation);
        break;
    case QSystemTrayIcon::Warning:
        notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
        break;
    case QSystemTrayIcon::Critical:
        notificationIcon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
        break;
    case QSystemTrayIcon::Custom:
        // Call a function that will fetch the needed icon and assign it to notificationIcon
        break;
    default:
        break;
    }
    qpa_sys->showMessage(message, title, notificationIcon,
                     static_cast<QPlatformSystemTrayIcon::MessageIcon>(icon), msecs);
}

【讨论】:

  • 感谢您的回答,但我了解我必须更改哪些内容才能使用自定义 QIcon 进行功能。整个问题是 - 如何在不改变 Qt 来源的情况下制作它。现在我正在考虑继承 QSystemTrayIcon (例如 MyTrayIcon )并完全重新实现 QSystemTrayIconPrivate (例如使用 MyTrayIconPrivate 制作它的副本)并尝试使它们以某种方式在两个类中使用新的额外功能。但我正在与 Q_D 和所有 Qt 的 D 指针系统作斗争 - wiki.qt.io/D-Pointer
  • @Shf 你检查到另一个问题的链接了吗?如果这有效,您不必修补源。唯一的问题是覆盖的图标是否与用于系统托盘的图标相同。
  • 谢谢,我想,这正是我所需要的。马上试试这个
  • 尝试使用 QProxyStyle 方法,并设置为 SP_MessageBoxInformation ,但控制从未到达 standardIcon QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = 0, const QWidget *widget = 0) const { // control never gets this far if (standardIcon == QStyle::SP_MessageBoxInformation) { return QIcon("myicon"); } }
  • @Shf 您是否将样式应用于您的小部件,如答案所示?如果是这样,那么我猜 QT 遗憾地只是不允许自定义该图标。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 2020-02-03
  • 2014-02-04
  • 2016-09-16
  • 2016-03-03
相关资源
最近更新 更多