C++ Qt Gui线程存在阻塞问题
我是初级程序员 最近,我使用Halcon库实现了图像抓取 当我按下live按钮时,计时器开始抓取图像。它工作,但主屏幕冻结到计时器周期 所以,我正在改进使用线程的图像抓取性能 首先,我实现了如下线程C++ Qt Gui线程存在阻塞问题,c++,qt,halcon,C++,Qt,Halcon,我是初级程序员 最近,我使用Halcon库实现了图像抓取 当我按下live按钮时,计时器开始抓取图像。它工作,但主屏幕冻结到计时器周期 所以,我正在改进使用线程的图像抓取性能 首先,我实现了如下线程 m_pThread = new QThread(); m_pUpdateWorker = new ImageUpdateWorker(nullptr, strName); m_pUpdateWorker->moveToThread(m_pThread); // Upda
m_pThread = new QThread();
m_pUpdateWorker = new ImageUpdateWorker(nullptr, strName);
m_pUpdateWorker->moveToThread(m_pThread); // UpdateWorker move to Thread
connect(m_pThread, SIGNAL(started()), m_pUpdateWorker, SLOT(run()));
connect(m_pThread, SIGNAL(finished()), m_pThread, SLOT(deleteLater()));
connect(m_pUpdateWorker, SIGNAL(finished()), m_pThread, SLOT(quit()));
connect(m_pUpdateWorker, SIGNAL(finished()), m_pUpdateWorker, SLOT(deleteLater()));
connect(m_pUpdateWorker, SIGNAL(grab()), this, SLOT(onGrab()));
[ImageUpdateWorker.h]
class ImageUpdateWorker : public QObject
{
Q_OBJECT
public:
explicit ImageUpdateWorker(QObject* parent = 0, QString strThreadName = "ImageUpdateWorker");
~ImageUpdateWorker();
signals:
void finished();
void grab();
public slots:
void run();
private:
bool m_bStop{ false };
};
[ImageUpdateWorker.cpp]
ImageUpdateWorker::ImageUpdateWorker(QObject* parent, QString strThreadName)
: QObject(parent)
{
setObjectName(strThreadName);
}
ImageUpdateWorker::~ImageUpdateWorker()
{
}
void ImageUpdateWorker::run()
{
while (m_bStop == false)
{
emit grab();
}
emit finished();
}
第二,我实现了继承的QWidget UI小部件,输出屏幕如下
m_pThread = new QThread();
m_pUpdateWorker = new ImageUpdateWorker(nullptr, strName);
m_pUpdateWorker->moveToThread(m_pThread); // UpdateWorker move to Thread
connect(m_pThread, SIGNAL(started()), m_pUpdateWorker, SLOT(run()));
connect(m_pThread, SIGNAL(finished()), m_pThread, SLOT(deleteLater()));
connect(m_pUpdateWorker, SIGNAL(finished()), m_pThread, SLOT(quit()));
connect(m_pUpdateWorker, SIGNAL(finished()), m_pUpdateWorker, SLOT(deleteLater()));
connect(m_pUpdateWorker, SIGNAL(grab()), this, SLOT(onGrab()));
当我调用“m_pThread->start();”时,屏幕开始出现阻塞:(
如果您有任何建议或信息,我将不胜感激。谢谢您的阅读。我在QT中不知道。
我把我在C#中使用的代码发给你了
如果不想冻结GUI,则必须使用委托
hdisplay是对象HalconDotNet:HWindowControlWPF
camera是我定义相机参数的类
摄像头内。抓取有代码:
HOperatorSet.GrabImage(out ho_Image, _AcqHandle);
h_Image = new HImage(ho_Image);
// Initialise the delegate
updateLiveDelegate = new UpdateLiveDelegate(this.UpdateLive);
HImage ho_Image = new HImage();
初始化时有以下代码:
HOperatorSet.GrabImage(out ho_Image, _AcqHandle);
h_Image = new HImage(ho_Image);
// Initialise the delegate
updateLiveDelegate = new UpdateLiveDelegate(this.UpdateLive);
HImage ho_Image = new HImage();
下面是我使用的代码:
// ==================
// LIVE
// ==================
bool stopLive = true;
// Declare the thread
private Thread liveThread = null;
// Declare a delegate used to communicate with the UI thread
private delegate void UpdateLiveDelegate();
private UpdateLiveDelegate updateLiveDelegate = null;
private void btnLive_Click(object sender, RoutedEventArgs e)
{
try
{
stopLive = !stopLive;
// if stopLive = false, live camera is activated
if (!stopLive)
{
// Launch the thread
liveThread = new Thread(new ThreadStart(Live));
liveThread.Start();
}
}
catch (Exception ex)
{
// Error
}
}
private void Live()
{
try
{
while (stopLive == false)
{
if (camera.Grab(out ho_Image))
{
// Show progress
Dispatcher.Invoke(this.updateLiveDelegate);
}
else
{
// No grab
stopLive = true;
}
}
// here stopLive is true
}
catch (Exception ex)
{
// Error
}
}
private void UpdateLive()
{
try
{
int imageHeight;
int imageWidth;
string imageType;
ho_Image.GetImagePointer1(out imageType, out imageWidth, out imageHeight);
hDisplay.HalconWindow.SetPart(0, 0, imageHeight - 1, imageWidth - 1);
// display
hDisplay.HalconWindow.DispImage(ho_Image);
}
catch (Exception ex)
{
// Error
}
}
使用m_pImageUpdateThread->moveToThread(m_pThread)调用
process
时,grab
发出多少次?我不知道确切的计数。有一件事是grab发出这么多次。@JarManRight,我不需要确切的数字。但这几乎肯定会导致在循环中发出信号的方式出现问题。为什么它需要发出这么多次呢频繁地?当我添加sleep in而循环冻结没有修复时。我不知道为什么抓取被冻结。如何调用进程
?void ImageUpdateWorker::run()在循环中发出信号,只是溢出事件队列(使用排队连接)。添加一些sleep()或仅在接收到下一帧抓取后才发出抓取。