QLineEdit自动调整大小以适应内容

10

我正在尝试创建一个带有LineEdit和PushButton的小部件。如果单击按钮,它应该打开一个FileDialog,让我选择一个文件。然后文件名应该显示在LineEdit中。这是我目前的代码:

#include "widget_openimage.h"
#include <QFontMetrics>

Widget_openimage::Widget_openimage(QWidget *parent) : QWidget(parent) {

// horizontal layout
layout = new QHBoxLayout();

// linedit on the left which shows the path of the chosen file
lineedit = new QLineEdit();
lineedit->setReadOnly(true);

// pushbutton on the right to select the file
btn = new QPushButton("...");
btn->setFixedSize(20,20);
connect(btn, SIGNAL(clicked()), this, SLOT(btn_clicked()));
connect(lineedit, SIGNAL(textChanged(QString)), this, SLOT(resize_to_content()));

layout->addWidget(lineedit);
layout->addWidget(btn);
this->setLayout(layout);
}

void Widget_openimage::btn_clicked() {
QString filename = QFileDialog::getOpenFileName(this,tr("Open"), "", tr("Image Files (*.png *.jpg *.bmp));
if (filename.isEmpty())
return;
else {
      lineedit->setText(filename);
     }
}

void Widget_openimage::resize_to_content() {
QString text = lineedit->text();
QFontMetrics fm = lineedit->fontMetrics();
int width = fm.boundingRect(text).width();
lineedit->resize(width, lineedit->height());
}

按钮的openfile函数运行正常,而且路径也在lineedit中正确显示。但是调整大小不起作用。有人能帮我一下吗?


当你没有调用setText方法时,如何在LineEdit中显示正确的路径?另外,你在错误的位置调用了connecttextChanged(QString)信号 - 你应该在构造函数中调用它。 - Amartel
抱歉,是我的错。setText当然在我的原始代码中,我只是在写问题时忘记了它。现在我已经将textChanged-connect移动到构造函数中,在另一个连接之后。但它仍然不起作用... - yangsunny
3个回答

10
首先,您的代码存在一些格式问题,我对其进行了编辑并添加了我的一些内容。我使用了 setFixedSize() 而不是 resize(),因为用户可能决定最小化窗口,如果发生这种情况,为什么还要显示完整的文件路径(我猜想您想始终显示完整路径并且不希望用户能够将窗口最小化至 lineedit 中的所有文本都无法显示的程度)。
Widget_openimage::Widget_openimage(QWidget *parent) : QWidget(parent) {

    // horizontal layout
    layout = new QHBoxLayout();

    // linedit on the left which shows the path of the chosen file
    lineedit = new QLineEdit;
    lineedit->setReadOnly(true);

    // pushbutton on the right to select the file
    btn = new QPushButton("...");
    btn->setFixedSize(20,20);

    connect(btn, SIGNAL(clicked()), this, SLOT(btn_clicked()));

    //do this connection so when the text in line edit is changed, its size    changes to show the full text
    connect(lineedit, SIGNAL(textChanged(QString)), this, SLOT(resize_to_content()));

    layout->addWidget(lineedit);
    layout->addWidget(btn);
    this->setLayout(layout);
}

void Widget_openimage::btn_clicked() {
    QString filename = QFileDialog::getOpenFileName(this,tr("Open"), "", tr("Image Files (*.png *.jpg *.bmp)"));

    //you have to set the file path text somewhere here
    lineedit->setText(filename);

    if (filename.isEmpty()) {
        return;
    }
}

void Widget_openimage::resize_to_content() {
    QString text = lineedit->text();

    //use QFontMetrics this way;
    QFont font("", 0);
    QFontMetrics fm(font);
    int pixelsWide = fm.width(text);
    int pixelsHigh = fm.height();

    lineedit->setFixedSize(pixelsWide, pixelsHigh);

    Widget_openimage::adjustSize();
}

谢谢你的回答,我刚刚尝试了你的方法。当路径变得更长时,比如从C:\image.jpg到D:\image\icon\icon.bmp,它能正常工作。但是反过来就不行了。当我将路径改为一个较短的名字时,LineEdit控件会在左右两侧留有空白,并居中显示。 - yangsunny
只需在 resize_to_content() 函数中添加 Widget_openimage::adjustSize();。我已经更新了我的答案以反映这一点。 - Richardson Ansong

2

我会这样做,使用适当的字体,并仅更改宽度:

void Widget_openimage::resizeToContent(QLineEdit *lineEdit)
{
    QString text = lineEdit->text();
    QFontMetrics fm(lineEdit->font());
    int pixelsWide = fm.width(text);
    lineEdit->setFixedWidth(pixelsWide);
    adjustSize();
}

0
这适用于Qt 6.3:
auto const edit = new QLineEdit;
connect(edit, &QLineEdit::textChanged, [edit](QString const& text){
    auto const text_size = edit->fontMetrics().size(0, text);
    auto const tm = edit->textMargins();
    auto const tm_size = QSize(tm.left() + tm.right(), tm.top() + tm.bottom());
    auto const cm = edit->contentsMargins();
    auto const cm_size = QSize(cm.left() + cm.right(), cm.top() + cm.bottom());
    auto const extra_size = QSize(8, 4); // hard coded stuff in Qt
    auto const contents_size = text_size + tm_size + cm_size + extra_size;

    QStyleOptionFrame op;
    op.initFrom(edit);
    auto const perfect_size =
        edit->style()->sizeFromContents(QStyle::CT_LineEdit, &op, contents_size);

    edit->setMinimumSize(perfect_size);
});

如果你想根据文本内容缩小编辑框的大小,那么请使用setFixedSize代替setMinimumSize


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接