【问题标题】:How connect a signal from C++ to QML function with parameter如何使用参数将信号从 C++ 连接到 QML 函数
【发布时间】:2016-04-29 11:48:55
【问题描述】:

我想将由 C++ QObject 创建的信号连接到 QML 项中的函数。该信号是来自 QSystemTrayIcon 的“激活”信号,它的参数是 ActivationReason(一个枚举值)。

不幸的是,我似乎无法将具有此签名的信号连接到似乎只能接收 QVariant 的插槽。

在 QML 文件中

function trayIconClicked(reason) { ... }

在 C++ 代码中

QObject::connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), rootObject, SLOT(trayIconClicked(QVariant)));

这就是我得到的

QObject::connect: Incompatible sender/receiver arguments
        QSystemTrayIcon::activated(QSystemTrayIcon::ActivationReason) --> ApplicationWindow_QMLTYPE_11_QML_60::trayIconClicked(QVariant)

如果我完全放弃槽端的参数,事件会调用函数。但后来我不知道是什么 ActivationReason 触发了它。

上面代码的完整工作版本在这里,除了我不能交原因参数https://github.com/sturmf/qt_samples/tree/master/trayicon

【问题讨论】:

  • 不幸的是,我以前读过这个答案。他很幸运,信号和插槽都可以更改为QVariant。我有来自 QSystemTrayIcon 的固定参数。我也知道可以用于翻译的中间槽。但是我的代码存在于 C++ 代码的 main 函数中,我没有可以作为中间体工作的 QObject。
  • @Fabian - QML-C++ 互操作需要转换为QVariant,您可以将自定义类型注册为元类型,以便它可以被变体包装,以便可以传递给QML 方面。
  • @ddriver 嗯,我的问题是 ActivationReason 不是自定义类型,我无法在 main.cpp 中注册它,至少我得到编译错误请使用 Q_DECLARE_METATYPE。而且我不能在 QObject 之外使用 Q_DECLARE_METATYPE。
  • ...您不能只实现一个蹦床插槽来执行包装并将信号作为 QVariant 重新发射吗?

标签: c++ qt qml


【解决方案1】:

我现在将 QSystemTrayicon 子类化并添加了一个插槽,该插槽在没有参数的情况下发出另一个信号。

#ifndef TRAYICON_H
#define TRAYICON_H
#include <iostream>
#include <QObject>
#include <QSystemTrayIcon>

class TrayIcon : public QSystemTrayIcon
{
    Q_OBJECT
public:
    explicit TrayIcon(QObject *parent = 0) : QSystemTrayIcon(parent){}

signals:
    void triggered();

public slots:
    void trayIconActivated(QSystemTrayIcon::ActivationReason reason) {
        std::cout << "activated" << std::endl;
        if (reason == QSystemTrayIcon::Trigger) {
            std::cout << "tiggered" << std::endl;
            emit triggered();
        }
    }
};

#endif // TRAYICON_H

【讨论】:

    【解决方案2】:

    顺便说一句,在 Qt5 中,您可以连接到匿名函数。

    QObject::connect(trayIcon
        , SIGNAL(activated(QSystemTrayIcon::ActivationReason))
        , [=](QSystemTrayIcon::ActivationReason r){
                  rootObject->trayIconClicked(r);
              });
    

    【讨论】:

    • 如何在rootObject中发出任意信号?
    • 你的意思是如何从rootObject的方法内部发出来自对象的任意信号?您可以将 rootObject 的信号连接到该信号并发出后者。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多