【问题标题】:QLabel showing an image inside a QScrollAreaQLabel 在 QScrollArea 内显示图像
【发布时间】:2012-06-14 10:48:04
【问题描述】:

我已经在 Qt 中成功实现了一个图像查看器(用于 DICOM)。 我可以看到图像并且可以正确放大和缩小。

现在,如果图像太大而无法在放大时显示,我想查看滚动条。

我已经使用了 UI。我放置了一个QScrollArea。在里面,QLabelverticalScrollBarPolicyScrollBarAsNeededhorizo​​ntalScrollBarPolicyScrollBarAsNeeded

问题是:它不起作用。我放大了,但没有出现滚动条。

第二次尝试:使用 QScrollArea 内的布局。

所以现在在 QScrollArea 和 QLabel 之间有一个 QWidget:水平布局。 打开相同的图像,现在我可以在右侧看到一个垂直滚动条。图像从左到右拉伸。当我缩放图像时,它会得到正确的比例。

但是...我缩小并且滚动条是相同的,即使我可以看到整个图像。水平滚动条永远不会出现。

调整 QLabel 的大小似乎没有影响。但是,如果我调整 QScrollArea 的大小(调整主窗口的大小),就会出现水平滚动条。

我一直在检查一些数字:

在 QScrollArea 中

  • 它的大小发生变化:宽度低于 599(为什么是这个数字?我在任何地方都看不到它)出现水平条。
  • sizeHint() 总是返回相同的值:33x41

在 QLabel 中

  • 尺寸发生变化,但这不影响。
  • sizeHint() 总是返回相同的值:560x1558

这是来自 UI 设计器的 XML 代码:

<widget class="QWidget" name="centralWidget">
   <property name="autoFillBackground">
    <bool>false</bool>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <property name="margin">
     <number>0</number>
    </property>
    <item>
     <widget class="QScrollArea" name="scrollArea">
      <property name="widgetResizable">
       <bool>true</bool>
      </property>
      <property name="alignment">
       <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
      </property>
      <widget class="QWidget" name="scrollAreaWidgetContents">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>637</width>
         <height>649</height>
        </rect>
       </property>
       <layout class="QHBoxLayout" name="horizontalLayout_2">
        <item>
         <widget class="QLabel" name="miImagen">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="autoFillBackground">
           <bool>true</bool>
          </property>
          <property name="scaledContents">
           <bool>true</bool>
          </property>
          <property name="alignment">
           <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
          </property>
         </widget>
        </item>
       </layout>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>

我错过了什么?谢谢。

【问题讨论】:

  • “放大”是什么意思?只有当QLabel 大于QScrollArea 时才会出现滚动条。
  • 是的,当我放大时,QLabel 变得更大,因为我在该图像中获得了更多细节。图像变大了。
  • 请在您创建和设置小部件属性的位置发布代码。
  • 已添加 XML 代码。我猜这是因为 QScrollArea 没有注意到 QLabel 正在改变它的大小,所以它只在我改变它的尺寸时才响应,而不是 QLabel 的尺寸。

标签: image qt scrollbar qlabel qscrollarea


【解决方案1】:

我知道这是一篇旧帖子 - 但如果您或任何人仍有问题,将 QScrollArea::widgetResizable 设置为 false 可能会有所帮助。

至少,当我尝试类似的事情时,我的垂直滚动条总是被禁用(即使我将可滚动小部件的大小设置为大于视口的高度),直到我将其设置为 false。

如果是真的,我认为它会更新可滚动小部件的大小,因此不需要滚动条。这使您可以执行我猜想的示例中的操作,并实现拉伸以适应功能。 (其实我想要做的是适合宽度,只有一个垂直滚动条)

【讨论】:

    【解决方案2】:

    您是否尝试过关注Qt's scroll area example?如果您使用 QLabel 来显示图像,那么使用 QScrollArea 几乎是实现您想要的标准的方法。你像这样使用它(来自示例):

     imageLabel = new QLabel;
     imageLabel->setBackgroundRole(QPalette::Base);
     imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
     imageLabel->setScaledContents(true);
    
     scrollArea = new QScrollArea;
     scrollArea->setBackgroundRole(QPalette::Dark);
     scrollArea->setWidget(imageLabel);
     setCentralWidget(scrollArea);
    

    然后像这样处理缩放:

     void ImageViewer::zoomIn() { 
        scaleImage(1.25);
     }
    
     void ImageViewer::zoomOut() {
         scaleImage(0.8);
     }
    
     void ImageViewer::scaleImage(double factor)
     {
         Q_ASSERT(imageLabel->pixmap());
         scaleFactor *= factor;
         imageLabel->resize(scaleFactor * imageLabel->pixmap()->size());
    
         adjustScrollBar(scrollArea->horizontalScrollBar(), factor);
         adjustScrollBar(scrollArea->verticalScrollBar(), factor);
    
         zoomInAct->setEnabled(scaleFactor < 3.0);
         zoomOutAct->setEnabled(scaleFactor > 0.333);
     }
    
     void ImageViewer::adjustScrollBar(QScrollBar *scrollBar, double factor) {
         scrollBar->setValue(int(factor * scrollBar->value()
                             + ((factor - 1) * scrollBar->pageStep()/2)));
     }
    

    当然,您可以通过查看示例来更好地了解正在发生的事情,但这就是它的要点。我想也许 adjustScrollBar() 函数可能对你最有帮助。

    您对原始帖子的最后评论是正确的,QScrollArea 不会神奇地注意到其内容大小的变化。看看示例如何使用 adjustScrollBar() 来弥补这一事实。

    【讨论】:

    • 事实上,这个 Qt 示例是我用来做我的应用程序的示例。我已经实现了这些功能。条不出现。唯一不同的是,在 XML 版本中,我不能实现 scrollArea->setWidget(imageLabel) 和 setCentralWidget(scrollArea) 语句。我猜第一个就像在滚动区域内拖动 imageLabel。我尝试了第二个,应用程序崩溃了。
    • 好吧,我检测到了错误,但我不知道为什么会这样:scrollArea->horizo​​ntalScrollBar()->setValue() 没有做任何事情。传递给 setValue 的值是负数还是正数,总是不同,但两个滚动条的值仍然是 0。总是! :(
    • 在与此示例类似的代码中,我发现只有在我为 imageLabel 设置最小尺寸时才会出现滚动条 - 这里建议:forum.qt.io/topic/31189/qlabel-won-t-expand-when-in-qscrollarea/…
    猜你喜欢
    • 2014-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    相关资源
    最近更新 更多