开发者

How to pass variables to slot methods in QT?

开发者 https://www.devze.com 2023-02-08 22:47 出处:网络
I\'m making a little chat messenger program, which needs a list of chat channels the user has joined. To represent this list graphically, I have made a list of QPushButtons, which all represent a diff

I'm making a little chat messenger program, which needs a list of chat channels the user has joined. To represent this list graphically, I have made a list of QPushButtons, which all represent a different channel. These buttons are made with the following method, and that's where my problem kicks in:

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 is a QWidget that holds the list.)

The point is that each button should call the switchTab(string& tabname) method when clicked, including the specific channel's name as开发者_StackOverflow中文版 variable. This implementation doesn't work though, and I haven't been able to find out how to properly do this.


For strings and integers, you can use QSignalMapper. In your Messenger class, you would add a QSignalMapper mapper object, and your function would look like:

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()));
}

and after you have added all channels to your active panels, you call

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


Use QSignalMapper to pass variables;

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


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

in slot i.e

void class::buttonClicked(QString data){

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

}

Hope my ans may help you


Don't use the sender method unless you absolutely have to. It ties the function directly to being used only as a slot (can't be called directly). Retain the behavior of having the function accept a string and simply make a mechanism by which you can call it.

One method, among others you might find, is to leverage use of QSignalMapper. It will map objects to values and regenerate signals of the appropriate signature.


I would do it with "relay" objects:

Create TabSwitchRelay which is a sub-class of QObject with this constructor:

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

It also has a slot clicked():

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

Now replace the line in your code that does connect with this:

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

It's not tested but you get teh basic idea.


You could try having your switchTab slot take no argument and use QObject::sender to get the object that sent the signal.

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


if you're using Qt5, you can do it through lambda:

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

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

精彩评论

暂无评论...
验证码 换一张
取 消