C++ Qt应用程序的版图设计问题

C++ Qt应用程序的版图设计问题,c++,qt,c++11,C++,Qt,C++11,首先,我为我拙劣的绘画技巧道歉。我有一个应用程序,其中我在QLabel中加载了4个大小为640x480的图像,如图所示。 字母V、H和G分别表示垂直、水平和网格布局 为QLabel实现了sizeHint()、heightForWidth()和widthForHeight()。在我的qmain窗口的resizeEvent()中,我在QLabel上调用setFixedWidth(),这解决了将QLabel的大小与保持纵横比的图像相匹配的问题。我希望始终保持图像的纵横比 问题: 在QLabel上设置

首先,我为我拙劣的绘画技巧道歉。我有一个应用程序,其中我在QLabel中加载了4个大小为
640x480
的图像,如图所示。

字母V、H和G分别表示垂直、水平和网格布局

QLabel
实现了
sizeHint()
heightForWidth()
widthForHeight()
。在我的
qmain窗口的
resizeEvent()
中,我在
QLabel
上调用
setFixedWidth()
,这解决了将
QLabel
的大小与保持纵横比的图像相匹配的问题。我希望始终保持图像的纵横比

问题:

  • QLabel
    上设置一个固定的宽度会使widget3在我的笔记本电脑等分辨率较小的屏幕上消失 我尝试为
    QLabel
    设置不固定的宽度,并尝试加载保持纵横比的图像。大小策略设置为“扩展”

    QSizePolicy sizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding)

    我得到了这样的东西

    问题:

    在保持纵横比的同时加载图像会导致
    QLabel
    超出图像水平方向的不必要扩展,这看起来很难看

    我想要什么:

  • QLabel
    应始终适合图像,而不考虑其自身大小
  • widget1
    QLabel
  • 通过改变
    QLabel
    的大小,同时保持图像的纵横比,整个应用程序应该适合任何分辨率

  • 我觉得这是一种定义/设计问题,而不是一个技术问题。我尝试了各种各样的限制和政策,但没能达到我想要的。我相信我可以在这里得到一些建议。

    我不能100%确定如何达到OP的精确布局要求

    在我准备的样本中稍微调整了一些拉伸因子后,这并没有变得更好

    因此,我的回答阐述了必须考虑的两个基本方面

    设置拉伸因子 这是我关于小部件集布局的经验,我首先在OSF/Motif中收集,然后在GTK+(具有IMHO最佳布局管理)中收集,最后在Qt中收集:

    不要试图与布局经理抗争——你最终会感到沮丧(比如)。相反,尝试提供正确的提示(尽管这是可能的),让布局管理器做一些最符合您期望的事情

    (或者只编写一个自己的,为基础小部件集提供固定的小部件位置和大小的小部件。这对了解布局管理器为何如此复杂的使用很有启发。)

    因此,我的第一次尝试是正确设置拉伸系数:

    #include <QtWidgets>
    
    int main(int argc, char **argv)
    {
      qDebug() << "Qt Version:" << QT_VERSION_STR;
      QApplication app(argc, argv);
      QImage img("cats.jpg");
      QPixmap pixmap; 
      // setup GUI
      QWidget winMain;
      winMain.setWindowTitle("Layout Sample");
      QVBoxLayout v;
      QHBoxLayout h;
      QLabel widget1("Widget1");
      widget1.setFrameStyle(QLabel::Box | QLabel::Plain);
      h.addWidget(&widget1, 1); // remark widget1 for growing (horizontally in HBox h)
      QGridLayout g;
      QLabel img1;
      img1.setPixmap(QPixmap::fromImage(img));
      g.addWidget(&img1, 0, 0);
      QLabel img2;
      img2.setPixmap(QPixmap::fromImage(img));
      g.addWidget(&img2, 0, 1);
      QLabel img3;
      img3.setPixmap(QPixmap::fromImage(img));
      g.addWidget(&img3, 1, 0);
      QLabel img4;
      img4.setPixmap(QPixmap::fromImage(img));
      g.addWidget(&img4, 1, 1);
      h.addLayout(&g, 0); // remark g for not growing (horizontally in HBox h)
      v.addLayout(&h, 0); // remark h for not growing (vertically in VBox v)
      QLabel widget2("Widget2");
      widget2.setFrameStyle(QLabel::Box | QLabel::Plain);
      widget2.setAlignment(Qt::AlignLeft | Qt::AlignTop);
      v.addWidget(&widget2, 1); // remark widget2 for growing (vertically in VBox v)
      QLabel widget3("Widget3");
      widget3.setFrameStyle(QLabel::Box | QLabel::Plain);
      widget3.setAlignment(Qt::AlignLeft | Qt::AlignTop);
      v.addWidget(&widget3, 1); // remark widget3 for growing (vertically in VBox v)
      winMain.setLayout(&v);
      winMain.show();
      // runtime loop
      return app.exec();
    }
    
    输出:

    布局管理没有发挥得那么好(正如预期的那样——我没有给出任何延伸暗示)。 但是,至少,
    ImageLabel

    • 确保正确考虑纵横比的图像缩放
    • (尝试)根据图像纵横比(如果可能)调整
      QLabel
    QSizePolicy
    起着重要作用。看完文件后。我必须承认,在找到最符合我期望的设置后,我尝试了一些似乎很有希望的设置



    IMHO,OPs解决方案是两个示例中技术的正确组合。

    我曾经摆弄过图像、
    QLabel
    s、纵横比等等。也许,这对你也有帮助:。该死!我不知道布局会这么复杂。我想首先了解你做了什么,并将尝试实施。会让你知道它是什么样子的。非常感谢你的努力。
    #include <QtWidgets>
    
    class LabelImage: public QLabel {
    
      private:
        QPixmap _qPixmap, _qPixmapScaled;
    
      public:
        LabelImage(const QPixmap &qPixmap, QWidget *pQParent = nullptr):
          QLabel(pQParent), _qPixmap(qPixmap)
        {
          QSizePolicy sizePolicy;
          sizePolicy.setHorizontalPolicy(QSizePolicy::Ignored);
          sizePolicy.setVerticalPolicy(QSizePolicy::Ignored);
          sizePolicy.setHeightForWidth(true);
          sizePolicy.setWidthForHeight(true);
          setSizePolicy(sizePolicy);
        }
        virtual ~LabelImage() = default;
        LabelImage(const LabelImage&) = delete;
        LabelImage& operator=(const LabelImage&) = delete;
    
      public:
        //virtual QSize sizeHint() const override;
        virtual int heightForWidth(int w) const override;
      protected:
        virtual void resizeEvent(QResizeEvent *pQEvent) override;
    };
    
    //QSize LabelImage::sizeHint() const { return _qPixmap.size(); }
    
    int LabelImage::heightForWidth(int w) const
    {
      if (_qPixmap.width() == 0 || _qPixmap.height() == 0) return w;
      return _qPixmap.height() * w / _qPixmap.width();
    }
    
    void LabelImage::resizeEvent(QResizeEvent *pQEvent)
    {
      QLabel::resizeEvent(pQEvent);
      _qPixmapScaled = _qPixmap.scaled(pQEvent->size(), Qt::KeepAspectRatio);
      QLabel::setPixmap(_qPixmapScaled);
    }
    
    int main(int argc, char **argv)
    {
      qDebug() << "Qt Version:" << QT_VERSION_STR;
      QApplication app(argc, argv);
      QImage img("cats.jpg");
      QPixmap pixmap; 
      // setup GUI
      QWidget winMain;
      winMain.setWindowTitle("Layout Sample");
      QVBoxLayout v;
      QHBoxLayout h;
      QLabel widget1("Widget1");
      widget1.setFrameStyle(QLabel::Box | QLabel::Plain);
      h.addWidget(&widget1);
      QGridLayout g;
      LabelImage img1(QPixmap::fromImage(img));
      g.addWidget(&img1, 0, 0);
      LabelImage img2(QPixmap::fromImage(img));
      g.addWidget(&img2, 0, 1);
      LabelImage img3(QPixmap::fromImage(img));
      g.addWidget(&img3, 1, 0);
      LabelImage img4(QPixmap::fromImage(img));
      g.addWidget(&img4, 1, 1);
      h.addLayout(&g);
      v.addLayout(&h);
      QLabel widget2("Widget2");
      widget2.setFrameStyle(QLabel::Box | QLabel::Plain);
      widget2.setAlignment(Qt::AlignLeft | Qt::AlignTop);
      v.addWidget(&widget2);
      QLabel widget3("Widget3");
      widget3.setFrameStyle(QLabel::Box | QLabel::Plain);
      widget3.setAlignment(Qt::AlignLeft | Qt::AlignTop);
      v.addWidget(&widget3);
      winMain.setLayout(&v);
      winMain.show();
      // runtime loop
      return app.exec();
    }