我有一個包含許多子菜單的QMenu。這些是動態創建的,即名稱菜單來自數據庫並在循環中創建。現在我想點擊菜單時點擊觸發()或類似的插槽,但我需要將QString菜單名稱傳遞給插槽,以便執行菜單特定的操作。我試過this,即將QAction *傳遞給觸發事件並使用了setData,但我得到運行時錯誤。如何通過QSignalMapper或其他方式將QString從QMenu傳遞到Qt插槽
對象::連接:沒有這樣的信號的QAction ::觸發(的QAction *)
for(int j=0; j<channelTypes[i].getNumChannels() ; j++){
QAction *subMenuAct = subMenu->addAction(tr(c_name)); // c_name the menu name
subMenuAct->setData(ch_name);
connect(subMenuAct, SIGNAL(triggered(QAction *)), this, SLOT(playChannel(QAction *))); // playChannel is the slot
}
void <ClassName>::playChannel(QAction *channelAction)
{
QString str = channelAction->data().toString();
qDebug() << "Selected - " << str;
}
可替換地,我還試圖QSignalMapper其中signalMapper是在構造初始化的數據成員
signalMapper = new QSignalMapper(this);
和
for(int j=0; j<channelTypes[i].getNumChannels() ; j++){
QAction *subMenuAct = subMenu->addAction(tr(c_name));
connect(subMenuAct, SIGNAL(triggered()), signalMapper, SLOT(map()));
signalMapper->setMapping(subMenu, ch_name);
connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(playChannel(QString)));
}
在第二種情況下,我沒有收到任何錯誤,但是插槽功能playChannel沒有被調用。如果有人能幫助解決這個問題,我會很感激。
更新1:唯一的區別,我從我看到其它實例中看到的是,通常人們都從幾個小部件的單個插槽連接信號(說不同的按鈕)。在我的情況下,我將幾個子菜單(具有不同的名稱)連接到單個插槽。這應該有什麼區別?
更新2:它在QSignalMapper的解決方案below中建議的更正之後工作。另外事實是我使用SubMenu作爲setMapping的參數,其中應該使用MenuAction項目。但是現在我正在多次觸發事件,即多次選擇子菜單類別的主菜單中的條目。如果頻道類型是帶有四個條目的英語(主菜單)),HBO,明星電影等(子菜單),並且我選擇HBO,則使用字符串HBO觸發四次事件。它工作正常,如果我爲每個子菜單創建一個單獨的信號映射器。但我希望能夠使用單個映射器,並且我在這裏做了一些不正確的事情。一些更多的細節在評論中給出答案。
您需要縮小有問題的代碼併發布最小代碼示例,以便重現問題。除了在每次迭代中不需要將signalMapper連接到某個插槽,一切看起來都很好。你確定你改變了插槽簽名嗎? –
謝謝 - 這些是兩個單獨的最小代碼示例,它們以任何方式重現問題。我沒有辦法縮小它的範圍。一個人通過信號映射器嘗試,另一個人使用QAction *。首先顯示運行時間錯誤,第二個完全沒有,但沒有任何工作。是的,我確定插槽簽名每個都改變了,例如一個是QString,另一個是QAction *。如果不是這樣,我會遇到編譯錯誤。 – fayyazkl
關於在每次迭代中連接signalMapper,我將如何指定ch_name的每次迭代具有不同的名稱,並且應該在從菜單中選擇時產生相同的名稱? – fayyazkl