2016-05-20 37 views
0

我想要一個QTreeView小部件,當單擊按鈕時發出點擊(const QModelIndex &)信號。這樣,我可以在點擊按鈕時獲得在QTreeView中選擇的所有項目的列表。現在,我想我可以用不同的參數(Qt Connect signals with different arguments)連接兩個信號,但是當我嘗試調用連接具有不同參數的兩個信號

connect(ui.pbAddVideo, SIGNAL(clicked()), ui.treeView_video, SIGNAL(clicked(const QModelIndex&))); 

我得到的錯誤信息:

QObject::connect: Incompatible sender/receiver arguments QPushButton::clicked() --> QTreeView::clicked(QModelIndex) 

我有沒有誤解整個信號轉發概念?

一如既往,非常感謝。

+0

要鏈接的文章是關於_fewer_參數。你試圖完成的是有更多的爭論。 –

+0

我不認爲這是可能的,你所期望的。如果您可以從與按鈕的點擊信號相連的插槽獲取所有信息,爲什麼還需要樹視圖中的信號?我認爲你只是讓事情變得複雜。 – vahancho

+0

@Jeffrey van de Glind那麼爲什麼有一個案例工作,其他不是? –

回答

1

我會解決你的問題有以下方法:

首先,你必須處理按鈕點擊:

connect(ui.pbAddVideo, SIGNAL(clicked()), this, SLOT(onLoadVideo())); 

在插槽中,你需要從樹視圖中選擇獲得的項目清單,並做一些與他們:

void MyClass::onLoadVideo() 
{ 
    QItemSelectionModel *selectionModel = ui.treeView_video->selectionModel(); 
    QModelIndexList selectedVideos = selectionModel->selectedIndexes(); 
    foreach (QModelIndex *video, selectedVideos) { 
     // Play the video. 
    } 

} 
+0

謝謝。這或多或少是我現在實施的解決方案。 –

0

您正在將一個SIGNAL()連接到另一個SIGNAL(),這是完全可以的,但它們的參數應該匹配。在你的情況下,第二個信號具有第一個信號不具有的參數(即QModelIndex)。

3

溫柔地,你必須通過點擊樹上的按鈕發送什麼索引? 其次,由於C++ 11非標準你可以做這樣的事情:

connect(ui.pbAddVideo, &QPushButton::clicked, [=] { emit ui.treeView_video->clicked(ui.treeView_video->currentIndex()); }); 
+0

這確實解決了我的問題,但它似乎是一種解決方法。我仍然好奇爲什麼直接轉發信號不起作用。我發現這些信號有不同的論點,但如果我只是希望發出一個信號,而另一個信號發出,我不明白爲什麼它應該是一個問題。 –

+0

發件人可以由任何參數填充,但發件人可以是或空的,或者具有發件人發送的相同參數(不是相同的計數但是以相同的順序)。所以你可以這樣做:'connect(this,SIGNAL(someSignal(int,int,QString)),SIGNAL(secondSignal(int,int)));',但是這個'connect(this,SIGNAL(someSignal()), SIGNAL(secondSignal(int,int)));'不會正確工作,因爲你不知道int是在接收器中?所以,解決方案之一 - 從'QTreeView'繼承並創建信號,你需要什麼。 – someoneinthebox

0

我誤解了整個信號轉發概念嗎?

是的。

當發出信號時,Qt接收信號的參數並將它們傳遞給所連接的插槽/信號。

有效信號槽連接

例如,假設在連接QSlider::valueChanged(int)信號到QSpinBox::setValue(int)槽。當的valueChanged()信號被髮射,這是時隙被如何有效地叫:

// "Emitting a signal" == "Calling the signal function" 
QSlider::valueChanged(int sliderSignalValue) 
{ 
    QSpinBox *receiver = findReceiver(); 
    receiver->setValue(sliderSignalValue); 
} 

有效信號,信號連接

同樣,如果您的QSlider::valueChanged(int)信號連接到QSpinBox::valueChanged(int)信號時,代碼的行爲是這樣的:

QSlider::valueChanged(int sliderSignalValue) 
{ 
    QSpinBox *receiver = findReceiver(); 
    emit receiver->valueChanged(sliderSignalValue); 
} 

現在,如果你想在相反的方向(connect(ui.treeView_video, SIGNAL(clicked(const QModelIndex&)), ui.pbAddVideo, SIGNAL(clicked()));連接,它是完美的罰款:

QTreeView::clicked(const QModelIndex& viewSignalValue) 
{ 
    QPushButton *receiver = findReceiver(); 
    emit receiver->clicked(); // No problem. The viewSignalValue is simply ignored. 
} 

無效的信號插槽連接

不過,對於連接,你要拍,代碼就需要這樣的表現:

QPushButton::clicked() 
{ 
    QTreeView *receiver = findReceiver(); 
    emit receiver->clicked(/*???*/); // ERROR: You need to pass a QModelIndex value! 
} 

你已經有了一個參數不匹配。 QTreeView::clicked()需要QModelIndex值,但QPushButton::clicked()無法提供此值。因此,您無法將這兩者連接在一起。

這是否有意義?

+0

謝謝,現在對我來說這一切都更加清晰。我相信這個解釋也會對其他人有用。 –

0

非常感謝@vahancho,我的答案是我的答案。從qTreeView中使用「clicked()」信號沒有意義,因爲我不需要等待它來訪問裏面的數據。因此:

connect(ui.pbAddVideo, SIGNAL(clicked()), this, SLOT(addVideo())); 

    void VigilWidget::addVideo() { 

    QItemSelectionModel *selectionModel = ui.treeView_video->selectionModel(); 
    QModelIndexList selectedVideos = selectionModel->selectedIndexes(); 
    foreach (QModelIndex video, selectedVideos) { 
     qDebug().nospace() << video.data(0); 
    } 

} 

至於我如何信號,信號連接的工作問題,感謝大家抽出時間來解釋這:)

相關問題