2015-10-16 25 views
0

兩天了,我一直在試圖理解爲什麼不同的插槽被我的應用程序上的同一個按鈕調用。我GOOGLE了很多有關的問題,但主要是什麼I found是關於一個獨特的SLOT被稱爲通過解決在連接調用 即增加第五個參數Qt::UniqueConnection同一按鈕多次:同一個按鈕如何調用不同的插槽?

連接(OBJ, SIGNAL(signal()),obj2,SLOT(slot()), Qt :: UniqueConnection);

繼續,我的問題是,當它不應該是一個相同的按鈕調用不同的插槽。我創建了一個通用的代碼來設置我的所有按鈕:

void KHUB::btSetupInt(QPushButton **button, const QString name, int posX, int posY, int width, int height, void (KHUB::*fptr)(int parameter), int value, int handler) { 
    *button = new QPushButton(name, this); 
    (*button)->setGeometry(QRect(QPoint(posX, posY), QSize(width, height))); 

    signalMapper->setMapping(*button, value); 
    connect(*button, SIGNAL(clicked()), signalMapper, SLOT(map())); 
    //qDebug() << "My value: " + QString::number(value); 

    switch (handler) { 
    case (int) ButtonHandler::hl_Register: 
     connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleRegister(int)), Qt::UniqueConnection); 
     break; 
    case (int)ButtonHandler::hl_UpVote: 
     connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleUpVote(int)), Qt::UniqueConnection); 
     break; 
    case (int) ButtonHandler::hl_OpenUrl: 
     //connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleUrl(int)), Qt::UniqueConnection); 
     break; 
    case (int)ButtonHandler::hl_DownVote: 
     connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleDownVote(int)), Qt::UniqueConnection); 
     break; 
    case (int) ButtonHandler::hl_DisposeBrowser: 
     connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleDispose(int)), Qt::UniqueConnection); 
     break; 
    } 
} 

在這我有我這是在我的頭文件中聲明signalMapper。此按鈕設置被稱爲:

void KHUB::handleSearch() { 
    //DO THE MATH 
    for (int pos = 0; pos < localUrl.size(); pos++){ 
    QLabel *link = new QLabel(); 
    link->setText("<a href=\"" + localUrl.at(pos) + "\">" + localUrl.at(pos) + "</a>"); 
    link->setTextFormat(Qt::RichText); 
    link->setTextInteractionFlags(Qt::TextBrowserInteraction); 
    link->setOpenExternalLinks(true); 

    QPushButton *upArrow = new QPushButton(); 
    btSetupInt(&upArrow, "Up Vote", 225, 300, 100, 25, &KHUB::handleUpVote, pos*147, (int)ButtonHandler::hl_UpVote); 

    QPushButton *open = new QPushButton("Open"); 
    //btSetupInt(&open, "Open", 225, 300, 100, 25, &KHUB::handleUrl, pos, (int) ButtonHandler::hl_OpenUrl); 

    QPushButton *downArrow = new QPushButton(); 
    btSetupInt(&downArrow, "Down Vote", 225, 300, 100, 25, &KHUB::handleDownVote, pos*163, (int)ButtonHandler::hl_DownVote); 

    QLabel *separator = new QLabel(); 
    QLabel *guider = new QLabel("<----------------------------------------------------------------------------------------------------------------------------------------------------->"); 

    gridLayout->addWidget(link, componentsPos, 0, 1, -1); 
    gridLayout->addWidget(guider, componentsPos, 1, 1, -1); 
    gridLayout->addWidget(upArrow, componentsPos - 1, 2, 1, 1, Qt::AlignBottom); 
    gridLayout->addWidget(open, componentsPos, 2, 1, 1); 
    gridLayout->addWidget(downArrow, componentsPos + 1, 2, 1, 1, Qt::AlignTop); 
    gridLayout->addWidget(separator, componentsPos + 2, 1, 1, 1); 

    componentsPos = componentsPos + 5; 
    } 
    //KEEP DOING THE MATH 
} 

註釋行與調試目的相同。無論如何,當我只有open QPushButton時,此代碼完全正常工作。當我添加upVotedownVote時,我希望程序能夠複製它的邏輯成功,而現在當我點擊向上投票或向下投票時,程序觸發兩個插槽來處理向上和向下投票,如果沒有評論,也會「打開」。處理向上和向下投票代碼:

void KHUB::handleUpVote(int reference) { 
    qDebug() << "This is my reference for upvoting: " + QString::number(reference/147); 
} 

void KHUB::handleDownVote(int reference) { 
    qDebug() << "This is my reference for DOWNVOTING: " + QString::number(reference/163); 
} 

根據Qt QSignalMapper documentation(主題「高級信號和槽的使用」,在頁面的結尾)我做的一切都如預期。您還必須注意到,自every button must have its only integer ID [請參閱集成void QSignalMapper::setMapping(QObject * sender, int id)的setMapping],我乘以 posbtSetupInt呼叫147和163(以產生「隨機」號碼)。

幾天前我對他們的三個按鈕(按鈕)使用了相同的位置(pos),以及生成的結果是否相乘。 這導致我的第一個問題:此ID是每個按鈕的唯一標識符或可以通過按鈕傳遞的唯一參數?我還沒有得到這考慮到我上面

這給了上下文是我的UI:

Application UI

這是我的輸出點擊(隨機鏈接choosen)最多投票在us.battle.net/wow/en/blog/19913791/patch-623-preview-10-14-2015

"This is my reference for upvoting: 3" 
"This is my reference for DOWNVOTING: 3" 

這是我的輸出點擊(隨機鏈接choosen)向下投票在http://www.swtor.com/holonet/companions/blizz

"This is my reference for upvoting: 6" 
"This is my reference for DOWNVOTING: 6" 

我用斷點來查看handler開關btSetupInt是否被正確調用,它是。即使不使用我的成員函數btSetupInt來調用連接,我仍然得到相同的錯誤結果。 要完成,我的第二個主要問題在給定的上下文中,甚至有可能同一個按鈕調用不同的插槽?我在這裏錯過了什麼?

+0

在將信號連接到新插槽之前,您需要將其與前一個插槽斷開連接。然後一切都會正常工作。 – johngull

+0

請賜教,我收到你的話,但沒有任何想法 - 我該怎麼做?在我的開關結束時,快速谷歌研究會像'button-> disconnect(SIGNAL(signal))'一樣? –

回答

1

因爲您要連接信號映射器多次,即每個按鈕實例。您正在創建一個按鈕,然後根據handler您正在連接到不同的插槽。但信號映射器的mapped(int)信號連接到多個插槽。希望你有我在這裏說的話。

您的代碼的另一個問題是內存泄漏。

QPushButton *upArrow = new QPushButton(); 
btSetupInt(&upArrow, "Up Vote", 225, 300, 100, 25, &KHUB::handleUpVote, pos*147, (int)ButtonHandler::hl_UpVote); 

btSetupInt()正在創建新按鈕。再次。

*button = new QPushButton(name, this); 

這是未經測試的代碼。檢查它是否有效。

// custom button claas 
class VotingButton : public QPushButton 
{ 
    Q_OBJECT 

public: 
    VotingButton(const QString& url, int voteType, QObject* prnt=0) 
     : QPushButton(prnt) 
      m_url(url), 
      m_voteType(voteType) 
    {} 

    QString getUrl() const { return m_url; } 
    int getVoteType() const { return m_voteType; } 

private: 
    QString  m_url; 
    int   m_voteType; 
} 

KHUB

connect(signalMapper, SIGNAL(mapped(QObject*)), this, SLOT(handleButtonPress(QObject*))); 

void KHUB::btSetupInt(QPushButton* button, const QString& name, int posX, int posY, int width, int height, const QString& url, int handler) { 
    button = new VotingButton(url, handler, this); 
    button->setText(name); 
    button->setGeometry(QRect(QPoint(posX, posY), QSize(width, height))); 
    signalMapper->setMapping(button, this); 
    connect(button, SIGNAL(clicked()), signalMapper, SLOT(map())); 
} 

void KHUB::handleSearch() { 
    //DO THE MATH 
    for (int pos = 0; pos < localUrl.size(); pos++){ 
    QLabel *link = new QLabel(); 
    link->setText("<a href=\"" + localUrl.at(pos) + "\">" + localUrl.at(pos) + "</a>"); 
    link->setTextFormat(Qt::RichText); 
    link->setTextInteractionFlags(Qt::TextBrowserInteraction); 
    link->setOpenExternalLinks(true); 

    QPushButton *upArrow; 
    btSetupInt(upArrow, "Up Vote", 225, 300, 100, 25, localUrl.at(i), (int)ButtonHandler::hl_UpVote); 

    QPushButton *open; 
    btSetupInt(open, "Open", 225, 300, 100, 25, localUrl.at(i), (int)ButtonHandler::hl_OpenUrl);  

    QPushButton *downArrow; 
    btSetupInt(downArrow, "Down Vote", 225, 300, 100, 25, localUrl.at(i), (int)ButtonHandler::hl_DownVote); 

    QLabel *separator = new QLabel(); 
    QLabel *guider = new QLabel("<----------------------------------------------------------------------------------------------------------------------------------------------------->"); 

    gridLayout->addWidget(link, componentsPos, 0, 1, -1); 
    gridLayout->addWidget(guider, componentsPos, 1, 1, -1); 
    gridLayout->addWidget(upArrow, componentsPos - 1, 2, 1, 1, Qt::AlignBottom); 
    gridLayout->addWidget(open, componentsPos, 2, 1, 1); 
    gridLayout->addWidget(downArrow, componentsPos + 1, 2, 1, 1, Qt::AlignTop); 
    gridLayout->addWidget(separator, componentsPos + 2, 1, 1, 1); 

    componentsPos = componentsPos + 5; 
    } 
    //KEEP DOING THE MATH 
} 

void KHUB::handleButtonPress(QObject* obj) 
{ 
    VotingButton* voteButton = static_cast<VotingButton*>(obj); 
    if (voteButton) { // now you have voteType and the url assigned to the button 
     switch (voteButton->getVoteType()) 
     { 
      case ... 
     } 
    } 
} 
+0

我真的很感謝你的回答,謝謝你;但是我需要幾個小時,直到我無法測試它,我明天有一個考試,所以我儘快回過頭來回答發生的事情 –

0

據我理解爲基於ramtheconqueror的回答,您不能使用同一個地圖來連接不同的插槽。在我的代碼中,我使用signalMapper連接到不同的處理程序(插槽),爲了解決這個問題,我只在btSetupInt上添加了一個QSignalMapper參數。我爲每種按鈕類型創建了三個不同的地圖,以提供我想要連接插槽的地圖。

我的代碼看起來像現在這樣:

void KHUB::btSetupInt(QPushButton **button, const QString name, int posX, int posY, int width, int height, void (KHUB::*fptr)(int parameter), QSignalMapper* map, int value, int handler) { 
    *button = new QPushButton(name, this); 
    (*button)->setGeometry(QRect(QPoint(posX, posY), QSize(width, height))); 

    map->setMapping(*button, value); 
    connect(*button, SIGNAL(clicked()), map, SLOT(map())); 
    //qDebug() << "My value: " + QString::number(value); 

    switch (handler) { 
    case (int) ButtonHandler::hl_Register: 
     connect(map, SIGNAL(mapped(int)), this, SLOT(handleRegister(int)), Qt::UniqueConnection); 
     break; 
    case (int)ButtonHandler::hl_UpVote: 
     connect(map, SIGNAL(mapped(int)), this, SLOT(handleUpVote(int)), Qt::UniqueConnection); 
     break; 
    case (int) ButtonHandler::hl_OpenUrl: 
     //connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(handleUrl(int)), Qt::UniqueConnection); 
     break; 
    case (int)ButtonHandler::hl_DownVote: 
     connect(map, SIGNAL(mapped(int)), this, SLOT(handleDownVote(int)), Qt::UniqueConnection); 
     break; 
    case (int) ButtonHandler::hl_DisposeBrowser: 
     connect(map, SIGNAL(mapped(int)), this, SLOT(handleDispose(int)), Qt::UniqueConnection); 
     break; 
    } 
} 

    void KHUB::handleSearch() { 
    //DO THE MATH 
    upVoteMap = new QSignalMapper(this); 
    downVoteMap = new QSignalMapper(this); 
    openMap = new QSignalMapper(this); 

    for (int pos = 0; pos < localUrl.size(); pos++){ 
    QLabel *link = new QLabel(); 
    link->setText("<a href=\"" + localUrl.at(pos) + "\">" + localUrl.at(pos) + "</a>"); 
    link->setTextFormat(Qt::RichText); 
    link->setTextInteractionFlags(Qt::TextBrowserInteraction); 
    link->setOpenExternalLinks(true); 

    QPushButton *upArrow; 
    btSetupInt(&upArrow, "Up Vote", 225, 300, 100, 25, &KHUB::handleUpVote, upVoteMap, pos, (int)ButtonHandler::hl_UpVote); 

    QPushButton *open; 
    btSetupInt(&open, "Open", 225, 300, 100, 25, &KHUB::handleUrl, openMap, pos, (int) ButtonHandler::hl_OpenUrl); 

    QPushButton *downArrow; 
    btSetupInt(&downArrow, "Down Vote", 225, 300, 100, 25, &KHUB::handleDownVote, downVoteMap, pos, (int)ButtonHandler::hl_DownVote); 

    QLabel *separator = new QLabel(); 
    QLabel *guider = new QLabel("<----------------------------------------------------------------------------------------------------------------------------------------------------->"); 

    gridLayout->addWidget(link, componentsPos, 0, 1, -1); 
    gridLayout->addWidget(guider, componentsPos, 1, 1, -1); 
    gridLayout->addWidget(upArrow, componentsPos - 1, 2, 1, 1, Qt::AlignBottom); 
    gridLayout->addWidget(open, componentsPos, 2, 1, 1); 
    gridLayout->addWidget(downArrow, componentsPos + 1, 2, 1, 1, Qt::AlignTop); 
    gridLayout->addWidget(separator, componentsPos + 2, 1, 1, 1); 

    componentsPos = componentsPos + 5; 
    } 
    //KEEP DOING THE MATH 
} 

相信ramtheconqueror的解決方案會工作,並肯定它比我的發燒友,儘管它,因爲我工作的一個命題是不適用我的情況和爲了證明我的POV,我需要創建預先建立的有限數量的類。

無論如何,我會認爲他的答案是正確的,因爲沒有他,我不會意識到我自己的答案。

不幸的是,我仍然沒有回答我的第一個問題,但我希望總體上這可以幫助未來的人。

乾杯

相關問題