ZetCode

Qt5 控件

最后修改于 2023 年 10 月 18 日

在本 Qt5 C++ 编程教程中,我们将讨论一些基本的 Qt5 控件。我们提供了关于 QLabelQSliderQComboBoxQSpinBoxQLineEditQMainWindow 控件的示例。

控件是 GUI 应用程序的基本构建块。Qt5 库拥有一组丰富的各种控件。

Qt5 QLabel

QLabel 用于显示文本和图像。没有用户交互。以下示例显示文本。

label.h
#pragma once

#include <QWidget>
#include <QLabel>

class Label : public QWidget {

  public:
    Label(QWidget *parent = nullptr);

  private:
    QLabel *label;
};

这是我们代码示例的头文件。

label.cpp
#include <QVBoxLayout>
#include <QFont>
#include "label.h"

Label::Label(QWidget *parent)
    : QWidget(parent) {

  QString lyrics = "Who doesn't long for someone to hold\n\
Who knows how to love you without being told\n\
Somebody tell me why I'm on my own\n\
If there's a soulmate for everyone\n\
\n\
Here we are again, circles never end\n\
How do I find the perfect fit\n\
There's enough for everyone\n\
But I'm still waiting in line\n\
\n\
Who doesn't long for someone to hold\n\
Who knows how to love you without being told\n\
Somebody tell me why I'm on my own\n\
If there's a soulmate for everyone";

  label = new QLabel(lyrics, this);
  label->setFont(QFont("Purisa", 10));

  auto *vbox = new QVBoxLayout();
  vbox->addWidget(label);
  setLayout(vbox);
}

我们使用 QLabel 控件在窗口中显示歌词。

label = new QLabel(lyrics, this);
label->setFont(QFont("Purisa", 10));

我们创建一个标签控件并为其设置特定的字体。

main.cpp
#include <QApplication>
#include <QTextStream>
#include "label.h"

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

  QApplication app(argc, argv);

  Label window;

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

  return app.exec();
}

这是主文件。

QLabel
图:QLabel

Qt5 QSlider

QSlider 是一个具有简单手柄的控件。这个手柄可以来回拉动。通过这种方式,我们为特定任务选择一个值。

slider.h
#pragma once

#include <QWidget>
#include <QSlider>
#include <QLabel>

class Slider : public QWidget {

  Q_OBJECT

  public:
    Slider(QWidget *parent = nullptr);

  private:
    QSlider *slider;
    QLabel *label;
};

该示例的头文件。

slider.cpp
#include <QHBoxLayout>
#include "slider.h"

Slider::Slider(QWidget *parent)
    : QWidget(parent) {

  auto *hbox = new QHBoxLayout(this);

  slider = new QSlider(Qt::Horizontal , this);
  hbox->addWidget(slider);

  label = new QLabel("0", this);
  hbox->addWidget(label);

//   connect(slider, &QSlider::valueChanged, label,
//     static_cast<void (QLabel::*)(int)>(&QLabel::setNum));

  connect(slider, &QSlider::valueChanged, label,
    qOverload<int>(&QLabel::setNum));
}

我们显示两个控件:一个滑块和一个标签。滑块控制标签中显示的数字。

slider = new QSlider(Qt::Horizontal , this);

创建了一个水平 QSlider

connect(slider, &QSlider::valueChanged, label,
  qOverload<int>(&QLabel::setNum));

在此代码行中,我们将 valueChanged 信号连接到标签的内置 setNum 插槽。由于 setNum 方法被重载,我们使用 qOverload 来选择正确的方法。

main.cpp
#include <QApplication>
#include "slider.h"

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

  QApplication app(argc, argv);

  Slider window;

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

  return app.exec();
}

这是主文件。

QSlider
图:QSlider

Qt5 QComboBox

QComboBox 是一个控件,它以占用最少屏幕空间的方式向用户提供选项列表。它是一个选择控件,显示当前项目,并可以弹出一个可选择项目的列表。组合框可以编辑,允许用户修改列表中的每个项目。

combobox.h
#pragma once

#include <QWidget>
#include <QComboBox>
#include <QLabel>

class ComboBoxEx : public QWidget {

  Q_OBJECT

  public:
    ComboBoxEx(QWidget *parent = nullptr);

  private:
    QComboBox *combo;
    QLabel *label;
};

我们使用两个控件:一个组合框和一个标签。

combobox.cpp
#include <QHBoxLayout>
#include "combobox.h"

ComboBoxEx::ComboBoxEx(QWidget *parent)
    : QWidget(parent) {

  QStringList distros = {"Arch", "Xubuntu", "Redhat", "Debian",
      "Mandriva"};

  auto *hbox = new QHBoxLayout(this);

  combo = new QComboBox();
  combo->addItems(distros);

  hbox->addWidget(combo);
  hbox->addSpacing(15);

  label = new QLabel("Arch", this);
  hbox->addWidget(label);

  connect(combo, qOverload<const QString &>(&QComboBox::activated),
      label, &QLabel::setText);
}

在示例中,从组合框中选择的项目显示在标签中。

QStringList distros = {"Arch", "Xubuntu", "Redhat", "Debian",
    "Mandriva"};

一个 QStringList 存储组合框的数据。我们有一个 Linux 发行版的列表。

combo = new QComboBox();
combo->addItems(distros);

创建了一个 QComboBox,并使用 addItems 方法插入项目。

connect(combo, qOverload<const QString &>(&QComboBox::activated),
    label, &QLabel::setText);

组合框的 activated 信号连接到标签的 setText 插槽。

main.cpp
#include <QApplication>
#include "combobox.h"

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

  QApplication app(argc, argv);

  ComboBoxEx window;

  window.resize(300, 150);
  window.setWindowTitle("QComboBox");
  window.show();

  return app.exec();
}

这是应用程序的主文件。

QComboBox
图:QComboBox

Qt5 QSpinBox

QSpinbox 是一个用于处理整数和离散值集的控件。在我们的代码示例中,我们有一个微调框控件。我们可以选择数字 0..99。当前选择的值显示在标签控件中。

spinbox.h
#pragma once

#include <QWidget>
#include <QSpinBox>

class SpinBox : public QWidget {

  Q_OBJECT

  public:
    SpinBox(QWidget *parent = nullptr);

  private:
    QSpinBox *spinbox;
};

这是微调框示例的头文件。

spinbox.cpp
#include <QHBoxLayout>
#include <QLabel>
#include "spinbox.h"

SpinBox::SpinBox(QWidget *parent)
    : QWidget(parent) {

  auto *hbox = new QHBoxLayout(this);
  hbox->setSpacing(15);

  spinbox = new QSpinBox(this);
  auto *lbl = new QLabel("0", this);

  hbox->addWidget(spinbox);
  hbox->addWidget(lbl);

  connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
    lbl, qOverload<int>(&QLabel::setNum));
}

我们将微调框放在窗口上,并将其 valueChanged 信号连接到 QLabelsetNum 插槽。

connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
  lbl, qOverload<int>(&QLabel::setNum));

我们需要使用 qOverload 两次,因为信号和插槽都被重载了。

main.cpp
#include <QApplication>
#include "spinbox.h"

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

  QApplication app(argc, argv);

  SpinBox window;

  window.resize(250, 150);
  window.setWindowTitle("QSpinBox");
  window.show();

  return app.exec();
}

这是主文件。

QSpinBox
图:QSpinBox

Qt5 QLineEdit

QLineEdit 是一个允许输入和编辑单行纯文本的控件。QLineEdit 控件有撤销/重做、剪切/粘贴和拖放功能。

在我们的示例中,我们显示了三个标签和三个行编辑框。

ledit.h
#pragma once

#include <QWidget>

class Ledit : public QWidget {

  public:
    Ledit(QWidget *parent = nullptr);
};

该示例的头文件。

ledit.cpp
#include <QGridLayout>
#include <QLabel>
#include <QLineEdit>
#include "ledit.h"

Ledit::Ledit(QWidget *parent)
    : QWidget(parent) {

  auto *name = new QLabel("Name:", this);
  name->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

  auto *age = new QLabel("Age:", this);
  age->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

  auto *occupation = new QLabel("Occupation:", this);
  occupation->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

  auto *le1 = new QLineEdit(this);
  auto *le2 = new QLineEdit(this);
  auto *le3 = new QLineEdit(this);

  auto *grid = new QGridLayout();

  grid->addWidget(name, 0, 0);
  grid->addWidget(le1, 0, 1);
  grid->addWidget(age, 1, 0);
  grid->addWidget(le2, 1, 1);
  grid->addWidget(occupation, 2, 0);
  grid->addWidget(le3, 2, 1);

  setLayout(grid);
}

我们显示了三个标签和三个行编辑框。这些控件使用 QGridLayout 管理器进行组织。

main.cpp
#include "ledit.h"
#include <QApplication>

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

  QApplication app(argc, argv);

  Ledit window;

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

  return app.exec();
}

这是主文件。

QLineEdit
图:QLineEdit

状态栏

状态栏是一个用于显示应用程序状态信息的面板。

在我们的示例中,我们有两个按钮和一个状态栏。如果我们单击按钮,每个按钮都会显示一条消息。状态栏控件是 QMainWindow 控件的一部分。

statusbar.h
#pragma once

#include <QMainWindow>
#include <QPushButton>

class Statusbar : public QMainWindow {

  Q_OBJECT

  public:
    Statusbar(QWidget *parent = nullptr);

  private slots:
    void OnOkPressed();
    void OnApplyPressed();

  private:
    QPushButton *okBtn;
    QPushButton *aplBtn;
};

该示例的头文件。

statusbar.cpp
#include <QLabel>
#include <QFrame>
#include <QStatusBar>
#include <QHBoxLayout>
#include "statusbar.h"

Statusbar::Statusbar(QWidget *parent)
    : QMainWindow(parent) {

  auto *frame = new QFrame(this);
  setCentralWidget(frame);

  auto *hbox = new QHBoxLayout(frame);

  okBtn = new QPushButton("OK", frame);
  hbox->addWidget(okBtn, 0, Qt::AlignLeft | Qt::AlignTop);

  aplBtn = new QPushButton("Apply", frame);
  hbox->addWidget(aplBtn, 1, Qt::AlignLeft | Qt::AlignTop);

  statusBar();

  connect(okBtn, &QPushButton::clicked, this, &Statusbar::OnOkPressed);
  connect(aplBtn, &QPushButton::clicked, this, &Statusbar::OnApplyPressed);
}

void Statusbar::OnOkPressed() {

  statusBar()->showMessage("OK button pressed", 2000);
}

void Statusbar::OnApplyPressed() {

 statusBar()->showMessage("Apply button pressed", 2000);
}

这是 statusbar.cpp 文件。

auto *frame = new QFrame(this);
setCentralWidget(frame);

QFrame 控件放置在 QMainWindow 控件的中心区域。中心区域只能容纳一个控件。

okBtn = new QPushButton("OK", frame);
hbox->addWidget(okBtn, 0, Qt::AlignLeft | Qt::AlignTop);

aplBtn = new QPushButton("Apply", frame);
hbox->addWidget(aplBtn, 1, Qt::AlignLeft | Qt::AlignTop);

我们创建了两个 QPushButton 控件并将它们放置在一个水平框中。按钮的父级是 frame 控件。

statusBar();

要显示状态栏控件,我们调用 QMainWindow 控件的 statusBar 方法。

void Statusbar::OnOkPressed() {

  statusBar()->showMessage("OK button pressed", 2000);
}

showMessage 方法在状态栏上显示消息。最后一个参数指定消息在状态栏上显示的时间(以毫秒为单位)。

main.cpp
#include <QApplication>
#include "statusbar.h"

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

  QApplication app(argc, argv);

  Statusbar window;

  window.resize(300, 200);
  window.setWindowTitle("QStatusBar");
  window.show();

  return app.exec();
}

这是主文件。

Statusbar example
图:状态栏示例

在本 Qt5 教程中,我们介绍了几个 Qt5 控件。