我写的一个 Qt 显示图片的控件

本文介绍了一个自定义的Qt图片展示控件,支持三种显示模式:FIXED_SIZE、FIX_SIZE_CENTRED、AUTO_ZOOM与AUTO_SIZE。详细解释了各模式的实现原理及代码示例,并提供了实际应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Qt 中没有专门显示图片的控件,通常我们会使用QLabel来显示图片。但是QLabel 显示图片的能力还是有点弱。比如不支持图像的缩放一类的功能,使用起来不是很方便。因此我就自己写了个简单的类。

 

我这个类支持三种图像显示模式,我分别称之为:FIXED_SIZE, CENTRED,AUTO_ZOOM, AUTO_SIZE

  • FIXED_SIZE 模式下,显示的图像大小等于图像尺寸乘以缩放因子,如果控件的尺寸小于这个大小则多出的部分被裁切掉。
  • FIX_SIZE_CENTRED模式与FIXED_SIZE 模式类似,但是,显示的图像居于窗口正中。
  • AUTO_ZOOM 模式下,显示的图像大小自动适应控件窗口大小。
  • AUTO_SIZE 模式下,这个控件的尺寸等于图像尺寸乘以缩放因子。

下面是代码:

#ifndef PICTUREBOX_H
#define PICTUREBOX_H

#include <QWidget>
#include <QImage>
#include <QPixmap>


class PictureBox : public QWidget
{    
    Q_OBJECT
public:
    enum PB_MODE {FIXED_SIZE, FIX_SIZE_CENTRED, AUTO_ZOOM, AUTO_SIZE};
    explicit PictureBox(QWidget *parent = 0);
    void setMode(PB_MODE mode);
    ~PictureBox();
private:
    QPixmap m_pixmap;
    double m_scale;
    PB_MODE m_mode;
    QBrush m_brush;
protected:
    void paintEvent(QPaintEvent * event);
signals:

public slots:
    bool setImage(QImage &image, double scale = 1.0);
    void setBackground(QBrush brush);
};

#endif // PICTUREBOX_H

#include "picturebox.h"
#include <QPainter>
#include <QDebug>
static const int IMAGE_WIDTH = 160;
static const int IMAGE_HEIGHT = 120;
static const QSize IMAGE_SIZE = QSize(IMAGE_WIDTH, IMAGE_HEIGHT);

PictureBox::PictureBox(QWidget *parent) : QWidget(parent)
{
    m_pixmap = QPixmap(IMAGE_SIZE);
    m_pixmap.fill();
    m_scale = 1.0;
    m_mode = FIXED_SIZE;
    m_brush = QBrush(Qt::white);
}

void PictureBox::setBackground(QBrush brush)
{
    m_brush = brush;
    update();
}

void PictureBox::setMode(PB_MODE mode)
{
    m_mode = mode;
    if(m_mode == AUTO_SIZE)
    {
        setFixedSize(m_pixmap.size() * m_scale);
    }
    else
    {
        setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
        setMinimumSize(0, 0);
    }
    update();
}

bool PictureBox::setImage(QImage &image, double scale)
{
    if(image.isNull())
    {
        return false;
    }
    m_pixmap = QPixmap::fromImage(image);
    m_scale = qBound(0.01, scale, 100.0);
    if(m_mode == AUTO_SIZE)
    {
        setFixedSize(m_pixmap.size() * m_scale);
    }
    update();
    return true;
}

void PictureBox::paintEvent(QPaintEvent * event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setBackground(m_brush);
    painter.eraseRect(rect());

    double window_width, window_height;
    double image_width, image_height;
    double r1, r2, r;
    int offset_x, offset_y;
    switch (m_mode)
    {
    case FIXED_SIZE:
    case AUTO_SIZE:
        painter.scale(m_scale, m_scale);
        painter.drawPixmap(0, 0, m_pixmap);
        break;
    case FIX_SIZE_CENTRED:
        window_width = width();
        window_height = height();
        image_width = m_pixmap.width();
        image_height = m_pixmap.height();
        offset_x = (window_width - m_scale * image_width) / 2;
        offset_y = (window_height - m_scale * image_height) / 2;
        painter.translate(offset_x, offset_y);
        painter.scale(m_scale, m_scale);
        painter.drawPixmap(0, 0, m_pixmap);
        break;
    case AUTO_ZOOM:
        window_width = width();
        window_height = height();
        image_width = m_pixmap.width();
        image_height = m_pixmap.height();
        r1 = window_width / image_width;
        r2 = window_height / image_height;
        r = qMin(r1, r2);
        offset_x = (window_width - r * image_width) / 2;
        offset_y = (window_height - r * image_height) / 2;
        painter.translate(offset_x, offset_y);
        painter.scale(r, r);
        painter.drawPixmap(0, 0, m_pixmap);
        break;
    }
}

PictureBox::~PictureBox()
{

}

AUTO_ZOOM 模式下显示例子如下:


FIXED_SIZE 模式下的例子如下:


FIX_SIZE_CENTRED 模式下的例子如下:




<think>嗯,用户想了解如何在Qt控件中绑定Halcon窗口来显示图像。我得先回忆一下Qt和Halcon的结合方式。记得Halcon提供了HWindow控件,但Qt中需要将其嵌入到QWidget里。可能需要通过Halcon的库函数将窗口句柄绑定到Qt的某个容器上。 首先,用户需要一个示例,所以结构要清晰。步骤可能包括创建Qt项目、添加必要的头文件和库、初始化Halcon窗口、图像读取与显示等。需要注意的是跨平台的问题,比如Windows和Linux下获取窗口句柄的方法不同,可能需要条件编译。 然后,考虑代码的正确性。比如在Qt中,可能需要使用QWIDGET_HWND来获取原生句柄,特别是Windows环境下。Halcon的部分,应该用OpenWindow来绑定到Qt的widget上,然后使用DispObj显示图像。同时,资源管理方面,确保在关闭窗口时释放Halcon对象,避免内存泄漏。 用户可能遇到的问题包括窗口句柄获取不正确,或者图像显示不出来。这时候需要检查Halcon的错误信息,确保图像路径正确,以及Halcon的库是否正确链接。此外,Qt的布局管理也需要正确设置,确保Halcon窗口所在的QWidget有合适的大小。 最后,示例代码要简洁,关键部分加上注释,说明每一步的作用。可能需要分步骤讲解,从创建Qt窗口到绑定Halcon控件,再到加载和显示图像,以及清理资源。还要提醒用户根据实际环境调整库的路径和包含目录。</think>以下是一个基于Qt和Halcon实现控件绑定并显示图像的示例代码(分步骤说明): ```cpp // 步骤1:创建Qt窗口并添加容器控件 #include <QWidget> #include <QLabel> #include "HalconCpp.h" class HWindowWidget : public QWidget { Q_OBJECT public: explicit HWindowWidget(QWidget *parent = nullptr) : QWidget(parent) { // 设置固定尺寸或使用布局管理器 setFixedSize(640, 480); } // 步骤2:获取窗口句柄并绑定Halcon窗口 void initHalconWindow() { // Windows系统获取句柄方式 #if defined(_WIN32) || defined(_WIN64) HWND hwnd = (HWND)this->winId(); HalconCpp::SetWindowAttr("background_color","black"); m_HalconWindow.OpenWindow(0, 0, width(), height(), (Hlong)hwnd, "visible", ""); #else // Linux系统 Window winId = (Window)this->winId(); m_HalconWindow.OpenWindow(0, 0, width(), height(), winId, "visible", ""); #endif } // 步骤3:显示图像 void displayImage(const QString &imagePath) { try { // 读取图像 HalconCpp::HObject ho_Image; HalconCpp::ReadImage(&ho_Image, imagePath.toStdString().c_str()); // 显示图像 m_HalconWindow.DispObj(ho_Image); } catch (HalconCpp::HException &e) { qDebug() << "Halcon Error:" << e.ErrorMessage().Text(); } } private: HalconCpp::HWindow m_HalconWindow; // Halcon窗口对象 }; // 步骤4:在Qt主窗口中使用 int main(int argc, char *argv[]) { QApplication a(argc, argv); QMainWindow mainWindow; // 创建Halcon窗口容器 HWindowWidget *hWindow = new HWindowWidget(&mainWindow); mainWindow.setCentralWidget(hWindow); // 初始化Halcon窗口 hWindow->initHalconWindow(); // 加载并显示图像 hWindow->displayImage("example.jpg"); mainWindow.show(); return a.exec(); } ``` 关键要点说明: 1. **窗口绑定原理**: - 使用Qt的`winId()`获取原生窗口句柄 - 通过Halcon的`OpenWindow`函数将窗口绑定到Qt容器 - 需注意Windows/Linux的跨平台处理 2. **内存管理**: - 在析构函数中应添加`m_HalconWindow.CloseWindow();` - 使用Halcon异常处理避免崩溃 3. **扩展功能**: ```cpp // 可添加图像交互功能 void HWindowWidget::mousePressEvent(QMouseEvent *event) { HTuple row, column; m_HalconWindow.GetMposition(&row, &column, nullptr); qDebug() << "Clicked at:" << row.D() << column.D(); } ``` 4. **项目配置**: - 需在.pro文件中添加Halcon库路径: ```makefile INCLUDEPATH += /usr/local/halcon/include LIBS += -L/usr/local/halcon/lib -lhalconcpp ``` 注意事项: 1. 确保Halcon运行时库已正确部署 2. 图像路径使用绝对路径更可靠 3. 建议使用Halcon 18.11及以上版本 4. 处理窗口大小变化时需要重置Halcon窗口视口 可通过`HWindow::SetPart()`调整显示区域,或使用`HWindow::SetColor()`修改绘图颜色实现更多交互功能。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值