我有一个功能可以检测3D切片器中的相机端口,但它似乎只运行一次。当我拔下/插入相机时,端口的数量应该在组合框中更新(在Qt中设计),但没有任何变化。
我正在使用的功能在单击相机端口时检测到:
void qSlicerTrackingModuleWidget::onCameraPortClicked(){
Q_D(qSlicerTrackingModuleWidget);
// Clear current entries
d->CameraPortComboBox->clear();
int n = 0;
// Loop over camera ports until last one is found. Add all available ports to combo box and exit.
while(1){
cv::VideoCapture cap = cv::VideoCapture(n);
if(!cap.isOpened()){
return;
}
QString portNum = QString::fromStdString(std::to_string(n++));
d->CameraPortComboBox->addItem(portNum);
qSlicerCoreApplication::processEvents();
}
}
设置功能最后运行,并将GUI分配给实际功能。
connect( d->CameraPortComboBox, SIGNAL(clicked()), this, SLOT(onCameraPortClicked()));
我需要刷新并尝试在每次点击组合框时检测摄像机,但由于接口设置,我不确定是否可能。我不认为不断刷新程序是一个不错的选择,所以我没有想法。有没有办法做到这一点?
答案 0 :(得分:1)
您可以在另一个帖子中生成相机列表:
void qSlicerTrackingModuleWidget::onCameraPortClicked() {
QtConcurrent::run([this]{
QStringList cameras;
for (int i = 0; true; ++i) {
auto cap = cv::VideoCapture(i);
if (! cap.isOpened()) break;
cameras << QString::number(i);
}
// This is a queued, thread-safe call. It will execute in the
// GUI thread.
QMetaObject::invokeMethod(this, "onCameraList",
Q_ARG(QStringList, cameras));
});
}
// another slot
void qSlicerTrackingModuleWidget::onCameraList(const QStringList & cameras) {
Q_D(qSlicerTrackingModuleWidget);
d->CameraPortComboBox->clear();
for (auto portNum : cameras)
d->CameraPortComboBox->addItem(portNum);
}
另请注意,组合框没有clicked()
信号。您需要在组合框上安装事件过滤器才能访问您感兴趣的事件。也许您也可以使用Enter
事件:
class EventSignaller : public QObject {
Q_OBJECT
bool eventFilter(QObject * obj, QEvent * event) {
if (event->type() == QEvent::Enter)
emit entered(qobject_cast<QWidget*>(obj));
if (event->type() == QEvent::MouseButtonPress)
emit clicked(qobject_cast<QWidget*>(obj));
return QObject::eventFilter(obj, event);
}
public:
EventSignaller(QObject* parent = 0) : QObject(parent) {}
Q_SIGNAL void entered(QWidget*);
Q_SIGNAL void clicked(QWidget*);
void track(QWidget * widget) {
widget->removeEventFilter(this); // ensure we're unique
widget->installEventFilter(this);
}
};
qSlicerTrackingModuleWidget::qSlicerTrackingModuleWidget() : ... {
auto signaller = new EventSignaller(this);
connect(signaller, SIGNAL(entered(QWidget*)), // or SIGNAL(clicked(QWidget*))
SLOT(updateCameraPorts()));
...
}
void qSlicerTrackingModuleWidget::updateCameraPorts() {
...
}