回答
您以linux標記了該問題。我在Windows 10上開發 - 離我最近的Linux是cygwin。因此,我在VS2013中解決了它,但是,嘿,這是C++與Qt。它應該是便攜式的...
實際上,QPixmap::scaled()
已經內置了所有必要的功能,通過保持寬高比進行縮放。因此,我的解決方案是將QLabel
和QPixmap
連接在一起。
// standard C++ header:
#include <iostream>
#include <string>
// Qt header:
#include <QApplication>
#include <QResizeEvent>
#include <QLabel>
#include <QMainWindow>
#include <QPixmap>
#include <QTimer>
using namespace std;
class LabelImage: public QLabel {
private:
QPixmap _qPixmap, _qPixmapScaled;
public:
void setPixmap(const QPixmap &qPixmap) { setPixmap(qPixmap, size()); }
protected:
virtual void resizeEvent(QResizeEvent *pQEvent);
private:
void setPixmap(const QPixmap &qPixmap, const QSize &size);
};
void LabelImage::resizeEvent(QResizeEvent *pQEvent)
{
QLabel::resizeEvent(pQEvent);
setPixmap(_qPixmap, pQEvent->size());
}
void LabelImage::setPixmap(const QPixmap &qPixmap, const QSize &size)
{
_qPixmap = qPixmap;
_qPixmapScaled = _qPixmap.scaled(size, Qt::KeepAspectRatio);
QLabel::setPixmap(_qPixmapScaled);
}
int main(int argc, char **argv)
{
cout << QT_VERSION_STR << endl;
// main application
#undef qApp // undef macro qApp out of the way
QApplication qApp(argc, argv);
// setup GUI
QMainWindow qWin;
#if 0 // does not consider aspect ratio
QLabel qLblImg;
qLblImg.setScaledContents(true);
#else // (not) 0
LabelImage qLblImg;
#endif // 0
qLblImg.setAlignment(Qt::AlignCenter);
qLblImg.setSizePolicy(
QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored));
QPixmap qPM;
if (qPM.load("cats.jpg")) qLblImg.setPixmap(qPM);
else {
qLblImg.setText(
QString::fromLatin1("Sorry. Cannot find file 'cats.jpg'."));
}
qWin.setCentralWidget(&qLblImg);
qWin.show();
// run application
return qApp.exec();
}
注:
我重載
QLabel::setPixmap()
方法和實際存儲像素圖的兩個版本 - 原和縮放。我不確定這是否有必要 - 這是我第一次使用QPixmap
。在閱讀Qt文檔時,我發現QLabel::setScaledContents()。我試了一下,但沒有考慮像素圖的長寬比。我無法找到將其設置爲額外選項的方法。 (可能是,我沒有足夠的搜索,我禁用了這個代碼,但留下它來記住這是「錯誤的方向」。)
在中間版本中,我能夠放大應用程序)但我無法縮小它。谷歌搜索一點點,我發現SO: Enable QLabel to shrink even if it truncates text。這解決了這個問題。
爲了保持短小的樣本,我對圖像文件名進行了硬編碼。實際上沒必要說應用程序的當前目錄必須是文件所在的目錄。 (這可能是在Linux下沒有問題,但我不得不適當調整在VS2013的調試設置。)
下面是我的測試申請:快照
這應該工作(當然)與任何可以加載到Qt中的圖像文件。但是,爲了使樣本完整(並且因爲互聯網和貓的照片真的屬於一起),我還提供了樣本圖像(供下載)。
左邊是最大,右邊是莫里茨。 (反之亦然?)
編輯:
根據Shefy牛哥元的反饋,這沒有正確的QLayout
工作。因此,我修改了原來的版本,並增加了QGridLayout
到我的示例代碼來研究這個話題:
// standard C++ header:
#include <iostream>
#include <string>
// Qt header:
#include <QApplication>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QMainWindow>
#include <QPixmap>
#include <QResizeEvent>
#include <QTimer>
using namespace std;
class LabelImage: public QLabel {
private:
QPixmap _qPixmap, _qPixmapScaled;
public:
void setPixmap(const QPixmap &qPixmap) { setPixmap(qPixmap, size()); }
protected:
virtual void resizeEvent(QResizeEvent *pQEvent);
private:
void setPixmap(const QPixmap &qPixmap, const QSize &size);
};
void LabelImage::resizeEvent(QResizeEvent *pQEvent)
{
QLabel::resizeEvent(pQEvent);
setPixmap(_qPixmap, pQEvent->size());
}
void LabelImage::setPixmap(const QPixmap &qPixmap, const QSize &size)
{
_qPixmap = qPixmap;
_qPixmapScaled = _qPixmap.scaled(size, Qt::KeepAspectRatio);
QLabel::setPixmap(_qPixmapScaled);
}
int main(int argc, char **argv)
{
cout << QT_VERSION_STR << endl;
// main application
#undef qApp // undef macro qApp out of the way
QApplication qApp(argc, argv);
// setup GUI
QMainWindow qWin;
QGroupBox qBox;
QGridLayout qGrid;
// a macro for the keyboard lazy:
#define Q_LBL_WITH_POS(ROW, COL) \
QLabel qLbl##ROW##COL(QString::fromLatin1(#ROW", "#COL)); \
/*qLbl##ROW##COL.setFrameStyle(QLabel::Raised | QLabel::Box);*/ \
qGrid.addWidget(&qLbl##ROW##COL, ROW, COL, Qt::AlignCenter)
Q_LBL_WITH_POS(0, 0);
Q_LBL_WITH_POS(0, 1);
Q_LBL_WITH_POS(0, 2);
Q_LBL_WITH_POS(1, 0);
LabelImage qLblImg;
qLblImg.setFrameStyle(QLabel::Raised | QLabel::Box);
qLblImg.setAlignment(Qt::AlignCenter);
//qLblImg.setMinimumSize(QSize(1, 1)); // seems to be not necessary
qLblImg.setSizePolicy(
QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored));
QPixmap qPM;
if (qPM.load("cats.jpg")) qLblImg.setPixmap(qPM);
else {
qLblImg.setText(
QString::fromLatin1("Sorry. Cannot find file 'cats.jpg'."));
}
qGrid.addWidget(&qLblImg, 1, 1, Qt::AlignCenter);
qGrid.setRowStretch(1, 1); // tell QGridLayout to stretch this cell...
qGrid.setColumnStretch(1, 1); // ...prior to other cells (w/ stretch 0)
Q_LBL_WITH_POS(1, 2);
Q_LBL_WITH_POS(2, 0);
Q_LBL_WITH_POS(2, 1);
Q_LBL_WITH_POS(2, 2);
qBox.setLayout(&qGrid);
qWin.setCentralWidget(&qBox);
qWin.show();
// run application
return qApp.exec();
}
注:
圖像的長寬比還是正確的,但調整大小並沒有工作了。因此,我添加了
QGrid::setRowStretch()
和QGrid::setColumnStretch()
。不幸的是,這並沒有太大的改變。我使用Google搜索這個主題,發現SO: Change resize behavior in Qt layouts。其實,這也沒有幫助,但讓我懷疑
QGridLayout
可能是這個佈局問題的實際來源。爲了更好地理解此佈局問題,我將幀添加到了所有的小部件。令我驚訝的是,它突然出現了。
我認爲在QGridLayout
作品的佈局有點不喜歡預期(雖然我不敢說它是錯誤)。但是,圍繞圖像製作框架的解決方法是我可以忍受的。 (事實上,它看起來沒有那麼糟糕。)
更新的代碼示例的快照:
。花了一些時間讓它工作,但它的作用像魅力。 –
- 您還可以告訴我如何爲另一個容器和佈局中的標籤執行此操作,而不是將其作爲中心控件?找不到辦法。 –
@ ShefyGur-ary剛發現那裏似乎沒有關於回答問題的自動通知。它是這樣的:我更新了我的示例,並且爲'QGridLayout'工作。我想聽聽這是否也適用於Linux端口。 – Scheff
- 1. 如何讓YouTube播放器縮放至頁面寬度,並保持寬高比?
- 2. 保持高寬比,而在FFmpeg的創建縮略圖
- 3. 保持圖像寬高比,並使用寬度百分比
- 4. Flexbox圖像縮放到高度並保持縱橫比
- 5. 縮放任何圖像保持比例和最小寬度
- 6. 放大/縮小如何保持寬高比?
- 7. jquery:保持寬高比並在窗口內包含div
- 8. 保持圖像的寬高比?
- 9. React Native保持寬高比圖像ios
- 10. 縮放圖像,但保持其比例
- 11. jquery - 打開彈出窗口和大小,然後在裏面放大圖像並保持寬高比
- 12. 根據長寬比使Flash文件縮放到div寬度並保持高度
- 13. 拉伸圖像視口保持寬高比
- 14. 如何在JavaScript中縮放(調整大小)圖片保持寬高比
- 15. javascript將圖像調整爲全屏並保持寬高比
- 16. 動態加載圖像並保持寬高比
- 17. 維持寬高比縮水
- 18. 調整圖像大小(image_lib),保持寬高比,但縮放到最小可能超過寬度和高度
- 19. 如何保持背景圖像的寬高比?
- 20. 如何通過保持寬高比在ImageView中填充圖像?
- 21. 如何強制圖像在WPF中保持寬高比?
- 22. 如何保持前景圖像的寬高比?
- 23. 如何保持圖像按鈕寬高比在android系統?
- 24. 在DirectShow中保持寬高比? (窗口)C++
- 25. 保持瀏覽器窗口大小的高寬比?
- 26. 保持圈的高寬比當窗口重新大小
- 27. 在css中保持寬高比與圖像寬度
- 28. 如何使用PIL調整圖像大小並保持其寬高比?
- 29. 如何重新調整圖像大小並保持長寬比
- 30. 縮放一個畫布元素並保持長寬比
請出示您到目前爲止試過的東西。你還會發現['QSize :: scaled'](http://doc.qt.io/qt-5/qsize.html#scaled-1)有用。 –
我嘗試在網格內放置後使用setSizePolicy。但我正在尋找一些有效的東西,而不是修復那些不是很好的東西 –