Название: Резиновый TextEdit
Отправлено: joffadark от Июня 20, 2015, 00:16
Здравствуйте, уважаемые форумчане.
Необходимо реализовать необычный flex-интерфейс. Есть QFrame, внутри которого два QFrame. Внешний фрэйм компонует их по вертикали.
В верхнем фрэйме располагается виджет, который занимает все пространство фрэйма.
В нижнем фрэйме зона ввода данных: есть QTextEdit. У него должна быть задана минимальная высота и максимальная высота. Изначально, нижний фрэйм должен иметь минимальную высоту. По мере наполнения QTextEdit (по высоте, несколько строк), нижний фрэйм должен увеличиваться по высоте и уменьшать высоту верхнего врэйма. Иными словами, QTextEdit при переносе строк должен увеличивать свое занимаемое пространство по высоте. И так до максимальной высоты, а дальше появляется скроллбар.
По умолчанию, QTextEdit при выходе за границы высоты просто отображает скроллбар.
Подскажите пожалуйста: как реализовать подобное?
Название: Re: Резиновый TextEdit
Отправлено: sociopath от Июня 20, 2015, 02:14
У верхнего фрейма поставить вертикальную sizePolicy Expanding, у нижнего text edit'a - Maximum. При изменении текста по сигналу менять maximumHeight у text edit'a. Я на коленке за 5 минут сделал что-то типа того: const int maximumTextAreaHeight = 100;
int recountTextAreaHeight(const QString& text) { int linesCount = text.count('\n'); return /* высота текста */ 9 * (linesCount + 1) + /* межстрочный интервал */ 4 * linesCount + /* 2х поля textEdit'a */ 10; }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); ui->textEdit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); on_textEdit_textChanged(); }
MainWindow::~MainWindow() { delete ui; }
void MainWindow::on_textEdit_textChanged() { int countedHeight = recountTextAreaHeight(ui->textEdit->toPlainText()); ui->textEdit->setMaximumHeight(countedHeight > maximumTextAreaHeight ? maximumTextAreaHeight : countedHeight); ui->textEdit->setVerticalScrollBarPolicy(countedHeight > maximumTextAreaHeight ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); }
Самое сложное: написать правильно функцию recountTextAreaHeight. Мне щас лень ее по уму писать, я написал так, чтобы работало на стандартном font'е в винде. По хорошему в ней нужно использовать QFontMetrics, а также где-то взять значения margins text edit'a (возможно, вбить константными).
Название: Re: Резиновый TextEdit
Отправлено: joffadark от Июня 24, 2015, 05:18
У верхнего фрейма поставить вертикальную sizePolicy Expanding, у нижнего text edit'a - Maximum. При изменении текста по сигналу менять maximumHeight у text edit'a. Я на коленке за 5 минут сделал что-то типа того: const int maximumTextAreaHeight = 100;
int recountTextAreaHeight(const QString& text) { int linesCount = text.count('\n'); return /* высота текста */ 9 * (linesCount + 1) + /* межстрочный интервал */ 4 * linesCount + /* 2х поля textEdit'a */ 10; }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->frame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); ui->textEdit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); on_textEdit_textChanged(); }
MainWindow::~MainWindow() { delete ui; }
void MainWindow::on_textEdit_textChanged() { int countedHeight = recountTextAreaHeight(ui->textEdit->toPlainText()); ui->textEdit->setMaximumHeight(countedHeight > maximumTextAreaHeight ? maximumTextAreaHeight : countedHeight); ui->textEdit->setVerticalScrollBarPolicy(countedHeight > maximumTextAreaHeight ? Qt::ScrollBarAsNeeded : Qt::ScrollBarAlwaysOff); }
Самое сложное: написать правильно функцию recountTextAreaHeight. Мне щас лень ее по уму писать, я написал так, чтобы работало на стандартном font'е в винде. По хорошему в ней нужно использовать QFontMetrics, а также где-то взять значения margins text edit'a (возможно, вбить константными). Огромнейшее тебе спасибо!
Название: Re: Резиновый TextEdit
Отправлено: Doggike от Июля 13, 2015, 07:26
I feel good to have people give vent to the back.
|