QLabel实现自适应图片大小(可鼠标右击全屏)

QLabel实现自适应图片大小(可鼠标右击全屏)

引言:首先说下走的弯路,按照固定思维QLabel外面套个QWidget,然后点击布局,让QLabel随着QWidget一起变化,理论上没啥问题,但是实践后,QLabel加载图片进行放大后,QLabel会填充整个widget,无法缩小。所以:

 QLabel不要使用布局管理器!!!!
一、修改构造函数
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->VideoShowLabel->setScaledContents(true); //图片自适应label大小
}

setScaledContents是让图片自适应label大小

二、重写resizeEvent函数

当调整窗口使其变化时,paintEvent 函数自动被调用执行,所以重绘label大小(这看起来是不是和 setScaledContents重复了,后续再进行解释)

void Widget::resizeEvent(QResizeEvent *event)
{
    ui->VideoShowLabel->resize(ui->widget->size());
}
三、显示图片

我这里是结合opencv获取图片,qt获取图片使用QImage和QPixmap即可

void Widget::OnUpdateFrame()
{
    int frameSize_, width, height;
    char *image_ = pHdev->getLatestFrame(m_camID,frameSize_,width,height);

    cv::Mat image;
    if (image_ != NULL)
    {
      	 cudaMemcpy(m_pImagedate, image_, frameSize_, cudaMemcpyDeviceToHost);
       	cv::Mat srcImg(height, width, CV_8UC4, m_pImagedate, cv::Mat::AUTO_STEP);
       	cv::cvtColor(srcImg, image, cv::COLOR_BGRA2BGR);

        cv::line(image,cv::Point(0,image.rows/2),cv::Point(image.cols,image.rows/2),cv::Scalar(255,0,0),1);
        cv::line(image,cv::Point(image.cols/2,0),cv::Point(image.cols/2,image.rows),cv::Scalar(255,0,0),1);
    }
    
    if(ui->VideoShowLabel->isFullScreen())
    {
        cv::resize(image, image,cv::Size(ui->VideoShowLabel->width(), ui->VideoShowLabel->height()));
    }
    else
    {
        cv::resize(image,image,cv::Size(1280,960));
    }

    //获取img
    QImage img = QImage((const uchar *)image.data, image.cols, image.rows,
    image.cols * image.channels(), QImage::Format_RGB888);
    QPixmap pixImage = QPixmap::fromImage(img.rgbSwapped());

    //显示图像
    ui->VideoShowLabel->setPixmap(pixImage);
    ui->VideoShowLabel->resize(QSize(pixImage.width(), pixImage.height()));
    this->update();
}
四、实现鼠标右击全屏和恢复(实现eventFilter即可)
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == ui->VideoShowLabel)
    {
       if(event->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
            if(mouseEvent->button() == Qt::RightButton)
            {
                ui->VideoShowLabel->setWindowFlags(Qt::Window);
                ui->VideoShowLabel->showFullScreen();
            }
            else if(mouseEvent->button() == Qt::LeftButton)
            {
                ui->VideoShowLabel->setWindowFlags(Qt::SubWindow);
                ui->VideoShowLabel->showNormal();
            }
        }
        return QObject::eventFilter(watched,event);
    }
}
总结:核心思想就是添加QWiget并进行布局,QWidget控件添加QLabel不使用布局!

问题:(链接:https://blog.csdn.net/emdfans/article/details/52936637

为什么不直接在窗口上显示QLabel而多加一个QWidget?
假如我们直接在窗口上显示QLabel,那么有两种情况:
一、使直接对QLabel使用布局管理器,二、不使用布局管理器。

不使用布局的情况很明显会使窗口布局错乱适应能力着,或者很难获得窗口真实的大小(我用QDockWidget的大小设定时,当窗口锚接入主窗口时种是遮盖图像的一部分)。

第一种情况:直接对QLabel使用布局管理器:那么情况是,打开界面QLabel自动调节为窗口大小,通过拖动使窗口变大后,窗口内有多余的空间后,布局管理器将QLabel自动放大到窗口大小;看似实现了自动适应窗口大小,但当我们想使窗口变小时问题就出来了,窗口无法缩小,原因是布局管理器内的QLabel大小是整个窗口,窗口没已经是最小了。

当使用QWidget做中间介质后,由于QWidget内没有布局管理器,所以当缩小主窗口时其大小可以改变,而QLabel为从QWidget的(0,0)开始绘制,大小为QWidget大小,所以可以实现与窗口同样大小,显示位置也是布局管理器设置的位置。

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值