您的当前位置:首页正文

QT学习笔记(五)——打开两个DockWidget窗口同时显示两张影像

2024-11-07 来源:个人技术集锦

开两个DockWidget窗口分别显示一张影像

在前面的基础上,做一些改变
首先在项目头文件里,之前定义的变量都要变成双份

//h
private:
    Ui::hqMchClass ui;
    QDockWidget* dock_Image1;//图像窗口1
    QDockWidget* dock_Image2;//图像窗口2
    myLabel* imgLabel1;//图像显示框1
    myLabel* imgLabel2;//图像显示框2
    QImage m_image1;//两张影像
    QImage m_image2;
    QScrollArea* scrollArea1;
    QScrollArea* scrollArea2;
    QString currentPath1;//当前图像的路径
    QString currentPath2;//当前图像的路径

    void Menu_File();//文件菜单
    void InitImage();//初始化
    void wheelEvent(QWheelEvent* event);//鼠标滚轮实现放大缩小

在.cpp文件中,重点是修改以下几个函数,部分函数省略,这里只记录几个重要的点

//cpp
void hqMch::InitImage()    // 初始化图像Label
{
    ……
    dock_Image1 = new QDockWidget(tr("图像1"), this);
    dock_Image2 = new QDockWidget(tr("图像2"), this);

    //setCentralWidget(dock_Image1);
    dock_Image1->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    dock_Image1->setFeatures(QDockWidget::DockWidgetMovable);
    addDockWidget(Qt::LeftDockWidgetArea, dock_Image1);
    dock_Image2->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    dock_Image1->setFeatures(QDockWidget::DockWidgetMovable);
    addDockWidget(Qt::RightDockWidgetArea, dock_Image2);

    imgLabel1 = new myLabel(dock_Image1);
    imgLabel2 = new myLabel(dock_Image2);

    QImage image = QImage(500, 500, QImage::Format_RGB32);  // 新建图像
    image.fill(qRgb(255, 255, 255));         // 全白

    imgLabel1->setPixmap(QPixmap::fromImage(image));         // 显示图像
    imgLabel1->resize(image.width(), image.height());        // 图像与imgLabel同大小
    imgLabel1->setScaledContents(true);  // 设置QLabel自动适应图像大小
    imgLabel2->setPixmap(QPixmap::fromImage(image));         // 显示图像
    imgLabel2->resize(image.width(), image.height());        // 图像与imgLabel同大小
    imgLabel2->setScaledContents(true);  // 设置QLabel自动适应图像大小

    m_image1 = image.copy();
    m_image2 = image.copy();

    //imgLabel->setGeometry(0, 20, image.width(), image.height());
    //增加滚动条,如果图像比imgLabel大,就会出现滚动条
    scrollArea1 = new QScrollArea(this);
    scrollArea1->setBackgroundRole(QPalette::Dark);
    scrollArea1->setAlignment(Qt::AlignCenter);
    scrollArea1->setWidget(imgLabel1);
    dock_Image1->setWidget(scrollArea1);

    scrollArea2 = new QScrollArea(this);
    scrollArea2->setBackgroundRole(QPalette::Dark);
    scrollArea2->setAlignment(Qt::AlignCenter);
    scrollArea2->setWidget(imgLabel2);
    dock_Image2->setWidget(scrollArea2);
}

在鼠标滚轮控制放大缩小的函数里,需要注意的是,鼠标在哪个dockWidget就要让那个窗口的图像缩放,所以需要多加一个判断条件

void hqMch::wheelEvent(QWheelEvent* event) {//鼠标滚轮实现放大缩小
    QRect scrollGeo1 = scrollArea1->geometry();
    QRect scrollGeo2 = scrollArea2->geometry();
    QPoint pos = event->pos();//得到当前鼠标在窗口的位置
    QPoint posscroll1 = pos; 
    posscroll1.setX(pos.x() - dock_Image1->geometry().x());    posscroll1.setY(pos.y() - dock_Image1->geometry().y());
    QPoint posscroll2 = pos;
    posscroll2.setX(pos.x() - dock_Image2->geometry().x());    posscroll2.setY(pos.y() - dock_Image2->geometry().y());
    int dockWin_pos = scrollArea1->geometry().y() + dock_Image1->geometry().y();
    if (scrollGeo1.contains(posscroll1)) {
        QScrollBar* tmph = scrollArea1->horizontalScrollBar();
        QScrollBar* tmpv = scrollArea1->verticalScrollBar();
        
        QRect tmplab = imgLabel1->geometry();//获得imglabel的位置

        int th = pos.x() - tmplab.x();
        int tv = pos.y() - tmplab.y() - dockWin_pos;//缩放前鼠标点在label中的坐标,这里的79是窗体标题的高度

        imgLabel1->setPixmap(QPixmap::fromImage(m_image1));      // 这一句是为了防止自适应窗口之后进行放缩图像分辨率变低,所以label重新加载原始影像
        double ratio = (double)m_image1.height() / (double)m_image1.width();//图像的比例
        QPoint numDegrees;                                     // 定义指针类型参数numDegrees用于获取滚轮转角
        numDegrees = event->angleDelta();                      // 获取滚轮转角
        int step = 0;                                          // 设置中间参数step用于将获取的数值转换成整数型
        if (!numDegrees.isNull())                              // 判断滚轮是否转动
        {
            step = numDegrees.y();                             // 将滚轮转动数值传给中间参数step
        }
        event->accept();                                       // 获取事件
        int currentWidth = imgLabel1->width();                  // 获取当前图像的宽
        int currentHeight = imgLabel1->height();                // 获取当前图像的高

        double stepr = (double)(step) / (double)(currentWidth);  //   (1.0+stepr)为放缩比例=r

        currentWidth += step;                                    // 对当前图像的高累加
        currentHeight = (int)(currentWidth * ratio+0.5);                    // 对当前图像的宽累加(四舍五入)

        double r = (double)currentWidth / (double)m_image1.width();//始终计算相对于原影像的放缩比例,用来计算所画点放缩后的坐标
        

        if (step > 0)                                          // 判断图像是放大还是缩小
        {
            QString imgsize = QString("图像放大,尺寸为:%1 * %2")
                .arg(currentWidth).arg(currentHeight);
            qDebug() << imgsize;                               // 打印放大后的图像尺寸
        }
        else
        {
            QString imgsize = QString("图像缩小,尺寸为:%1 * %2")
                .arg(currentWidth).arg(currentHeight);
            qDebug() << imgsize;                                // 打印缩小后的图像尺寸
        }
        imgLabel1->resize(currentWidth, currentHeight);          // 通过更新图像显示控件的大小来更新图像大小

        int move_x = stepr * th + 0.5;
        int move_y = stepr * tv + 0.5;

        tmph->setValue(tmph->value() + move_x);
        tmpv->setValue(tmpv->value() + move_y);
    }
    
    else if (scrollGeo2.contains(posscroll2)) {
        QScrollBar* tmph = scrollArea2->horizontalScrollBar();
        QScrollBar* tmpv = scrollArea2->verticalScrollBar();

        QRect tmplab = imgLabel2->geometry();//获得imglabel的位置

        int th = pos.x() - tmplab.x()-dock_Image2->geometry().x();
        int tv = pos.y() - tmplab.y() - dockWin_pos;//缩放前鼠标点在label中的坐标,这里的79是窗体标题的高度

        imgLabel2->setPixmap(QPixmap::fromImage(m_image2));      // 这一句是为了防止自适应窗口之后进行放缩图像分辨率变低,所以label重新加载原始影像
        double ratio = (double)m_image2.height() / (double)m_image2.width();//图像的比例
        QPoint numDegrees;                                     // 定义指针类型参数numDegrees用于获取滚轮转角
        numDegrees = event->angleDelta();                      // 获取滚轮转角
        int step = 0;                                          // 设置中间参数step用于将获取的数值转换成整数型
        if (!numDegrees.isNull())                              // 判断滚轮是否转动
        {
            step = numDegrees.y();                             // 将滚轮转动数值传给中间参数step
        }
        event->accept();                                       // 获取事件
        int currentWidth = imgLabel2->width();                  // 获取当前图像的宽
        int currentHeight = imgLabel2->height();                // 获取当前图像的高

        double stepr = (double)(step) / (double)(currentWidth);  //   (1.0+stepr)为放缩比例=r

        currentWidth += step;                                  // 对当前图像的高累加
        currentHeight = (int)(currentWidth * ratio + 0.5);                    // 对当前图像的宽累加(四舍五入)

        double r = (double)currentWidth / (double)m_image2.width();//始终计算相对于原影像的放缩比例,用来计算所画点放缩后的坐标

        if (step > 0)                                          // 判断图像是放大还是缩小
        {
            QString imgsize = QString("图像2放大,尺寸为:%1 * %2")
                .arg(currentWidth).arg(currentHeight);
            qDebug() << imgsize;                               // 打印放大后的图像尺寸
        }
        else
        {
            QString imgsize = QString("图像2缩小,尺寸为:%1 * %2")
                .arg(currentWidth).arg(currentHeight);
            qDebug() << imgsize;                                // 打印缩小后的图像尺寸
        }
        imgLabel2->resize(currentWidth, currentHeight);          // 通过更新图像显示控件的大小来更新图像大小

        int move_x = stepr * th + 0.5;
        int move_y = stepr * tv + 0.5;

        tmph->setValue(tmph->value() + move_x);
        tmpv->setValue(tmpv->value() + move_y);
        
    }
}

其他地方改起来基本上都比较简单,就不再详细写了
运行效果:

显示全文