转自:http://blog.csdn.net/wusiyuan163/article/details/51107574
最近因为项目的需要,需要在QLabel标签上显示图片。那么问题就来:1.图片如何自适应窗口控件的大小;2.图片如何随着窗口大小的改变而改变呢?这就是两个比较基本也最常见的问题了。
解决问题一:图片如何自适应窗口控件的大小?
相对于第一个问题,最初的想法的就是QLabel用布局进行管理,这样岂不就是固定了QLabel的大小,如何图片岂不也就是固定在QLabel里面,可是后来尝试了这种方法之后就呵呵(实践永远是真理)。虽然QLabel用布局管理了,但是当QLabel加载了图片以后,由于图片的大小问题,QLabel会压缩其他控件的位置,使得整个布局都变得凌乱了。比如下面的代码:
- QLabel *image1Label = new QLabel();
- QLabel *image2Label = new QLabel();
- image1Label->setPixmap(QPixmap::fromImage(img1));
- imgae2Label->setPixmap(QPixmap::fromImage(img2));
实践证明这种简单粗暴的方法是解决不了图片自适应窗口控件大小的问题的。那么既然是由于图片大小问题导致的原因,那在向QLabel加载图片的时候,将图片的大小缩变为QLabel的大小那么解决问题了。这样想是正确,图片缩放到QLabel的大小,那再加载到QLabel中的时候,就不会出现QLabe挤压其他空间的现象了。直接上代码看看:
- QPixmap *img1 = new QPixmap("1.jpg");
- QPixmap *img2 = new QPixmap("2.jpg");
- img1->scaled(image1Label->size(), Qt::KeepAspectRatio);
- img2->scaled(imgae2Label->size(), Qt::KeepAspectRatio);
- image1Label->setPixmap(img1);
- imgae2Label->setPixmap(img2);
解决问题二:如何使得图片的大小随着窗口大小改变而改变呢?
貌似这个问题好像不存在,因为有人会说:你的QLabel不是在布局管理中吗,那么QLabel的大小就可以调整嘛。对的,是这样的,布局中的QLabel是可以随着窗口大小变化而做出相应的变化的。由于我们采用了上面所说的改变图片尺寸的方法来解决问题一的,那么现在就有个新问题了:当QLabel的大小发生变化的时候,我也得重新改变图片的大小,使其适应新的QLabel的大小。是的,思路就是这样的,没啥偏差,那就编码实现看看效果呗。为了能够实现重绘图片的大小,那就得重新实现窗口的resizeEvent虚函数了。这个虚函数是基类QWidget的虚函数,主要是对窗口尺寸变化事件的一个处理。我们需要对这个函数进行重新实现。在相应的头文件中添加下面的代码:
- // rewrite virtual function
- virtual void resizeEvent(QResizeEvent *event);
- void CMViewer::resizeEvent(QResizeEvent *event)
- {
- QWidget::resizeEvent(event);
- QPixmap *img1 = new QPixmap("1.jpg");
- QPixmap *img2 = new QPixmap("2.jpg");
- if (image1Widget->height()>100)
- {
- img1->scaled(image1Label->size(), Qt::KeepAspectRatio);
- image1Label->setPixmap(img1);
- }
- if (image2Widget->height()>100)
- {
- img2->scaled(imgae2Label->size(), Qt::KeepAspectRatio);
- imgae2Label->setPixmap(img2);
- }
- }
--------------------------------------------------------华丽的分割线--------------------------------------------------------------
思想:
1.部署一个QWidget控件,并用布局管理器进行设计;
2.在QWidget控件上放置一个QLabel,不要使用任何布局。
具体操作过程:
1.在要显示的窗口放置一个QWidget,并使用用布局管理器(以便窗口可以规范布局);
2 在QWidget内放置QLabel ,位置为左上角,不使用任何布局管理器;
3 在构造函数内添加如下代码:
- ui->label->setScaledContents(true)
- ui->label->resize(ui->widget->size());
当我们调整窗口使其变化时,paintEvent 函数自动被调用执行,执行 ui->label->resize(ui->widget->size());语句为:设置label大小为widget大小。
而ui->label->setScaledContents(true);为设置QLabel自动缩放,既:显示图像大小自动调整为Qlabel大小。
解释问题:
1 为什么不直接在窗口上显示QLabel而多加一个QWidget?
假如我们直接在窗口上显示QLabel,那么有两种情况:
一、使直接对QLabel使用布局管理器,二、不使用布局管理器。
不使用布局的情况很明显会使窗口布局错乱适应能力着,或者很难获得窗口真实的大小(我用QDockWidget的大小设定时,当窗口锚接入主窗口时种是遮盖图像的一部分)。
第一种情况:直接对QLabel使用布局管理器:那么情况是,打开界面QLabel自动调节为窗口大小,通过拖动使窗口变大后,窗口内有多余的空间后,布局管理器将QLabel自动放大到窗口大小;看似实现了自动适应窗口大小,但当我们想使窗口变小时问题就出来了,窗口无法缩小,原因是布局管理器内的QLabel大小是整个窗口,窗口没已经是最小了。
当使用QWidget做中间介质后,由于QWidget内没有布局管理器,所以当缩小主窗口时其大小可以改变,而QLabel为从QWidget的(0,0)开始绘制,大小为QWidget大小,所以可以实现与窗口同样大小,显示位置也是布局管理器设置的位置。