40.md 16.6 KB
Newer Older
W
init  
wizardforcel 已提交
1 2 3 4 5 6
# Qt5 中的布局管理

> 原文: [http://zetcode.com/gui/qt5/layoutmanagement/](http://zetcode.com/gui/qt5/layoutmanagement/)

在 Qt5 编程教程的这一部分中,我们将讨论小部件的布局管理。 我们提到了`QHBoxLayout``QVBoxLayout``QFormLayout``QGridLayout`管理器。

W
wizardforcel 已提交
7
典型的应用由各种小部件组成。 这些小部件放置在布局内。 程序员必须管理应用的布局。 在 Qt5 中,我们有两个选择:
W
init  
wizardforcel 已提交
8 9

*   绝对定位
W
wizardforcel 已提交
10
*   布局管理器
W
init  
wizardforcel 已提交
11 12 13 14 15 16

## 绝对定位

程序员以像素为单位指定每个小部件的位置和大小。 当使用绝对定位时,我们必须了解几件事。

*   如果我们调整窗口大小,则小部件的大小和位置不会改变。
W
wizardforcel 已提交
17 18
*   在各种平台上,应用看起来有所不同(通常很差)。
*   在我们的应用中更改字体可能会破坏布局。
W
init  
wizardforcel 已提交
19 20 21 22 23 24
*   如果决定更改布局,则必须完全重做布局,这既繁琐又耗时。

在某些情况下,我们可能会使用绝对定位。 但是大多数情况下,在实际程序中,程序员使用布局管理器。

`absolute.cpp`

W
wizardforcel 已提交
25
```cpp
W
init  
wizardforcel 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#include <QApplication>
#include <QDesktopWidget>
#include <QTextEdit>

class Absolute : public QWidget {

 public:
     Absolute(QWidget *parent = 0);
};

Absolute::Absolute(QWidget *parent)
    : QWidget(parent) {

  QTextEdit *ledit = new QTextEdit(this);
  ledit->setGeometry(5, 5, 200, 150);
}

int main(int argc, char *argv[]) {

  QApplication app(argc, argv);  

  Absolute window;

  window.setWindowTitle("Absolute");
  window.show();

  return app.exec();
}

```

`setGeometry()`方法用于以绝对坐标将窗口小部件放置在窗口上。

W
wizardforcel 已提交
59
```cpp
W
init  
wizardforcel 已提交
60 61 62 63 64 65 66 67 68
QTextEdit *edit = new QTextEdit(this);
ledit->setGeometry(5, 5, 200, 150);

```

我们创建一个`QTextEdit`小部件并手动定位。 `setGeometry()`方法有两件事:将窗口小部件定位到绝对坐标并调整窗口小部件的大小。

![Before resizement](img/c942c8661ff3e58e73778bd29230a055.jpg)

W
wizardforcel 已提交
69
图:调整大小前
W
init  
wizardforcel 已提交
70 71 72

![After resizement](img/8a5b78174a280b2b277f60a7308422a1.jpg)

W
wizardforcel 已提交
73
图:调整大小后
W
init  
wizardforcel 已提交
74

W
wizardforcel 已提交
75
## `QVBoxLayout`
W
init  
wizardforcel 已提交
76 77 78 79 80

`QVBoxLayout`类垂直排列小部件。 使用`addWidget()`方法将小部件添加到布局。

`verticalbox.h`

W
wizardforcel 已提交
81
```cpp
W
init  
wizardforcel 已提交
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
#pragma once

#include <QWidget>

class VerticalBox : public QWidget {

  public:
    VerticalBox(QWidget *parent = 0);
};

```

头文件。

`verticalbox.cpp`

W
wizardforcel 已提交
98
```cpp
W
init  
wizardforcel 已提交
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
#include "verticalbox.h"
#include <QVBoxLayout>
#include <QPushButton>

VerticalBox::VerticalBox(QWidget *parent)
    : QWidget(parent) {

  QVBoxLayout *vbox = new QVBoxLayout(this);
  vbox->setSpacing(1);

  QPushButton *settings = new QPushButton("Settings", this);
  settings->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  QPushButton *accounts = new QPushButton("Accounts", this);
  accounts->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  QPushButton *loans = new QPushButton("Loans", this);
  loans->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  QPushButton *cash = new QPushButton("Cash", this);
  cash->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  QPushButton *debts = new QPushButton("Debts", this);
  debts->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

  vbox->addWidget(settings);
  vbox->addWidget(accounts);
  vbox->addWidget(loans);
  vbox->addWidget(cash);
  vbox->addWidget(debts);

  setLayout(vbox);
}

```

在我们的示例中,我们有一个垂直布局管理器。 我们在其中放入了五个按钮。 我们使所有按钮都可以在两个方向上展开。

W
wizardforcel 已提交
133
```cpp
W
init  
wizardforcel 已提交
134 135 136 137 138
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->setSpacing(1);

```

W
wizardforcel 已提交
139
我们创建`QVBoxLayout`并在子窗口小部件之间设置 1px 的间距。
W
init  
wizardforcel 已提交
140

W
wizardforcel 已提交
141
```cpp
W
init  
wizardforcel 已提交
142 143 144 145 146 147 148
QPushButton *settings = new QPushButton("Settings", this);
settings->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

```

我们创建一个按钮并为其设置大小策略。 子窗口小部件由布局管理器管理。 默认情况下,按钮水平扩展,垂直方向固定大小。 如果要更改它,我们将设置一个新的大小策略。 在我们的例子中,按钮可以向两个方向扩展。

W
wizardforcel 已提交
149
```cpp
W
init  
wizardforcel 已提交
150 151 152 153 154 155 156 157
vbox->addWidget(settings);
vbox->addWidget(accounts);
...

```

我们使用`addWidget()`方法将子窗口小部件添加到布局管理器。

W
wizardforcel 已提交
158
```cpp
W
init  
wizardforcel 已提交
159 160 161 162 163 164 165 166
setLayout(vbox);

```

我们为窗口设置`QVBoxLayout`管理器。

`main.cpp`

W
wizardforcel 已提交
167
```cpp
W
init  
wizardforcel 已提交
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
#include "verticalbox.h"
#include <QApplication>

int main(int argc, char *argv[]) {

  QApplication app(argc, argv);  

  VerticalBox window;

  window.resize(240, 230);
  window.setWindowTitle("VerticalBox");
  window.show();

  return app.exec();
}

```

主文件。

![QVBoxLayout](img/e05702c31471184a6a8996d82db931bc.jpg)

W
wizardforcel 已提交
190
图:`QVBoxLayout`
W
init  
wizardforcel 已提交
191

W
wizardforcel 已提交
192
## 按钮
W
init  
wizardforcel 已提交
193 194 195 196 197

在下面的示例中,我们在窗口的客户区域上显示两个按钮。 它们将位于窗口的右下角。

`buttons.h`

W
wizardforcel 已提交
198
```cpp
W
init  
wizardforcel 已提交
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
#pragma once

#include <QWidget>
#include <QPushButton>

class Buttons : public QWidget {

  public:
    Buttons(QWidget *parent = 0);

  private:
    QPushButton *okBtn;
    QPushButton *applyBtn;
};

```

头文件。

`buttons.cpp`

W
wizardforcel 已提交
220
```cpp
W
init  
wizardforcel 已提交
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
#include "buttons.h"
#include <QVBoxLayout>
#include <QHBoxLayout>

Buttons::Buttons(QWidget *parent)
    : QWidget(parent) {

  QVBoxLayout *vbox = new QVBoxLayout(this);
  QHBoxLayout *hbox = new QHBoxLayout();

  okBtn = new QPushButton("OK", this);
  applyBtn = new QPushButton("Apply", this);

  hbox->addWidget(okBtn, 1, Qt::AlignRight);
  hbox->addWidget(applyBtn, 0);

  vbox->addStretch(1);
  vbox->addLayout(hbox);
}

```

假设我们想在窗口的右下角有两个按钮。

W
wizardforcel 已提交
245
```cpp
W
init  
wizardforcel 已提交
246 247 248 249 250 251 252
QVBoxLayout *vbox = new QVBoxLayout(this);
QHBoxLayout *hbox = new QHBoxLayout();

```

我们创建了两个框布局管理器:一个垂直框布局管理器和一个水平框布局管理器。

W
wizardforcel 已提交
253
```cpp
W
init  
wizardforcel 已提交
254 255 256 257 258 259 260
okBtn = new QPushButton("OK", this);
applyBtn = new QPushButton("Apply", this);

```

我们创建两个按钮。

W
wizardforcel 已提交
261
```cpp
W
init  
wizardforcel 已提交
262 263 264 265 266 267 268
hbox->addWidget(okBtn, 1, Qt::AlignRight);
hbox->addWidget(applyBtn, 0);

```

这些按钮位于水平布局管理器中。 使用`addWidget()`方法。 这些按钮右对齐。 第一个参数是子窗口小部件。 第二个参数是拉伸因子,最后一个参数是对齐。 通过将“确定”按钮的拉伸因子设置为 1,我们在窗口的左侧到右侧留出一定的空间。 窗口小部件不会扩展到分配给它的所有空间。 最后,`Qt::AlignRight`常数将小部件对齐到分配空间的右侧。

W
wizardforcel 已提交
269
```cpp
W
init  
wizardforcel 已提交
270 271 272 273 274 275 276 277 278
vbox->addStretch(1);
vbox->addLayout(hbox);

```

通过调用`addStretch()`方法,我们在垂直框中放入了一个可扩展的空白区域。 然后,将水平框布局添加到垂直框布局。

`main.cpp`

W
wizardforcel 已提交
279
```cpp
W
init  
wizardforcel 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
#include <QApplication>
#include "buttons.h"

int main(int argc, char *argv[]) {

  QApplication app(argc, argv);  

  Buttons window;

  window.resize(290, 170);
  window.setWindowTitle("Buttons");
  window.show();

  return app.exec();
}

```

主文件。

![Buttons](img/6ef6b6e0d590a812570c117b56d969d1.jpg)

W
wizardforcel 已提交
302
图:按钮
W
init  
wizardforcel 已提交
303 304 305 306 307 308 309

## 嵌套布局

以下示例的目的是说明可以合并布局管理器。 通过甚至简单布局的组合,我们可以创建复杂的对话框或窗口。 要嵌套布局,我们利用`addLayout()`方法。

`nesting.h`

W
wizardforcel 已提交
310
```cpp
W
init  
wizardforcel 已提交
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
#pragma once

#include <QWidget>

class Layouts : public QWidget {

  public:
    Layouts(QWidget *parent = 0);
};

```

这是头文件。

`nesting.cpp`

W
wizardforcel 已提交
327
```cpp
W
init  
wizardforcel 已提交
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
#include <QVBoxLayout>
#include <QPushButton>
#include <QListWidget>
#include "nesting.h"

Layouts::Layouts(QWidget *parent)
    : QWidget(parent) {

  QVBoxLayout *vbox = new QVBoxLayout();
  QHBoxLayout *hbox = new QHBoxLayout(this);

  QListWidget *lw = new QListWidget(this);
  lw->addItem("The Omen"); 
  lw->addItem("The Exorcist");
  lw->addItem("Notes on a scandal");
  lw->addItem("Fargo");
  lw->addItem("Capote");

  QPushButton *add = new QPushButton("Add", this);
  QPushButton *rename = new QPushButton("Rename", this);
  QPushButton *remove = new QPushButton("Remove", this);
  QPushButton *removeall = new QPushButton("Remove All", this);

  vbox->setSpacing(3);
  vbox->addStretch(1);
  vbox->addWidget(add);
  vbox->addWidget(rename);
  vbox->addWidget(remove);
  vbox->addWidget(removeall);
  vbox->addStretch(1);

  hbox->addWidget(lw);
  hbox->addSpacing(15);
  hbox->addLayout(vbox);

  setLayout(hbox);
}

```

在示例中,我们创建一个窗口,该窗口由四个按钮和一个列表小部件组成。 这些按钮被分组在一个垂直列中,并位于列表小部件的右侧。 如果我们调整窗口的大小,列表小部件也将被调整大小。

W
wizardforcel 已提交
370
```cpp
W
init  
wizardforcel 已提交
371 372 373 374 375 376
QVBoxLayout *vbox = new QVBoxLayout();

```

`QVBoxLayout`将是按钮的列。

W
wizardforcel 已提交
377
```cpp
W
init  
wizardforcel 已提交
378 379 380 381 382 383
QHBoxLayout *hbox = new QHBoxLayout(this);

```

`QHBoxLayout`将是小部件的基本布局。

W
wizardforcel 已提交
384
```cpp
W
init  
wizardforcel 已提交
385 386 387 388 389 390 391 392 393 394 395
QListWidget *lw = new QListWidget(this);
lw->addItem("The Omen"); 
lw->addItem("The Exorcist");
lw->addItem("Notes on a scandal");
lw->addItem("Fargo");
lw->addItem("Capote");

```

`QListWidget`已创建。

W
wizardforcel 已提交
396
```cpp
W
init  
wizardforcel 已提交
397 398 399 400 401 402 403 404 405
QPushButton *add = new QPushButton("Add", this);
QPushButton *rename = new QPushButton("Rename", this);
QPushButton *remove = new QPushButton("Remove", this);
QPushButton *removeall = new QPushButton("Remove All", this);

```

在这里,我们创建四个按钮。

W
wizardforcel 已提交
406
```cpp
W
init  
wizardforcel 已提交
407 408 409 410 411 412 413 414 415 416 417 418
vbox->setSpacing(3);
vbox->addStretch(1);
vbox->addWidget(add);
vbox->addWidget(rename);
vbox->addWidget(remove);
vbox->addWidget(removeall);
vbox->addStretch(1);

```

创建带有四个按钮的垂直框。 我们在按钮之间留了一些空间。 注意,我们在垂直框的顶部和底部添加了一个拉伸因子。 这样,按钮可以垂直居中。

W
wizardforcel 已提交
419
```cpp
W
init  
wizardforcel 已提交
420 421 422 423 424 425 426 427
hbox->addWidget(lw);
hbox->addSpacing(15);
hbox->addLayout(vbox);

```

列表小部件和按钮的垂直框放置在水平框布局中。 `addLayout()`方法用于将一个布局添加到另一个布局。

W
wizardforcel 已提交
428
```cpp
W
init  
wizardforcel 已提交
429 430 431 432 433 434 435 436
setLayout(hbox);

```

我们为父窗口设置基本布局。

`main.cpp`

W
wizardforcel 已提交
437
```cpp
W
init  
wizardforcel 已提交
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
#include <QApplication>
#include "nesting.h"

int main(int argc, char *argv[]) {

  QApplication app(argc, argv);  

  Layouts window;

  window.setWindowTitle("Layouts");
  window.show();

  return app.exec();
}

```

这是主文件。

![Nesting layouts](img/6a0c9fff072563f54762817b558f6549.jpg)

W
wizardforcel 已提交
459
图:嵌套布局
W
init  
wizardforcel 已提交
460

W
wizardforcel 已提交
461
## `QFormLayout`
W
init  
wizardforcel 已提交
462 463 464 465 466

`QFormLayout`是一个简单的布局管理器,用于管理输入窗口小部件及其相关标签的形式。 它以两列的形式布置其子项。 左列包含标签,右列包含输入窗口小部件,例如`QLineEdit``QSpinBox`

`form.h`

W
wizardforcel 已提交
467
```cpp
W
init  
wizardforcel 已提交
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
#pragma once

#include <QWidget>

class FormEx : public QWidget {

  public:
    FormEx(QWidget *parent = 0);
};

```

这是标题文件管理器。

`form.cpp`

W
wizardforcel 已提交
484
```cpp
W
init  
wizardforcel 已提交
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include "form.h"

FormEx::FormEx(QWidget *parent)
    : QWidget(parent) {

  QLineEdit *nameEdit = new QLineEdit(this);
  QLineEdit *addrEdit = new QLineEdit(this);
  QLineEdit *occpEdit = new QLineEdit(this);

  QFormLayout *formLayout = new QFormLayout;
  formLayout->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);
  formLayout->addRow("Name:", nameEdit);
  formLayout->addRow("Email:", addrEdit);
  formLayout->addRow("Age:", occpEdit);

  setLayout(formLayout);
}

```

该示例创建一个包含三个标签和三个行编辑的表单。

W
wizardforcel 已提交
510
```cpp
W
init  
wizardforcel 已提交
511 512 513 514 515 516
QFormLayout *formLayout = new QFormLayout;

```

创建`QFormLayout`的实例。

W
wizardforcel 已提交
517
```cpp
W
init  
wizardforcel 已提交
518 519 520 521 522 523
formLayout->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);

```

使用`setLabelAlignment()`方法,我们设置标签小部件的对齐方式。

W
wizardforcel 已提交
524
```cpp
W
init  
wizardforcel 已提交
525 526 527 528 529 530 531 532
formLayout->addRow("Name:", nameEdit);

```

`addRow()`方法将新行添加到表单布局的底部,并带有给定的标签和输入小部件。

`main.cpp`

W
wizardforcel 已提交
533
```cpp
W
init  
wizardforcel 已提交
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
#include <QApplication>
#include "form.h"

int main(int argc, char *argv[]) {

  QApplication app(argc, argv);  

  FormEx window;

  window.setWindowTitle("Form example");
  window.show();

  return app.exec();
}

```

这是主文件。

![Simple form](img/6d27d71de321ef2df014339d3037ab0e.jpg)

W
wizardforcel 已提交
555
图:简单 form
W
init  
wizardforcel 已提交
556

W
wizardforcel 已提交
557
## `QGridLayout`
W
init  
wizardforcel 已提交
558 559 560 561 562

`QGridLayout`将其小部件放置在网格中。 它是一个功能强大的布局管理器。

`calculator.h`

W
wizardforcel 已提交
563
```cpp
W
init  
wizardforcel 已提交
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
#pragma once

#include <QWidget>

class Calculator : public QWidget {

  public:
    Calculator(QWidget *parent = 0);

};

```

头文件。

`calculator.cpp`

W
wizardforcel 已提交
581
```cpp
W
init  
wizardforcel 已提交
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
#include <QGridLayout>
#include <QPushButton>
#include "calculator.h"

Calculator::Calculator(QWidget *parent)
    : QWidget(parent) {

  QGridLayout *grid = new QGridLayout(this);
  grid->setSpacing(2);

  QList<QString> values({ "7", "8", "9", "/", 
    "4", "5", "6", "*",
    "1", "2", "3", "-",
    "0", ".", "=", "+"
  });

  int pos = 0;

  for (int i=0; i<4; i++) {
   for (int j=0; j<4; j++) {

     QPushButton *btn = new QPushButton(values[pos], this);
     btn->setFixedSize(40, 40);
     grid->addWidget(btn, i, j);
     pos++;
   }
  }  

  setLayout(grid);
}

```

我们创建计算器的骨架。

W
wizardforcel 已提交
617
```cpp
W
init  
wizardforcel 已提交
618 619 620 621 622
QGridLayout *grid = new QGridLayout(this);
grid->setSpacing(2);

```

W
wizardforcel 已提交
623
我们创建网格布局,并在子小部件之间设置 2px 的空间。
W
init  
wizardforcel 已提交
624

W
wizardforcel 已提交
625
```cpp
W
init  
wizardforcel 已提交
626 627 628 629 630 631 632 633 634 635
QList<QString> values({ "7", "8", "9", "/", 
  "4", "5", "6", "*",
  "1", "2", "3", "-",
  "0", ".", "=", "+"
});

```

这些是按钮上显示的字符。

W
wizardforcel 已提交
636
```cpp
W
init  
wizardforcel 已提交
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
for (int i=0; i<4; i++) {
  for (int j=0; j<4; j++) {

      QPushButton *btn = new QPushButton(values[pos], this);
      btn->setFixedSize(40, 40);
      grid->addWidget(btn, i, j);
      pos++;
  }
} 

```

我们将十六个小部件放置到网格布局中。 每个按钮将具有固定的大小。

`main.cpp`

W
wizardforcel 已提交
653
```cpp
W
init  
wizardforcel 已提交
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675
#include <QApplication>
#include "calculator.h"

int main(int argc, char *argv[]) {

  QApplication app(argc, argv); 

  Calculator window;

  window.move(300, 300);
  window.setWindowTitle("Calculator");
  window.show();

  return app.exec();
}

```

这是主文件。

![QGridLayout](img/00c5ae9d280d2f2d167660eebe69f822.jpg)

W
wizardforcel 已提交
676
图:`QGridLayout`
W
init  
wizardforcel 已提交
677

W
wizardforcel 已提交
678
## 回顾
W
init  
wizardforcel 已提交
679 680 681 682 683

在本章的下一个示例中,我们使用`QGridLayout`管理器创建一个更复杂的窗口。

`review.h`

W
wizardforcel 已提交
684
```cpp
W
init  
wizardforcel 已提交
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700
#pragma once

#include <QWidget>

class Review : public QWidget {

  public:
    Review(QWidget *parent = 0);
};

```

头文件。

`review.cpp`

W
wizardforcel 已提交
701
```cpp
W
init  
wizardforcel 已提交
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
#include <QTextEdit>
#include "review.h"

Review::Review(QWidget *parent)
    : QWidget(parent) {

  QGridLayout *grid = new QGridLayout(this);
  grid->setVerticalSpacing(15);
  grid->setHorizontalSpacing(10);

  QLabel *title = new QLabel("Title:", this);
  grid->addWidget(title, 0, 0, 1, 1);
  title->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

  QLineEdit *edt1 = new QLineEdit(this);
  grid->addWidget(edt1, 0, 1, 1, 1);

  QLabel *author = new QLabel("Author:", this);
  grid->addWidget(author, 1, 0, 1, 1);
  author->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

  QLineEdit *edt2 = new QLineEdit(this);
  grid->addWidget(edt2, 1, 1, 1, 1);

  QLabel *review = new QLabel("Review:", this);
  grid->addWidget(review, 2, 0, 1, 1);
  review->setAlignment(Qt::AlignRight | Qt::AlignTop);

  QTextEdit *te = new QTextEdit(this);
  grid->addWidget(te, 2, 1, 3, 1);

  setLayout(grid);
}

```

该代码创建了一个窗口,可用于输入作者,书名和书评。

W
wizardforcel 已提交
743
```cpp
W
init  
wizardforcel 已提交
744 745 746 747 748 749
QGridLayout *grid = new QGridLayout(this);

```

`QGridLayout`管理器已创建。

W
wizardforcel 已提交
750
```cpp
W
init  
wizardforcel 已提交
751 752 753 754 755 756 757
grid->setVerticalSpacing(15);
grid->setHorizontalSpacing(10);

```

我们使用`setVerticalSpacing()`方法添加垂直间距,并使用`setHorizontalSpacing()`方法添加水平间距。

W
wizardforcel 已提交
758
```cpp
W
init  
wizardforcel 已提交
759 760 761 762 763
QLabel *title = new QLabel("Title", this);
grid->addWidget(title, 0, 0, 1, 1);

```

W
wizardforcel 已提交
764
这些代码行创建一个标签小部件,并将其放入网格布局中。 `addWidget()`方法具有五个参数。 第一个参数是子窗口小部件,在本例中为标签。 接下来的两个参数是放置标签的网格中的行和列。 最后,最后一个参数是`rowspan``colspan`。 这些参数指定当前窗口小部件将跨越多少行。 在我们的情况下,标签将仅跨越一列和一行。
W
init  
wizardforcel 已提交
765

W
wizardforcel 已提交
766
```cpp
W
init  
wizardforcel 已提交
767 768 769 770 771 772
title->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

```

`setAlignment()`方法将标题标签对准其单元格。 在水平方向上,它是右对齐的。 在垂直方向上,它居中。

W
wizardforcel 已提交
773
```cpp
W
init  
wizardforcel 已提交
774 775 776 777 778 779 780 781 782
QTextEdit *te = new QTextEdit(this);
grid->addWidget(te, 2, 1, 3, 1);

```

`QTextEdit`小部件位于第三行和第二列; 它跨越三行一列。

`main.cpp`

W
wizardforcel 已提交
783
```cpp
W
init  
wizardforcel 已提交
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
#include <QApplication>
#include "review.h"

int main(int argc, char *argv[]) {

  QApplication app(argc, argv);  

  Review window;

  window.setWindowTitle("Review");
  window.show();

  return app.exec();
}

```

主文件。

![Review](img/fbca6cb98cffb7a563b63f604d412e7b.jpg)

W
wizardforcel 已提交
805
图:回顾
W
init  
wizardforcel 已提交
806 807

Qt5 教程的这一部分专门用于布局管理。