连接两个具有不同参数的信号
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);
}
}
关于我关于信号到信号连接如何工作的问题,感谢大家花时间解释这个:)
我想让 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);
}
}
关于我关于信号到信号连接如何工作的问题,感谢大家花时间解释这个:)