2014-01-16 46 views
8

我在C++上有一個Qt應用程序,我想給QPushButton分配一個插槽。但我想傳遞一些參數,因爲我有不止一個QPushButton做類似的事情,所以我想要一個函數,但有一個參數,但Qt一直說我沒有這樣的插槽。有人能告訴我爲什麼,我該怎麼做?Qt 5將參數分配給QPushButton插槽

預先感謝您

在.h文件中我有:(它是在開始私人,但我的問題的搜索改變了它)

public slots: 
    void handleButton(int row, int col); 

然後在的.cpp:

void fieldWindow::handleButton(int row, int col){ 
    cout << row << " " << col << endl; 
} 
在相同的.cpp

並再次:

connect(this->buttonsField[i][j], SIGNAL(released()), this, SLOT(handleButton(i,j))); 

這是在兩個嵌套循環中完成的,因此ij已被很好地定義。

而且我的錯誤是:

QObject::connect: No such slot fieldWindow::handleButton(i,j) in ..\Proj1\fieldwindow.cpp:41 
QObject::connect: (receiver name: 'fieldWindow') 

我看了網上的東西,我應該說handleButton(int, int);但後來我應該如何傳遞參數?

+0

'connect'語句不接受'SIGNAL(...)'表達式中的任何參數。 'SIGNAL'是一個將函數*簽名*封裝在要傳遞給'connect'的字符串中的宏。 – leemes

+0

所以它應該是'handleButton(int,int)'?!但是,我怎樣才能通過這些論據呢?! – Bankin

回答

11

不幸的是,當調用信號時,Qt信號槽連接不接受任何傳遞給槽的參數。這隻適用於信號本身提供這些參數的情況,但不能將其添加到connect語句中。

但是你不是唯一一個想要這樣做的人,所以在Qt中有一個類差不多你想要什麼:QSignalMapper。此類的一個實例可用作信號插槽連接的「代理」:將(多個)按鈕連接到此類的插槽,並將此類的信號連接到目標插槽。然後,對於每個「發件人」實例(在您的案例按鈕中),您可以告訴該類添加到被調用插槽的值。例如:

QPushButton * button1 = ...; 
QPushButton * button2 = ...; 

QSignalMapper mapper; 

connect(button1, SIGNAL(released()), &mapper, SLOT(map())); 
mapper.setMapping(button1, 42); // Number to be passed in the slot 

connect(button2, SIGNAL(released()), &mapper, SLOT(map())); 
mapper.setMapping(button2, 1337); // Number to be passed in the slot 

connect(&mapper, SIGNAL(mapped(int)), this, SLOT(handleButton(int))); 

可悲的是,你可以看到這個類只能處理一個參數。對於你的情況,你應該選擇一種不同的方法(我解釋了上述情況,如果你再次遇到類似的問題,但只有一個參數int)。

適合您的問題的替代方法是依靠插槽中的sender()。記住你的映射像

QMap<QObject*,int> rows; 
QMap<QObject*,int> cols; 

的數據結構和訪問這些在你的插槽,採用沒有參數

void fieldWindow::handleButton(){ 
    int row = rows[sender()]; 
    int col = cols[sender()]; 
    cout << row << " " << col << endl; 
} 

當然,初始化你的UI時,你需要把相應的值這些地圖。或者您可以搜索您現有陣列中的按鈕buttonsField

自Qt5和C++ 11以來存在另一種方法:除了插槽,您可以在lambda函數中處理信號。這看起來像這樣(的信號是使用一種新的語法命名):

connect(this->buttonsField[i][j], &QPushButton::released, [=]{ 
    handleButton(i, j); 
}); 

如果你不喜歡的lambda語法,它也可以使用一些helper從標準庫組成一個仿函數,而不是一個lambda,或者你可以編寫你自己的函數類,但是我個人覺得lambda非常可讀。

+0

非常感謝!我可以用簡單的公式'i * count_on_row + j'減少到一個,所以我會嘗試第一種方法,我希望它能起作用!非常感謝你的詳細解答:) – Bankin

+1

我很高興能幫上忙。如果你有Qt5,我添加了第三種方法。請注意,如果您只需要這些值來訪問您獲取按鈕指針的按鈕數組,您也可以簡單地使用'sender()'來完成。 – leemes

+2

哦,他們加了lambda!大!這工作完美!非常感謝! :) – Bankin