When I re-plug the camera from USB port and fire up my program, the preview pane will black out and nothing works. However, if I fire up my program for the second time, the qt preview pane will live play smoothly.
How can I fix preview pane not working at first startup after connecting the camera?
INFO:
Mac mini
OS: macOS m1, montery 12.3.1
Platform: Qt 6.3
Port: USB3.0
IMG format: Motion JPEG
Code snippet:
main.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsVideoItem>
#include <QCamera>
#include <QMediaCaptureSession>
#include <QMediaDevices>
#include <QCameraDevice>
#include <QList>
#include <QAudioInput>
#include <QCloseEvent>
#include <QPushButton>
#include <QImageCapture>
#include "opencv2/opencv.hpp"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void showEvent(QShowEvent* event);
void closeEvent(QCloseEvent* event);
private:
Ui::MainWindow *ui;
QGraphicsView* pGraphyView;
QGraphicsScene* pGraphyScene;
QGraphicsVideoItem* pGraphyVideoItem;
QCamera* pCamera;
QMediaCaptureSession captureSession;
QAudioInput* pAudioInput;
QImageCapture* pImageCapture;
cv::Mat srcImage;
cv::Mat dstImage;
};
#endif // MAINWINDOW_H
main.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
//=====================================================================
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
pGraphyView = 0;
pGraphyScene = 0;
pGraphyVideoItem = 0;
pCamera = 0;
}
//=====================================================================
MainWindow::~MainWindow()
{
delete ui;
}
//=====================================================================
void MainWindow::showEvent(QShowEvent* event)
{
pAudioInput = new QAudioInput;
captureSession.setAudioInput(pAudioInput);
QStringList str_list;
QString str_id;
QString str_vid;
QString str_pid;
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
qDebug() << "camera count = " << cameras.size();
for (const QCameraDevice &cameraDevice : cameras)
{
str_id = cameraDevice.id();
str_vid = str_id.mid(9,4);
str_pid = str_id.right(4);
qDebug() << "id = " << str_id;
qDebug() << "vid = 0x" << str_vid;
qDebug() << "pid = 0x" << str_pid;
if(str_vid == "a168")
{
pCamera = new QCamera(cameraDevice);
captureSession.setCamera(pCamera);
pGraphyScene = new QGraphicsScene(0,0,640,480);
pGraphyView = new QGraphicsView(this);
pGraphyView->setScene(pGraphyScene);
this->setCentralWidget((QWidget*)pGraphyView);
pGraphyVideoItem = new QGraphicsVideoItem;
pGraphyVideoItem->setSize(QSizeF(640,480));
pGraphyVideoItem->setPos(0,0);
pGraphyScene->addItem(pGraphyVideoItem);
captureSession.setVideoOutput(pGraphyVideoItem);
pCamera->start(); // live play.
break;
}
}
}
//=====================================================================
void MainWindow::closeEvent(QCloseEvent* event)
{
if(pAudioInput)
{
delete pAudioInput;
pAudioInput = 0;
}
if(pGraphyVideoItem)
{
delete pGraphyVideoItem;
pGraphyVideoItem = 0;
}
if(pGraphyScene)
{
delete pGraphyScene;
pGraphyScene = 0;
}
if(pGraphyView)
{
delete pGraphyView;
pGraphyView = 0;
}
event->accept();
}
I tried using macOS' facetime to check if the camera itself is functionable, and it did. The facetime live play smoothly.
I guess it's something related to Qt 6.3.
I can't get the qt preview pane to work. It's always black after I plug in the camera.
INFO:
Mac mini
OS: macOS m1, montery 12.3.1
Platform: Qt 6.3
Port: USB3.0
Img format: YUY2
Code snippets:
main.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsVideoItem>
#include <QCamera>
#include <QMediaCaptureSession>
#include <QMediaDevices>
#include <QCameraDevice>
#include <QList>
#include <QAudioInput>
#include <QCloseEvent>
#include <QPushButton>
#include <QImageCapture>
#include "opencv2/opencv.hpp"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void showEvent(QShowEvent* event);
void closeEvent(QCloseEvent* event);
private:
Ui::MainWindow *ui;
QGraphicsView* pGraphyView;
QGraphicsScene* pGraphyScene;
QGraphicsVideoItem* pGraphyVideoItem;
QCamera* pCamera;
QMediaCaptureSession captureSession;
QAudioInput* pAudioInput;
QImageCapture* pImageCapture;
cv::Mat srcImage;
cv::Mat dstImage;
};
#endif // MAINWINDOW_H
main.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
//=====================================================================
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
pGraphyView = 0;
pGraphyScene = 0;
pGraphyVideoItem = 0;
pCamera = 0;
}
//=====================================================================
MainWindow::~MainWindow()
{
delete ui;
}
//=====================================================================
void MainWindow::showEvent(QShowEvent* event)
{
pAudioInput = new QAudioInput;
captureSession.setAudioInput(pAudioInput);
QStringList str_list;
QString str_id;
QString str_vid;
QString str_pid;
const QList<QCameraDevice> cameras = QMediaDevices::videoInputs();
qDebug() << "camera count = " << cameras.size();
for (const QCameraDevice &cameraDevice : cameras)
{
str_id = cameraDevice.id();
str_vid = str_id.mid(9,4);
str_pid = str_id.right(4);
qDebug() << "id = " << str_id;
qDebug() << "vid = 0x" << str_vid;
qDebug() << "pid = 0x" << str_pid;
if(str_vid == "a168")
{
pCamera = new QCamera(cameraDevice);
captureSession.setCamera(pCamera);
pGraphyScene = new QGraphicsScene(0,0,640,480);
pGraphyView = new QGraphicsView(this);
pGraphyView->setScene(pGraphyScene);
this->setCentralWidget((QWidget*)pGraphyView);
pGraphyVideoItem = new QGraphicsVideoItem;
pGraphyVideoItem->setSize(QSizeF(640,480));
pGraphyVideoItem->setPos(0,0);
pGraphyScene->addItem(pGraphyVideoItem);
captureSession.setVideoOutput(pGraphyVideoItem);
pCamera->start(); // live play.
break;
}
}
}
//=====================================================================
void MainWindow::closeEvent(QCloseEvent* event)
{
if(pAudioInput)
{
delete pAudioInput;
pAudioInput = 0;
}
if(pGraphyVideoItem)
{
delete pGraphyVideoItem;
pGraphyVideoItem = 0;
}
if(pGraphyScene)
{
delete pGraphyScene;
pGraphyScene = 0;
}
if(pGraphyView)
{
delete pGraphyView;
pGraphyView = 0;
}
event->accept();
}
I tried using macOS' facetime to check if the camera itself is functionable, and it did. The facetime live play smoothly.
I guess it's something related to Qt 6.3.
When I setup font for Qt application, it has no effect on the part of code executed on QTimer's timeout() signal.
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QFontDatabase>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
int id = QFontDatabase::addApplicationFont(":/Blackbird.ttf");
qDebug() << "Initial font:" << qApp->font();
qApp->setFont(QFontDatabase::applicationFontFamilies(id).at(0));
qDebug() << "Set font:" << qApp->font();
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFontDatabase>
#include <QTime>
#include <QTimer>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QTimer *t = new QTimer(this);
t->start(1000);
connect(t, &QTimer::timeout, [=]{
qDebug() << "Timer font:" << qApp->font();
ui->label->setText(QTime::currentTime().toString());
});
}
MainWindow::~MainWindow()
{
delete ui;
}
Output of this code:
Initial font: QFont(Liberation Sans,11,-1,5,50,0,0,0,0,0)
Set font: QFont(Blackbird,12,-1,5,50,0,0,0,0,0)
Timer font: QFont(Liberation Sans,11,-1,5,50,0,0,0,0,0)
Timer font: QFont(Liberation Sans,11,-1,5,50,0,0,0,0,0)
...
But when I add some the code
QTimer *t = new QTimer(this);
t->setSingleShot(true);
connect(t, &QTimer::timeout, [=]{
qApp->setFont(QFontDatabase::applicationFontFamilies(0).at(0));
});
t->start(0);
t->setSingleShot(false);
t->start(1000);
connect(t, &QTimer::timeout, [=]{
qDebug() << "Timer font:" << qApp->font();
ui->label->setText(QTime::currentTime().toString());
});
everything works:
Initial font: QFont(Liberation Sans,11,-1,5,50,0,0,0,0,0)
Set font: QFont(Blackbird,12,-1,5,50,0,0,0,0,0)
Timer font: QFont(Blackbird,12,-1,5,50,0,0,0,0,0)
Timer font: QFont(Blackbird,12,-1,5,50,0,0,0,0,0)
It looks like the main thread and QTimer use different QCoreApplication::instance, but I checked qApp->applicationPid(), it is the same.
Is there a possibility to set the same font for all application at once?
UPD: I have just noticed, that the problem exists with Qt 5.14.1, which is currently default on Gentoo Linux.
With Qt 5.12.8, compiled from source with 'debug' option, it works properly.
Welcome I have a problem with scanning Wi-Fi to get all available connecting in Wi-Fi. I have writed so far this code:
#include <QCoreApplication>
#include <QNetworkConfigurationManager>
#include <QNetworkConfiguration>
#include <QDebug>
#include <QNetworkSession>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QNetworkConfigurationManager ncm;
QNetworkConfiguration cfg;
QNetworkConfiguration::StateFlags flags;
int count = QNetworkConfiguration::Active;
qDebug() << "Amount available connect in Wi-Fi :" << count;
qDebug() << ncm.allConfigurations(flags = 0);
return a.exec();
}
I have a problem with shows allConfigurations. I have read documentation
Qt Network Configuration Manager
but I do not know how to do that.
Scanning Wi-Fi using QNetworkAccessManager.
I use QNetworkConfigurationManager class to get all WiFi s availables and show all of them into QTreeWidget.
QNetworkConfigurationManager ncm;
netcfgList = ncm.allConfigurations();
.pro file:
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = WiFi
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
.cpp file:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
findTimer = new QTimer();
findTimer->setInterval(1000);
connect(findTimer,&QTimer::timeout,this,&MainWindow::findActiveWirelesses);
findTimer->start();
foundCount = 0;
ui->treeWidgetWiFis->setColumnWidth(0,50);
ui->treeWidgetWiFis->setColumnWidth(1,200);
findActiveWirelesses();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::findActiveWirelesses()
{
QNetworkConfigurationManager ncm;
netcfgList = ncm.allConfigurations();
WiFisList.clear();
for (auto &x : netcfgList)
{
if (x.bearerType() == QNetworkConfiguration::BearerWLAN)
{
if(x.name() == "")
WiFisList << "Unknown(Other Network)";
else
WiFisList << x.name();
qDebug() << x.type();
}
}
for(int i=0; i<WiFisList.size(); i++)
{
bool exist = false;
QTreeWidgetItem * item = new QTreeWidgetItem();
for(int j=0; j<ui->treeWidgetWiFis->topLevelItemCount(); j++)
{
QTreeWidgetItem *index = ui->treeWidgetWiFis->topLevelItem(j);
QString str = index->text(1);
if(str == WiFisList[i])
{
exist = true;
break;
}
}
if(!exist)
{
item->setTextAlignment(0,Qt::AlignVCenter);
item->setTextAlignment(1,Qt::AlignHCenter);
item->setText(0,QString::number(++foundCount));
item->setText(1,WiFisList[i]);
ui->treeWidgetWiFis->addTopLevelItem(item);
}
}
}
.h file:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include <QList>
#include <QInputDialog>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QNetworkConfiguration>
#include <QNetworkConfigurationManager>
#include <QNetworkSession>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
int foundCount;
QNetworkConfiguration netcfg;
QStringList WiFisList;
QList<QNetworkConfiguration> netcfgList;
public slots:
void findActiveWirelesses();
private:
Ui::MainWindow *ui;
QTimer *findTimer;
QStandardItemModel* listModel;
QNetworkSession *session;
};
#endif // MAINWINDOW_H
I want to make my application multithreaded. When I added 2 separate independent threads I have got runtime error message. I can't find the solution. Perhaps someone may help.
Here is link to runtime error image https://postimg.org/image/aasqn2y7b/
threads.h
#include <thread>
#include <atomic>
#include <chrono>
#include <iostream>
class Threads
{
public:
Threads() : m_threadOne(), m_threadTwo(), m_stopper(false) { }
~Threads() {
m_stopper.exchange(true);
if (m_threadOne.joinable()) m_threadOne.join();
if (m_threadTwo.joinable()) m_threadTwo.join();
}
void startThreadOne() {
m_threadOne = std::thread([this]() {
while (true) {
if (m_stopper.load()) break;
std::cout << "Thread 1" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
}
void startThreadTwo() {
m_threadOne = std::thread([this]() {
while (true) {
if (m_stopper.load()) break;
std::cout << "Thread 2" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
}
private:
std::thread m_threadOne;
std::thread m_threadTwo;
std::atomic<bool> m_stopper;
};
mainwindow.h
#include "threads.h"
#include <QMainWindow>
#include "ui_mainwindow.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0) : QMainWindow(parent), ui(new Ui::MainWindow), m_threads() {
ui->setupUi(this);
m_threads.startThreadOne();
m_threads.startThreadTwo();
}
~MainWindow() { delete ui; }
private:
Ui::MainWindow *ui;
Threads m_threads;
};
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Your start thread two is broken:
m_threadOne = std::thread([this]() { ... });
After starting thread one, m_thread_one gets another thread assigned. However, the thread one is not joined, hence the termination.