我有一个功能可以检测 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()));
每次单击组合框时,我都需要刷新并尝试检测摄像头,但由于界面设置,我不确定是否可行。我不认为不断刷新程序是一个好的选择,所以我没有想法。有什么办法吗?
最佳答案
您可以在另一个线程中生成相机列表:
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() {
...
}
关于c++ - 在 C++ 中刷新组合框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31125470/