一文了解如何在Qt中间集成Halcon窗口并在子线程显示(附工程源码下载链接)

发布于:2025-02-10 ⋅ 阅读:(174) ⋅ 点赞:(0)

在基于图像处理的开发中,Halcon作为功能强大的图像处理库,经常需要与Qt结合,以便通过Qt提供的UI功能更好地显示和交互。本文将讲解如何在Qt中集成Halcon窗口,并通过子线程实现Halcon图像的显示,保证主线程的流畅运行。


工程代码下载链接

通过网盘分享的文件:HALCON窗口依附Qt控件
链接: https://pan.baidu.com/s/1gNWCTpha9-vsYPHEX0R_vQ?pwd=jkcf 提取码: jkcf

在这里插入图片描述

一、Halcon窗口与Qt控件的结合原理

在Qt中,QGraphicsView等控件用于显示图像。而Halcon可以通过窗口句柄将其窗口嵌入到Qt控件中。通过将Halcon窗口与Qt控件绑定,我们既能使用Qt的交互功能,又能发挥Halcon的强大图像处理能力。为了提升程序性能,Halcon窗口的操作可以放到子线程中执行,避免阻塞主线程。


二、项目初始化与Halcon库的配置

在Qt中使用Halcon库时,首先需要配置.pro文件,添加Halcon库的路径:

1. 修改.pro文件

# 配置头文件路径
INCLUDEPATH += "./libary/hdevelop/include"
INCLUDEPATH += "./libary/hdevelop/include/halconcpp"

# 配置库文件路径
LIBS += "./libary/hdevelop/lib/halconcpp.lib"

其中:

  • INCLUDEPATH 指定 Halcon 头文件的路径。
  • LIBS 指定 Halcon 动态库的路径。

2. 全局窗口句柄声明

为了管理Halcon窗口,声明一个全局变量:

#include "HalconCpp.h"

HalconCpp::HTuple m_window; // 全局窗口句柄

三、分离线程逻辑:创建一个线程类

在复杂的程序中,将线程逻辑独立出来是一种更好的设计方式。我们通过创建一个专门的线程类,处理Halcon图像的显示逻辑。

1. 线程类定义

新建线程类 ThreadedWorker,继承自 QThread

ThreadedWorker.h
#ifndef THREADEDWORKER_H
#define THREADEDWORKER_H

#include <QThread>
#include "HalconCpp.h"

class ThreadedWorker : public QThread
{
    Q_OBJECT

public:
    explicit ThreadedWorker(HalconCpp::HTuple window, QObject* parent = nullptr);
    ~ThreadedWorker();

protected:
    void run() override;

private:
    HalconCpp::HTuple m_window; // Halcon窗口句柄
};

#endif // THREADEDWORKER_H
ThreadedWorker.cpp
#include "ThreadedWorker.h"

ThreadedWorker::ThreadedWorker(HalconCpp::HTuple window, QObject* parent)
    : QThread(parent), m_window(window)
{
}

ThreadedWorker::~ThreadedWorker()
{
    if (isRunning()) {
        quit();
        wait();
    }
}

void ThreadedWorker::run()
{
    try {
        // 设置Halcon窗口的显示区域
        HalconCpp::SetPart(m_window, 0, 0, 1023, 1023);

        // 清空窗口并显示图像
        HalconCpp::ClearWindow(m_window);

        HalconCpp::HObject hv_Image;
        HalconCpp::GenImageConst(&hv_Image, "byte", 1024, 1024); // 生成测试图像
        HalconCpp::DispObj(hv_Image, m_window); // 在窗口中显示图像
    } catch (HalconCpp::HException& ex) {
        qWarning("Halcon exception: %s", ex.ErrorText().Text());
    }
}
  • run() 是线程的主函数,负责设置Halcon窗口并显示图像。
  • Halcon操作(如 SetPartClearWindowDispObj)都集中在此线程中,避免阻塞主线程。

四、主窗口中调用线程类

在主窗口类中,我们完成Halcon窗口的初始化,并创建和启动线程。

1. 主窗口类定义

MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "HalconCpp.h"
#include "ThreadedWorker.h"

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;
    HalconCpp::HTuple m_window; // Halcon窗口句柄
    ThreadedWorker* worker;    // 线程对象
};

#endif // MAINWINDOW_H

2. 主窗口实现

MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 初始化Halcon窗口
    HalconCpp::OpenWindow(0, 0, 500, 500, static_cast<Hlong>(ui->graphicsView->winId()), "", "", &m_window);
    HalconCpp::SetColored(m_window, 12); // 设置窗口颜色
    HalconCpp::SetHcppInterfaceStringEncodingIsUtf8(true); // 启用UTF-8编码

    // 创建线程对象
    worker = new ThreadedWorker(m_window, this);

    // 启动线程
    worker->start();
}

MainWindow::~MainWindow()
{
    // 关闭线程
    if (worker) {
        worker->quit();
        worker->wait();
        delete worker;
    }

    delete ui;
}

五、运行效果

  1. 主线程的职责

    • 初始化Halcon窗口,将其与QGraphicsView控件绑定。
    • 创建并启动线程对象。
  2. 子线程的职责

    • 设置Halcon窗口的显示区域。
    • 在Halcon窗口中显示测试图像。

运行程序后,Halcon窗口会嵌入到Qt的GraphicsView控件中,显示测试图像,同时主线程保持流畅运行。


六、设计优点

  1. 解耦性
    将线程逻辑与主窗口分离,使代码结构清晰,易于维护和扩展。

  2. 性能优化
    通过子线程执行Halcon操作,避免阻塞主线程,提高UI的响应速度。

  3. 易于扩展
    若需增加其他图像处理功能,可直接在 ThreadedWorker 类中添加,不影响主窗口逻辑。



网站公告

今日签到

点亮在社区的每一天
去签到