我必须通过其SDK使用Qt Gui控制摄像头的c + +。照相机由于启动问题需要花费很多时间,并且自从完成后,我的Gui仍然处于冻结状态,所以解决方案 - >线程化。我要检查相机的状态(可以同时手动控制相机),所以线程也是一个好方法。基于此tutorial。线程机制工作正确。但问题是关闭应用程序。我成为ASSERT失败(我猜想是坏内存管理)或“QThread:线程仍在运行时被销毁”有人可以帮我解决这个问题。所以让我们从头开始。这Diagram代表想要的工作流程... 令s在SDK中说,我们有以下要素硬件通信安全地线程关闭c + +和Qt
//from the <SDK_Camera_Types.h>
enum Power
{
on = 0,
off = 1
NA =2; //not Acknowledge
}
struct DeviceSetting
{
public:
bool operational;
unsigned int fieldOfView;
unsigned int focus;
}
和
//from the <SDK_Camera_Device.h>
//to control the camera I use the object from the SDK
Camera_Device myCamera
//and to startup/stop. I use the method
bool myCamera.SetDevicePower(Power status);
// to find the Power status, true if no error
bool myCamera.getDevicePower(Power &status);
//to get the settings. I use the method, true if no error
bool myCamera.getDeviceSettings(DeviceSettings &settings);
,所以这是我的相机对象代码:
// Camera Class
class SDKCamera
{
SDKCamera(){};
~SDKCamera(){};
Camera_Device* myCamera = new Camera_Device();
DeviceSetting settings;
Power powerStatus = NA;
}
之后来了主窗口:
void MyWindow::btnClicked()
{
Power powerNow = NA;
if (on != theCamera.powerStatus)
powerNow = on;
else powerNow = off;
powerControllingThread = new QThread(this);
powerWorker = new PowerControllingWorker(&theCamera,powerNow, &theMutex);
connect(powerControllingThread, SIGNAL(started()), powerWorker, SLOT(startStopCamera()));
connect(powerWorker, SIGNAL(done()), powerControllingThread, SLOT(quit()), Qt::DirectConnection);
// directConnection to emit finished()
connect(powerWorker, SIGNAL(done()), powerWorker, SLOT(deleteLater()));
connect(powerControllingThread, SIGNAL(finished()), powerControllingThread, SLOT(deleteLater()));
connect(powerWorker, SIGNAL(cameraOn()), this, SLOT(startRefresh()));
powerWorker->moveToThread(powerControllingThread);
powerControllingThread->start();
}
void MyWindow::startRefresh()
{
settingsCheckerThread = new QThread(this);
settingsChecker = new SettingsCheckWorker(&theCamera,&theMutex);
connect(settingsCheckerThread , SIGNAL(started()), settingsChecker, SLOT(getCyclicSettings()));
connect(settingsChecker, SIGNAL(done()), settingsCheckerThread , SLOT(quit()), Qt::DirectConnection);
// directConnection to emit finished()
connect(settingsChecker, SIGNAL(done()), settingsChecker, SLOT(deleteLater()));
connect(settingsCheckerThread , SIGNAL(finished()), settingsCheckerThread , SLOT(deleteLater()));
connect(settingsChecker, SIGNAL(refreshed()), this, SLOT(refreshLabels()));
settingsChecker->moveToThread(settingsCheckerThread);
settingsCheckerThread->start();
}
void MyWindow::closeThreads(const int time)
{
if(powerControllingThread)
{
if(!powerControllingThread->wait(time))
powerControllingThread->exit();
}
if(settingsCheckerThread)
{
if(!settingsCheckerThread->wait(time))
settingsCheckerThread->exit();
}
}
void MyWindow::Close()
{
closeThreads(1000);
qApp->exit();
}
相机开始工人插槽如下定义:
void PowerControllingWorker::startStopCamera()
{
lock_guard<mutex> lock((*pmtx));
if(true == camera->SetDevicePower(status))
{
if(true == camera->getDevicePower(camera->powerStatus))
{
if (on == camera->powerStatus) emit cameraOn();
}
}
emit done();
}
但循环工人帽子这样的定义:
void SettingsCheckWorker::getCyclicSettings()
{
while(1)
{
lock_guard<mutex> lock((*pmtx));
if(on == camera->powerStatus)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
if(true == camera->getDevicePower(camera->powerStatus))
{
if (on == camera->powerStatus)
{
if (true ==camera->getDeviceSettings(camera->settings)
emit refreshed();
} else break;
}else break;
}else break;
}
emit done();
}
因此,如果您已经阅读直到这一行首先感谢您的耐心和这里是我的问题,如何关闭Gui并杀死线程,如果它们在运行?我也尝试过使用smart_poiters,但我还没找到正确的方式来使用它们。谢谢
“所以如果你已经阅读,直到这一行..”不,我只是滚动,直到这一行,我认为你应该提供[mcve],因为这只是太多的代码 – user463035818
使用QThreads而不是'std :: thread' 。它们适用于所有QT对象的生命周期。除非你完全知道你在做什么,否则不要使用“DirectConnection”。不要尝试从不由QT管理的线程调用任何QT功能。将您的QObject移动到它们应该居住的线程中。如果需要循环执行,请使用QTimers。 – Ext3h
@ tobi303好的,谢谢我会尝试!但我怎样才能清楚地解释第三方图书馆? –