连接两个具有不同参数的信号

Connecting two signals with different arguments

我想让 QTreeView 小部件在单击按钮时发出 clicked(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)

我是不是误解了整个信号转发的概念?

一如既往,非常感谢。

您正在将一个 SIGNAL() 连接到另一个 SIGNAL(),这完全没问题,但它们的参数应该匹配。在您的情况下,第二个信号具有第一个信号没有的参数(即 QModelIndex)。

首先,您必须通过单击树中的按钮发送什么索引? 其次,由于 c++11 标准,你可以做类似的事情:

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

我会用以下方法解决你的问题:

首先你必须处理按钮点击:

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.
    }

}

Have I misunderstood the whole signal forwarding concept?

是的。

发出信号时,Qt 获取信号的参数并将它们传递给连接的 slot/signal。

有效的信号槽连接

例如,假设您将 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() 无法提供此值。因此,您不能将这两者联系在一起。

这有意义吗?

非常感谢@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);
    }

}

关于我关于信号到信号连接如何工作的问题,感谢大家花时间解释这个:)