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.
Related
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.
In an earlier Question I asked about why my program/QTcpServer was crashing all the time, and I really appreciate the help I got from everyone.
However, I have decided to try and rebuild the Program from scratch in order to see why it crashes, and I may have found something.
Allow me to post the new Code below:
//mainwindow.h
#include <QMainWindow>
#include <QPushButton>
#include <QTextEdit>
#include <QStandardItemModel>
#include <QTcpServer>
#include <QTcpSocket>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void startServer();
void handleConnection();
void readMessage();
void ReadXML(QString XMLString);
private:
QPushButton *SServer;
QTextEdit * ContainerView; //not changing to QTableView just yet
int Pallet_Number;
QTcpServer *tcpServer;
QTcpSocket *tcpSocket;
};
//mainwindow.cpp
#include "mainwindow.h"
#include <QLabel>
#include <QLayout>
#include <QDebug>
#include <QDomDocument>
#include <QRegularExpression>
static QRegularExpression Box_Code("B");
static QRegularExpression Cylinder_Code("C");
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
SServer(new QPushButton("Start Listening")),
ContainerView(new /*QTableView*/QTextEdit),
tcpServer(new QTcpServer),
tcpSocket(new QTcpSocket)
{
QStringList HeaderRow;
HeaderRow.append("Pallet");
HeaderRow.append("Container");
HeaderRow.append("Code");
HeaderRow.append("Height");
HeaderRow.append("Breadth/Diameter");
HeaderRow.append("Length");
HeaderRow.append("Weight");
resize(800,300);
connect(SServer, &QPushButton::clicked, this, &MainWindow::startServer);
connect(tcpServer, &QTcpServer::newConnection, this, &MainWindow::handleConnection);
connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::handleConnection);
QLabel *Lab1(new QLabel("Listening on Port 6164"));
QHBoxLayout *HB(new QHBoxLayout);
QVBoxLayout *VB(new QVBoxLayout);
HB->addWidget(SServer);
HB->addWidget(Lab1);
VB->addItem(HB);
VB->addWidget(ContainerView);
QWidget *window(new QWidget);
window->setLayout(VB);
setCentralWidget(window);
}
MainWindow::~MainWindow()
{
}
void MainWindow::startServer()
{
if(!tcpServer->listen(QHostAddress::LocalHost, 6164)){
qDebug() << "Error connecting to Server";
tcpServer->close();
return;
} else {
qDebug() << "Started Successfully";
}
}
void MainWindow::handleConnection()
{
tcpSocket = tcpServer->nextPendingConnection();
qDebug() << "New Connection!";
connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::readMessage);
}
void MainWindow::readMessage()
{
ContainerView->clear(); //clear table to prepare for new XMLString
QByteArray buffer = tcpSocket->readAll();
QString FromContainer = QString::fromUtf8(buffer);
ReadXML(FromContainer);
}
void MainWindow::ReadXML(QString XMLString)
{
ContainerView->append(XMLString);
QDomDocument Xml_String;
Xml_String.setContent(XMLString);
QDomElement Xml_Root = Xml_String.documentElement();
if(Xml_Root.tagName() == "Pallets")
{
QDomElement Xml_Pallet = Xml_Root.firstChildElement();
while(!Xml_Pallet.isNull())
{
if(Xml_Pallet.tagName() == "Pallet")
{
int PN = Xml_Pallet.attribute("Number").toInt(nullptr,10);
QDomElement Box_Cyl = Xml_Pallet.firstChildElement();
while(!Box_Cyl.isNull())
{
if(Box_Cyl.tagName() == "Box")
{
QString BC = Box_Cyl.tagName();
ContainerView->append("Pallet No. " + QString::number(PN) + "\nContainer: " + BC);
// QDomElement Box_Info = Box_Cyl.firstChildElement();
// while(!Box_Info.isNull())
// {
// ...more code
// Box_Info = Box_Info.nextSiblingElement();
// }
} else if(Box_Cyl.tagName() == "Cylinder")
{
QString BC = Box_Cyl.tagName();
ContainerView->append("Pallet No. " + QString::number(PN) + "\nContainer: " + BC);
}
Box_Cyl = Box_Cyl.nextSiblingElement();
}
}
Xml_Pallet = Xml_Pallet.nextSiblingElement();
}
}
}
The XML String I am trying to read is shown below:
When I include the commented code to read the Elements within 'Box' or 'Cylinder' (I altered the code to check both sides), the program freezes.
This hasn't happened to me before, so I have no idea what to do.
I have been facing issues with a simple C++ group project I am working on. I am trying to create a thread that does a background job while my UI and the main app is working perfectly fine. I tried to the same thing on a test file before and it worked fine, however doing it in the Qt Project doesn't works somehow. I do not have much idea about Qt for ref. Here's my code. I am trying to update the progress bar repeatedly till my app runs.
Here's my code for more over view
test code
#include <thread>
#include <iostream>
#include <windows.h>
int getRamUsage() {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.dwMemoryLoad;
}
void ramUsage() {
while (true) {
std::cout << "RAM usage: " << getRamUsage() << "%" << std::endl;
Sleep(1000);
}
}
int main() {
auto ramLoop = [=]() {
while (true) {
std::cout << "RAM usage: " << getRamUsage() << "%" << std::endl;
Sleep(1000);
}
};
std::thread t1(ramLoop);
t1.join();
}
It works, But it doesn't in the Front Ended Qt one I mentioned. May I know any other ideas to make this work.
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "ramUsage.h"
#include <thread>
#include <windows.h>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
auto ramLoop = [=]() {
while (true) {
ui->ramBar->setValue(getRamUsage());
Sleep(1000);
}
};
std::thread t(ramLoop);
t.join();
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp
#include "mainwindow.h"
#include <stdio.h>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
ramUsage.cpp
#include <windows.h>
#include "../ramUsage.h"
int getRamUsage() {
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
return statex.dwMemoryLoad;
}
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
ramUsage.h
#pragma once
#ifndef RAMUSAGE_H
#define RAMUSAGE_H
int getRamUsage();
#endif // RAMUSAGE_H
I tried using QProcess and the basic threading options for windows which doesn't seem to work
Sorry, I use google translator.
I am exploring how QGraphicsItem works.
But I don’t understand how the data is transmitted through the pointers to the scene.
Here is a code
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qmyscene.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QMyScene(this);
ui->graphicsView->setScene(scene);
scene->setSceneRect(0,0,800,600);
}
MainWindow::~MainWindow()
{
delete ui;
}
qmyscene.cpp
#include "qmyscene.h"
#include "qpixitem.h"
#include <qdebug.h>
QMyScene::QMyScene(QObject *parent) : QGraphicsScene(parent)
{
QPixItem *pix1 = new QPixItem (this,100,100);
QPixItem *pix2 = new QPixItem (this,50,50);
}
QMyScene::~QMyScene()
{
}
qpixitem.cpp
#include "qpixitem.h"
#include <QMessageBox>
QPixItem::QPixItem (QGraphicsScene *MyScene,int x,int y): QGraphicsPixmapItem()
{
QPixmap pic (":/Items/OutLet.png");
this->setPixmap(pic);
this->setPos(x, y);
this->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemSendsGeometryChanges);
qDebug() << "create";
QGraphicsLineItem* line = MyScene->addLine(QLineF(40, 40, 80, 80));
MyScene->addItem(this);
}
QVariant QPixItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange)
{
QPointF newPos = value.toPointF();
int p1 = newPos.x();
int p2 = newPos.y();
MyScene->addLine(QLineF(40,40,p1, p2)); //error
//this->line->setLine(QLineF(40,40,p1, p2)); //error
qDebug() << "Scene::move";
}
return QGraphicsItem::itemChange(change, value);
}
qmyscene.h
#ifndef QMYSCENE_H
#define QMYSCENE_H
#include <QGraphicsScene>
#include <QDebug>
class QMyScene: public QGraphicsScene
{
Q_OBJECT
public:
explicit QMyScene(QObject *parent = 0);
~QMyScene();
private:
};
#endif // QMYSCENE_H
qpixitem.h
#ifndef QPIXITEM_H
#define QPIXITEM_H
#include <QGraphicsItem>
#include "QGraphicsScene"
#include "mainwindow.h"
#include <QGraphicsPixmapItem>
class QPixItem: public QGraphicsPixmapItem
{
public:
QPixItem (QGraphicsScene *MyScene,int x,int y);
QGraphicsScene *MyScene;
int x,y;
private:
QGraphicsLineItem* line;
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
};
#endif // QPIXITEM_H
// error - the lines cause an error (closing the program due to memory access), I am sure that this is due to improperly used pointers. How to use them correctly in such code?
You never seem to allocate this->line.
Did you mean:
this->line = MyScene->addLine(QLineF(40, 40, 80, 80));
Instead of
QGraphicsLineItem* line = MyScene->addLine(QLineF(40, 40, 80, 80));
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