如何让QScrollArea的高度尽量贴合内部QLabel的高度,同时不超过最大行数?
我在使用QLabel来显示任意长度的文本(作为命令输出传回)。我把QLabel放在一个垂直布局中,和其他控件一起。问题是如果QLabel接收到太多行文本,它的高度会无限制地增加,把它之下的控件挤出可见区域……
我尝试了QScrollArea,但不知道如何在QLabel还没有达到例如10行时让它紧贴地适应标签的高度;只有当标签超过10行时,滚动区域才停止扩展,改为滚动。在我的尝试中,滚动区域显得很僵硬,即使QLabel里几乎没有文本也会占用额外的竖向空间。
应该怎么做?
编辑:一个基本的代码示例:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "./ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
ui->label->setText(ui->label->text() + "\nA new line");
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTableWidget" name="tableWidget"/>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>784</width>
<height>232</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>First line</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Add a line</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>36</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
问题在于 label 含有很少的文本,但滚动区域并不能紧贴文本。是否可以做到在最多只有10行文本时,滚动区域自动调整大小以适合文本而不滚动;超过10行后,尺寸不再继续增加,滚动也能正常工作?
解决方案
大概是这样的?
#include <QApplication>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QPushButton>
#include <QFontMetrics>
class Window : public QWidget
{
private:
QTextEdit *edit;
int lineCount{};
int minimumHeight{};
int margin{};
const int MAX_LINES{10};
public:
Window(QWidget *parent = nullptr) : QWidget(parent){
auto layout = new QVBoxLayout;
setLayout(layout);
edit = new QTextEdit;
auto addBtn=new QPushButton("Add new line");
auto btn = new QPushButton("Some widget");
layout->addWidget(addBtn);
layout->addWidget(edit);
layout->addWidget(btn);
layout->addStretch();
margin = edit->contentsMargins().bottom()
+ edit->contentsMargins().top();
minimumHeight = edit->fontMetrics().lineSpacing()
+ edit->document()->documentMargin() * 2
+ margin;
edit->setFixedHeight(minimumHeight);
connect(addBtn, &QPushButton::clicked, this, [this]{
edit->append("new line " + QString::number(++lineCount));
});
connect(edit, &QTextEdit::textChanged, this, [this]{
if(edit->document()->lineCount() <= MAX_LINES){
edit->setFixedHeight(edit->document()->size().height() + margin);
// Changes at the request of the topic author
// adjustSize();
edit->setMinimumHeight(minimumHeight);
}
// Changes at the request of the topic author
else{
edit->setFixedHeight(minimumHeight * MAX_LINES + margin);
}
});
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window w;
w.show();
return a.exec();
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。