将自定义参数传递给 Qt/C++ 中的插槽
Posted
技术标签:
【中文标题】将自定义参数传递给 Qt/C++ 中的插槽【英文标题】:Passing custom arguments to a slot in Qt/C++ 【发布时间】:2015-04-06 14:22:57 【问题描述】:我在尝试将自定义小部件传递到我的 Qt 应用程序中的自定义插槽时遇到了一些麻烦。
这是我需要的示例:(注意插槽)
void MainWindow::HttpRequest(const QString & URL, QCustomWidget *Feed)
manager = new QNetworkAccessManager(this);
reply = manager->get(QNetworkRequest(QUrl(URL)));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(HttpImageError(Feed)));
connect(reply, SIGNAL(finished()), this, SLOT(HttpImageFinished(Feed)));
我已经在 Google 上进行了搜索,发现 QSignalMapper
用于将参数传递给插槽,但 QSignalMapper
仅可用于传递整数、QStrings
、QObjects
和 QWidgets
。我需要传递一个自定义小部件。我还读到有一些技巧可以将自定义小部件包装在结构或类似的东西中,但我对如何做到这一点感到非常困惑。
有人可以帮我吗?
【问题讨论】:
首先您的信号必须与插槽具有相同的签名。因此,如果您希望将对象传递给插槽,则该对象必须来自信号。但是,如果您确实想将 void 信号连接到非 void 插槽,其输入来自上下文,例如this
的成员,也有办法做到这一点。投票结束此问题,因为尚不清楚要问的是哪一个。
你能举个例子吗? ty
请帮帮我,如果你能根据你指出的第一个案例写一个简单的例子,那就太好了! :) 谢谢
您可以将Feed
安全地作为成员变量,将SIGNAL(finished(void))
连接到SLOT(HttpImageFinished(void))
,然后在HttpImageFinished(void)
中调用HttpImageFinished(Feed)
并保存Feed
。将SIGNAL(finished(void))
连接到SLOT(HttpImageFinished(void))
,或将SIGNAL(finished(QCustomWidget *))
连接到SLOT(HttpImageFinished(QCustomWidget *))
。如果签名不匹配,你必须想办法传递信号。
【参考方案1】:
使用 Qt 5 和 C++11,您可以使用新的 lambda 语法:
connect(reply, &QNetworkReply::NetworkError, [this, Feed]()
this->HttpImageError(Feed);
);
这里向 lambda 捕获块添加了插槽函数的附加 Feed
参数。
【讨论】:
第一个错误是什么?如果使用 GCC,则必须使用-std=c++11
选项启用 C++11 语法。
C:\Users\Matteo\Desktop\mainwindow.cpp:116: 错误: 没有匹配函数调用'MainWindow::connect(QNetworkReply*&, const char [36], MainWindow:: HttpRequest(const QString&, bool, QCustomWidget *)::NetworkError
是信号函数,显然它是QNetworkReply 类的字符串。只需在第二个参数中传递一个指向信号函数的指针,在你的情况下它可能是&QNetworkReply::error
。
谢谢 S.T.但是我发现使用队列解决了我的问题! :)
谢谢,最优雅的解决方案。【参考方案2】:
仅供参考... 我找到了解决问题的另一种方法,实际上是传递一个自定义小部件,我继承了 QSignalMapper 类(我还没有在大学学习 OOP,所以请耐心等待我!:P),这里有一些代码:
QCustomMapper.h
#ifndef QCUSTOMMAPPER_H
#define QCUSTOMMAPPER_H
#include <QSignalMapper>
#include <QHash>
#include "customwidget.h"
class QCustomMapper : public QSignalMapper
Q_OBJECT
public:
explicit QCustomMapper(QObject *parent = 0);
void setMapping(QObject *sender, CustomWidget *customWidget);
void removeMappings(QObject *sender);
QHash<QObject *, CustomWidget *> customHash;
Q_SIGNALS:
void mapped(CustomWidget *);
public slots:
void senderDestroyed()
removeMappings(sender());
void map(QObject *sender);
void map();
;
#endif // QCUSTOMMAPPER_H
QCustomMapper.cpp
#include "qcustommapper.h"
QCustomMapper::QCustomMapper(QObject *parent) : QSignalMapper(parent)
void QCustomMapper::setMapping(QObject *sender, CustomWidget *customWidget)
customHash.insert(sender, customWidget);
connect(sender, SIGNAL(destroyed()), this, SLOT(senderDestroyed()));
void QCustomMapper::removeMappings(QObject *sender)
customHash.remove(sender);
void QCustomMapper::map(QObject *sender)
if (customHash.contains(sender))
emit mapped(customHash.value(sender));
void QCustomMapper::map()
map(sender());
注意:我不知道这是否是一种“优雅”的方法,或者子类化是否正确完成..(我在没有正确知识的情况下完成了它)无论如何它对我来说工作正常! (奇迹发生了:D) 我希望这篇文章能帮助遇到同样问题的人!
再见,马特奥。
【讨论】:
以上是关于将自定义参数传递给 Qt/C++ 中的插槽的主要内容,如果未能解决你的问题,请参考以下文章
是否存在某种方式将自定义参数传递给 Firebase 上的短动态链接?
如何将自定义注释中的参数传递给库中的 WebSecurityConfigurer