用C ++刷新一个Combobox?

时间:2015-06-29 20:59:52

标签: c++ qt combobox camera

我有一个功能可以检测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()));

我需要刷新并尝试在每次点击组合框时检测摄像机,但由于接口设置,我不确定是否可能。我不认为不断刷新程序是一个不错的选择,所以我没有想法。有没有办法做到这一点?

1 个答案:

答案 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() {
  ...
}