2011-02-07 22 views
11

我正在做一個小聊天信使程序,它需要用戶加入的聊天頻道列表。爲了用圖形表示這個列表,我列出了QPushButtons的列表,這些列表代表了不同的頻道。這些按鈕與以下的方法進行,而這也正是我的問題踢:(activePanelContents是保存列表一個QWidget)如何將變量傳遞給QT中的插槽方法?

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

的一點是,每個按鈕應該調用switchTab(string& tabname)方法當點擊時,包括特定頻道的名稱作爲變量。這個實現雖然不起作用,但我一直無法找到如何正確地做到這一點。

回答

0

您可以嘗試使switchTab插槽不採用參數,並使用QObject::sender來獲取發送信號的對象。

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

注意的警告使用的QObject ::發件人之前在您的代碼 – 2011-02-08 00:01:58

+0

不知道爲什麼您的帖子被濫用,但無論如何感謝。你幫了很多 – parsecer 2016-04-23 16:27:19

1

除非絕對必須,否則不要使用發件人方法。它將函數直接綁定爲僅用作插槽(不能直接調用)。保留讓函數接受字符串的行爲,並簡單地創建一個可以調用它的機制。

其中一種方法,你可能會發現,是利用QSignalMapper的使用。它會將對象映射到值並重新生成相應簽名的信號。

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

它沒有測試,但你得到了一個基本的想法。

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 &))); 
+0

這似乎沒有工作... switchTab()根本不會被調用,儘管沒有任何錯誤在任何地方給出。 – Neko 2011-02-09 21:51:10

3

使用QSignalMapper到傳遞變量;

 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。Ë

void class::buttonClicked(QString data){ 

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

} 

希望我的ANS可以幫助你

0

如果你使用QT5,您可以通過拉姆達做到這一點:

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

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