如何在QT中将变量传递给槽方法?

时间:2011-02-07 23:20:52

标签: c++ qt signals-slots

我正在制作一个聊天信使程序,需要用户加入的聊天频道列表。为了以图形方式表示此列表,我列出了QPushButtons,它们都代表不同的渠道。这些按钮是用以下方法制作的,这就是我的问题所在:

void Messenger::addToActivePanels(std::string& channel)
{
    activePanelsContents = this->findChild<QWidget *>(QString("activePanelsContents"));
    pushButton = new QPushButton(activePanelsContents);
    pushButton->setObjectName("pushButton");
    pushButton->setGeometry(QRect(0, 0, 60, 60));
    pushButton->setText("");
    pushButton->setToolTip(QString(channel.c_str()));
    pushButton->setCheckable(true);
    pushButton->setChecked(false);
    connect(pushButton, SIGNAL(clicked()), this, SLOT(switchTab(channel)));
}

(activePanelContents是一个保存列表的QWidget。)

关键是每个按钮在单击时应调用switchTab(string& tabname)方法,包括特定通道的名称作为变量。这个实现虽然不起作用,但我还是找不到如何正确地做到这一点。

6 个答案:

答案 0 :(得分:7)

对于字符串和整数,您可以使用QSignalMapper。在Messenger课程中,您将添加QSignalMapper mapper对象,您的函数将如下所示:

void Messenger::addToActivePanels(std::string& channel)
{
    activePanelsContents = this->findChild<QWidget *>(QString("activePanelsContents"));
    pushButton = new QPushButton(activePanelsContents);
    // ...
    connect(pushButton, SIGNAL(clicked()), &mapper, SLOT(map()));
    mapper.setMapping(pushButton, QString(channel.c_str()));
}

将所有频道添加到活动面板后,请致电

connect(&mapper, SIGNAL(mapped(const QString &)), this, SLOT(switchTab(const QString &)));

答案 1 :(得分:3)

使用QSignalMapper传递变量;

        QSignalMapper* signalMapper = new QSignalMapper (this) ;
        QPushButton *button = new QPushButton();


         signalMapper -> setMapping (button, <data>) ;
         connect (signalMapper, SIGNAL(mapped(QString)), this,   
                   SLOT(buttonClicked(QString))) ;
在插槽中

void class::buttonClicked(QString data){

    //use data
    // to get sender 
    QSignalMapper *temp = (QSignalMapper *)this->sender();
    QPushButton *btn = (QPushButton *)temp->mapping(data);
    // use btn

}

希望我的回答可以帮助你

答案 2 :(得分:1)

除非绝对必须,否则请勿使用发送方法。它将函数直接绑定到仅用作插槽(不能直接调用)。保留让函数接受字符串的行为,并简单地建立一个可以调用它的机制。

您可能会发现一种方法是利用QSignalMapper。它会将对象映射到值并重新生成相应签名的信号。

答案 3 :(得分:1)

我会用“继电器”对象来做:

使用此构造函数创建TabSwitchRelay QObject的子类:

TabSwitchRelay::TabSwitchRelay(QObject *parent, Messanger * m, const QString & c)
: QObject(parent), m_messanger(m), m_channel(c)
{
}

它还有一个广告位clicked()

void TabSwitchRelay::clicked()
{
    m_messager->switchTab(m_channel);
}

现在替换代码中与此相关的行:

TabSwitchRelay * tabRelay = new TabSwitchRelay(pushButton, this, channel);
connect(pushButton, SIGNAL(clicked()), tabRelay, SLOT(clicked()));

它没有经过测试,但你得到了基本的想法。

答案 4 :(得分:0)

您可以尝试让switchTab广告位不参数,并使用QObject::sender获取发送信号的对象。

Messenger::switchTab()
{
  QObject* sender = this->sender();
  QPushButton* button = qobject_cast<QPushButton*>(sender);
  if(button)
  {
    // Do stuff...
  }
}

答案 5 :(得分:0)

如果你正在使用Qt5,你可以通过lambda:

来完成
connect( sender, &Sender::valueChanged,  [=](){ myMethod(5); } );

void myMethod(int value)
{
  // do stuff
}