Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何调整图像的大小以在Qt中缩放?_C++_Qt - Fatal编程技术网

C++ 如何调整图像的大小以在Qt中缩放?

C++ 如何调整图像的大小以在Qt中缩放?,c++,qt,C++,Qt,我创建了一个名为ImageLabel的类,它扩展了QLabel。我希望它保持图像的大小比,无论它是如何伸展显示。当你把窗户调大的时候,它工作的很好。当你试图缩小窗口时,问题就出现了:它不会调整高度,而是让它伸展开来。我该如何解决这个问题 int ImageLabel::heightForWidth(int width) const { int height = (this->size.height()*width)/this->size.width(); return heig

我创建了一个名为ImageLabel的类,它扩展了QLabel。我希望它保持图像的大小比,无论它是如何伸展显示。当你把窗户调大的时候,它工作的很好。当你试图缩小窗口时,问题就出现了:它不会调整高度,而是让它伸展开来。我该如何解决这个问题


int ImageLabel::heightForWidth(int width) const {
    int height = (this->size.height()*width)/this->size.width();
    return height;
}

QSize ImageLabel::sizeHint() const {
    return this->size;
}

QSize ImageLabel::minimumSizeHint() const {
    return QSize(0, 0);
}

void ImageLabel::setSizePolicy(){
    QSizePolicy policy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    policy.setHeightForWidth(true);
    QLabel::setSizePolicy(policy);
    QLabel::setScaledContents(true);
}

void ImageLabel::setPixmap ( const QPixmap &pixmap ){
    this->size = pixmap.size();
    QLabel::setPixmap(pixmap);
}

int main(int argc, char *argv[]){
    QApplication a(argc, argv);

    QFrame *frame = new QFrame;
    QVBoxLayout *layout = new QVBoxLayout;
    frame->setLayout(layout);

    QPixmap map;
    map.load("test.png");
    ImageLabel *label = new ImageLabel;
    label->setSizePolicy();
    label->setPixmap(map);
    layout->addWidget(label);
    frame->show();

    return a.exec();
}


QLabel
中没有内置用于保持图像纵横比的功能。由于
Qlabel
可能具有您不需要的功能,因此您应该对
QWidget
进行子类化,并覆盖
paintEvent()
,以您想要的方式呈现图像。

有几种方法可以做到这一点,但最重要的是,我建议您不要试图通过提示方面来对抗布局系统。如您所见,您必须尝试并实现一些方法来帮助布局

我可以举两个例子。他们都不使用布局

第一个使用子
QLabel
显示图像,并将其固定大小从调整大小事件中移出:

//imagelabel.h
类ImageLabel:公共QWidget
{
Q_对象
公众:
显式ImageLabel(QWidget*parent=0);
常量QPixmap*pixmap()常量;
公众时段:
void setPixmap(const QPixmap&);
受保护的:
void resizeEvent(QResizeEvent*);
专用插槽:
void resizeImage();
私人:
QLabel*标签;
};
//imagelabel.cpp
ImageLabel::ImageLabel(QWidget*父项):
QWidget(父级)
{
标签=新的QLabel(本);
标签->设置缩放内容(真);
标签->设置固定大小(0,0);
}
void ImageLabel::resizeEvent(QResizeEvent*事件){
QWidget::resizeEvent(事件);
调整图像大小();
}
常量QPixmap*ImageLabel::pixmap()常量{
返回标签->pixmap();
}
void ImageLabel::setPixmap(常量QPixmap和pixmap){
标签->设置pixmap(pixmap);
调整图像大小();
}
void ImageLabel::resizeImage(){
QSize-pixSize=label->pixmap()->size();
scale(size(),Qt::KeepAspectRatio);
标签->设置固定大小(像素大小);
}
第二个例子基于@Arnold_Spence给出的答案。它甚至更短,因为它不使用子QLabel。它只是在绘制事件中绘制像素贴图:

// imagelabel2.h

class ImageLabel2 : public QWidget
{
    Q_OBJECT

public:
    explicit ImageLabel2(QWidget *parent = 0);
    const QPixmap* pixmap() const;

public slots:
    void setPixmap(const QPixmap&);

protected:
    void paintEvent(QPaintEvent *);

private:
    QPixmap pix;
};

// imagelabel2.cpp

ImageLabel2::ImageLabel2(QWidget *parent) :
    QWidget(parent)
{
}

void ImageLabel2::paintEvent(QPaintEvent *event) {
    QWidget::paintEvent(event);

    if (pix.isNull())
        return;

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QSize pixSize = pix.size();
    pixSize.scale(event->rect().size(), Qt::KeepAspectRatio);

    QPixmap scaledPix = pix.scaled(pixSize,
                                   Qt::KeepAspectRatio,
                                   Qt::SmoothTransformation
                                   );

    painter.drawPixmap(QPoint(), scaledPix);

}

const QPixmap* ImageLabel2::pixmap() const {
    return &pix;
}

void ImageLabel2::setPixmap (const QPixmap &pixmap){
    pix = pixmap;
}

是的,这就是为什么我添加了
heightForWidth
功能,这些功能在
Qlabel
中是缺乏的。问题不仅仅是绘画,它是关于布局的。您可以让一个小部件尝试向布局提供反馈,告诉它想要的大小,并始终将图像绘制到小部件的完整尺寸,或者您可以允许布局以任何方式调整小部件的大小,并始终在小部件的边界内以适当的比例和位置绘制图像。前者可能会变得复杂,后者似乎更容易。@chacham15:我实际上认为在绘画活动中这样做是一个好建议,因为这样可以让你明确地画出你想要的确切的像素贴图,而不是反对布局。您可以在组合QLabel上设置固定大小,并使用resizeEvent不断调整子对象的大小。方法
paintEvent
看起来很简单,我不明白它是如何与布局系统交互的。它如何告诉布局系统仅为高度分配正确的宽度?它看起来没有告诉它任何事情,只是利用了它现有的资源。在这种情况下,您可能会有令人讨厌的页边距,对吗?正如我所说,它不使用布局。您可以将此
ImageLabel
放置到一个布局中,该布局将驱动其大小。但是当
ImageLabel
对这些大小变化做出反应时,它将控制pixmap的精确显示。是的,如果将父窗口小部件设置得很宽,则可以留有边距。如果你想让它居中,那么为
drawPixmap
调用获得一个合适的
QPoint
只需要一点数学知识。实际上,这里重要的是你是否需要它来有一些对齐选项。除此之外,您只需将其与其他小部件一起放入布局中。这个小部件应该做的就是保持一个pixmap正确缩放,与小部件中可用空间的某个区域对齐。我想做一个图片拼贴,每张图片紧挨着另一张(想象一下像pinterest一样)。我想知道的是,父布局如何知道要给它多少空间,这样它就不会有疯狂的边距?澄清一下,这两种方法对我都有效,但只有在我(在pyQt中)对实例执行了以下操作之后:
imageLabelSizePolicy=QSizePolicy(QSizePolicy.MinimumExpanding,QSizePolicy.MinimumExpanding);imageLabelSizePolicy.setHeightForWidth(真);imageLabel.setSizePolicy(imageLabelSizePolicy)
。这可能是Qt n00b的评论,但我相信在将来的某个时候,另一个Qt n00b会出现在这个页面上。