从代码创建的 QPushButton 的最小尺寸/宽度

问题描述 投票:0回答:4

我创建了 2 行按钮,每行都位于 QHBoxLayout 内。 enter image description here

我在代码中创建按钮:

static const char* buttonText = "23456789TJQKA";
for (int ii = 0; buttonText[ii]; ii++)
{
    QPushButton* pushButton = new QPushButton(this);
    pushButton->setText(QString(buttonText[ii]));
    ui->horizontalLayout_1->addWidget(pushButton);
}
for (int ii = 0; buttonText[ii]; ii++)
{
    QPushButton* pushButton = new QPushButton(this);
    pushButton->setText(QString(buttonText[ii]));
    ui->horizontalLayout_2->addWidget(pushButton);
}

问题是它们无法缩小(当用户调整对话框大小时)超过该大小,即使它们的文本适合更小的宽度。如果我在资源编辑器中而不是在代码中手动创建按钮,它们的宽度可以比这更小。

c++ qt button resize
4个回答
10
投票

发生这种情况是因为

minimumSizeHint
QPushButton
不允许
QLayout
调整其大小 :

minimumSizeHint() 的默认实现返回无效值 如果此小部件没有布局,则返回大小,并返回布局的 否则最小尺寸。大多数内置小部件重新实现 最小尺寸提示()。

QLayout 永远不会将小部件的大小调整为小于最小值 大小提示,除非设置了minimumSize()或将大小策略设置为 QSizePolicy::忽略。如果设置了minimumSize(),则最小尺寸提示 将会被忽略。

简单的解决方案是显式设置最小宽度:

static const char* buttonText = "23456789TJQKA";
for (int ii = 0; buttonText[ii]; ii++)
{
   QPushButton* pushButton = new QPushButton(this);
   pushButton->setMinimumWidth(5);
   pushButton->setText(QString(buttonText[ii]));
   ui->horizontalLayout_1->addWidget(pushButton);
}
for (int ii = 0; buttonText[ii]; ii++)
{
   QPushButton* pushButton = new QPushButton(this);
   pushButton->setMinimumWidth(5);
   pushButton->setText(QString(buttonText[ii]));
   ui->horizontalLayout_2->addWidget(pushButton);
}

5
投票

正如 pnezis 所写,您可能想要覆盖按钮计算的默认最小尺寸。这是一种方法,您可以在避免选择任意大小的同时避免在条件变化(不同的字体或字体大小、UI 样式等)时可能不起作用的方法:

QWidget* parent = /* some widget */
auto button = new QPushButton(QLatin1String("X"), parent);
auto textSize = button->fontMetrics().size(Qt::TextShowMnemonic, button->text());
QStyleOptionButton opt;
opt.initFrom(button);
opt.rect.setSize(textSize);
button->setMinimumSize(
  button->style()->sizeFromContents(QStyle::CT_PushButton,
                                    &opt,
                                    textSize,
                                    button));

上面是根据QPushButton自己的代码改编和简化的。您可能想查看 QPushButton::sizeHint 的源代码以获取所有详细信息。


1
投票

setMaximumWidth 对我有用。 示例代码在 pyqt 中,但它应该直接翻译为 C++,没有任何问题。

from PyQt4 import QtGui

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        layout = QtGui.QHBoxLayout()
        texts = [":)",
                 "&Short",
                 "&Longer",
                 "&Different && text",
                 "More && text",
                 "Even longer button text", ]
        for text in texts:
            btn = QtGui.QPushButton(text)
            double = text.count('&&')
            text = text.replace('&', '') + ('&' * double)
            width = btn.fontMetrics().boundingRect(text).width() + 7
            btn.setMaximumWidth(width)
            layout.addWidget(btn)
        self.setLayout(layout)

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)
    mainWin = Window()
    mainWin.show()
    sys.exit(app.exec_())

0
投票

这个最小按钮宽度来自您的

QStyle
,例如如果使用
"fusion"
作为样式,则为 80 像素:

您可以通过覆盖此实现的

QProxyStyle
来删除它:

#include <QApplication>
#include <QProxyStyle>
#include <QStyleOptionButton>

class CustomStyle: public QProxyStyle {
public:
    using QProxyStyle::QProxyStyle;

protected:
    auto sizeFromContents(
        ContentsType const type,
        QStyleOption const* option,
        QSize const& size,
        QWidget const* widget
    ) const -> QSize override {
        if (type == CT_PushButton) {
            auto newSize = QCommonStyle::sizeFromContents(type, option, size, widget);
            if (auto const btn = qstyleoption_cast<QStyleOptionButton const*>(option)) {
                if (!btn->icon.isNull() && btn->iconSize.height() > 16) {
                    newSize -= QSize(0, 2);
                }
            }
            return newSize;
        }

        return QProxyStyle::sizeFromContents(type, option, size, widget);
    }
};

为您的应用程序设置此自定义样式,您的

QPushButton
将缩小,直到与文本宽度匹配。

#include <QBoxLayout>
#include <QPushButton>
#include <ranges>

int main(int argc, char** argv) {
    QApplication app(argc, argv);

    // Set your new custom style
    app.setStyle(new CustomStyle()); // or e.g. CustomStyle("fusion")

    auto const layout = new QHBoxLayout;
    for (auto const i: std::ranges::views::iota(0, 19)) {
        layout->addWidget(new QPushButton(QString::number(i)));
    }

    auto widget = QWidget{};
    widget.setLayout(layout);
    widget.show();

    return app.exec();
}

© www.soinside.com 2019 - 2024. All rights reserved.