C++ Qt应用程序的版图设计问题
首先,我为我拙劣的绘画技巧道歉。我有一个应用程序,其中我在QLabel中加载了4个大小为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上设置
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();
}