c++ - 再次关于在 QT 中将窗口大小调整为其子项的大小

标签 c++ qt user-interface layout

类似的问题已经有人问过了,但是没有给出明确的答案,所以我再问一次。 假设我们有一个 QMainWindow,里面有一个 QScrollArea。我在程序中调整了 QScrollArea 的大小,我希望窗口相应地调整大小。 以下代码几乎可以正常工作:当新图像大于旧图像时,窗口的大小会增加。但是,当新图像变小时,窗口并没有变小,只是QScrollArea变小,QScrollArea和其他元素(标签、按钮)之间出现较大的空间

class PictureDialog : public QMainWindow {
Q_OBJECT

public:
    PictureDialog() : QMainWindow() {
        QWidget* canvas = new QWidget(this);
        setCentralWidget(canvas);
        QVBoxLayout* layout = new QVBoxLayout(canvas);
        imageLabel = new QLabel(" ");
        imageLabel->setStyleSheet("QLabel { background-color : white; color : black; }");
        scrollArea = new QScrollArea(this);
        scrollArea->resize(300, 300);
        scrollArea->setBackgroundRole(QPalette::Dark);
        scrollArea->setWidget(imageLabel);
        layout->addWidget(scrollArea);
        imgnamelabel = new QLabel(tr("Picture: "), this);
        layout->addWidget(imgnamelabel);
        QHBoxLayout *hlayout = new QHBoxLayout();
        layout->addLayout(hlayout);
        yesButton = new QPushButton(QPixmap(":pics/yes.png"), QString::null, this);
        yesButton->setShortcut(Qt::Key_Plus);
        yesButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
        hlayout->addWidget(yesButton);
        noButton = new QPushButton(QPixmap(":pics/no.png"), QString::null, this);
        noButton->setShortcut(Qt::Key_Minus);
        noButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
        hlayout->addWidget(noButton);
        hlayout->addStretch();
        connect(yesButton, SIGNAL(clicked()), SLOT(hide()));
        connect(noButton, SIGNAL(clicked()), SLOT(hide()));
    }

    void setPicture(QString imagePath, bool showNo) {
        imgnamelabel->setText(tr("Picture: ") + imagePath);
        if (!QFile::exists(imagePath)) {
            imageLabel->setText(tr("Picture file not found: ") + imagePath);
            imageLabel->resize(imageLabel->fontMetrics().boundingRect(imageLabel->text()).width(),
                               imageLabel->fontMetrics().boundingRect(imageLabel->text()).height());
        } else {
            QImage image(imagePath);
            if (image.isNull()) {
                imageLabel->setText(tr("Failed to open picture file: ") + imagePath);
                imageLabel->resize(imageLabel->fontMetrics().boundingRect(imageLabel->text()).width(),
                                imageLabel->fontMetrics().boundingRect(imageLabel->text()).height());
            } else {
                imageLabel->setPixmap(QPixmap::fromImage(image));
                imageLabel->resize(image.width(), image.height());
            }
        }

        scrollArea->setFixedSize(mini(imageLabel->width() + 20, QApplication::desktop()->screenGeometry().width() * 8 / 10),
                                 mini(imageLabel->height() + 20, QApplication::desktop()->screenGeometry().height() * 8 / 10));
        adjustSize();
        updateGeometry();
        if (showNo)
            noButton->setEnabled(true);
        else
            noButton->setEnabled(false);
    }

    QPushButton *yesButton, *noButton;

private:
    QLabel *imageLabel;
    QLabel *imgnamelabel;
    QScrollArea* scrollArea;
};

最佳答案

几个月前我遇到过类似的问题(使用 Qt SQL TableView )。

简而言之:尝试添加一个 CentralWidget->adjustSize(); before 行调整 MainWindow 的大小。

例子:

...
scrollArea->setFixedSize(...);
canvas->adjustSize();
adjustSize();
updateGeometry();
...

说明:在我的案例中,关键因素是我一直在使用 MainWindow + CentralWidget 组合来呈现 UI。

当您尝试将 “CentralWidgeted” MainWindow 的大小调整为其内容的大小时,它会将 CentralWidget 的大小作为内容大小。在这种情况下,MainWindow 的 adjustSize() 方法会尝试将窗口的大小调整为 CentralWidget,但 CentralWidget 仍然具有原始大小 [1],因此 MainWindow 保持其原始大小。

[1]:一些小部件可能能够自动调整自己的大小(我不记得有什么特别的,但我确定有一些),但在你的代码中你使用一个简单的 QWidget 作为 CentralWidget 和 QWidgets 缺乏这种能力(就像 QMainWindows)。如果使用此类“自动调整大小”小部件,则可以省略调整 CentralWidget 的大小。

关于c++ - 再次关于在 QT 中将窗口大小调整为其子项的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14811038/

相关文章:

带有 NDK 的 Android 未定义引用

c++ - tr() 函数不再工作从 Qt 4 迁移到 Qt 5

c++ - Qt:在两个子线程之间使用信号和槽

c++ - 比较bcrypt加密后的密码

java - 如何从多维数组的listview中获取值?

java - 更改标签和文本框的位置

c++ - 分配包含 STL vector 的结构时发生内存泄漏

c++ - 二维数组数据成员的初始化

C++ DLL接口(interface)和内存

c++ - 显示 QT 上下文菜单时没有 keyReleaseEvent