c++ - 在 C++ 中刷新组合框?

标签 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()));

每次单击组合框时,我都需要刷新并尝试检测摄像头,但由于界面设置,我不确定是否可行。我不认为不断刷新程序是一个好的选择,所以我没有想法。有什么办法吗?

最佳答案

您可以在另一个线程中生成相机列表:

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/

相关文章:

c++ - 当套接字错误发生时,QWebSocket 底层的 QTcpSocket(或 QSslSocket)是否会被自身破坏?

c++ - 在qt中使用QStandardItemModel显示QSQLite数据库

c++ - 很多 QGraphicsItem

c++ - 如何将图像附加到使用 Qt Creator 创建的 gui

c# - 如何验证我分配给组合框的字典值是我认为的值?

.net - VB.NET:如何防止用户在组合框中输入

c# - 组合框下拉列表和按键

c++ - 试图引用已删除的函数(未引用已创建的函数)

c++ - 使用 opencv 库和 c++ 缩放图像的像素

c++ - 如何为vector of vector预留内存