【QT开发笔记-基础篇】| 第二章 常用控件 | 2.1 窗口-QWidget 发表于 2025-12-28 | 总字数: 2k | 阅读时长: 8分钟
QWidget类是所有窗口类和控件类的基类,它有以下特点:
所有窗口类的基类
Qt中有3个窗口的基类:QWidget、QMainWindow、QDialog,其中QMainWindow、QDialog都继承自QWidget
在创建Qt工程时,通常需要选择三者之一作为当前窗口的基类
所有控件类的基类
Qt中的控件,比如按钮、输入框、单选框、表格控件等,都是直接或间接地继承自QWidget
内嵌窗口、独立窗口
可以内嵌到其他窗口的内部,此时需要给其指定父窗口
可以作为独立的窗口显示,此时无需给其指定父窗口
1. 效果演示 本节演示QWidget作为内嵌窗口和独立窗口、窗口的大小和位置、窗口的标题和图标,如下:
2. 属性和方法 QWidget有很多属性,完整的可查看帮助文档,这里列出常用的属性和方法。
2.1 窗口位置 以下截图来自官方文档:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const QRect &geometry () const ;void setGeometry (int x, int y, int w, int h) ;void setGeometry (const QRect &) ;QRect frameGeometry () const void move (int x, int y) ;void move (const QPoint &) ;
2.2 窗口大小 通常,窗口可以拖动其右下角,进行放大和缩小。
可以设置窗口的最小大小和最大大小。另外,窗口可以设置为固定大小,这样窗口就不能放大和缩小
常用的设置大小的函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 QSize size () const void resize (int w, int h) ;void resize (const QSize &) ;QSize maximumSize () const ;void setMaximumSize (const QSize &) ;void setMaximumSize (int maxw, int maxh) ;QSize minimumSize () const ;void setMinimumSize (const QSize &) ;void setMinimumSize (int minw, int minh) ;void QWidget::setFixedSize (const QSize &s) ;void QWidget::setFixedSize (int w, int h) ;int height () const ;int minimumHeight () const ;int maximumHeight () const ;void setFixedHeight (int h) ;void setMaximumHeight (int maxh) ;void setMinimumHeight (int minh) ;int width () const ;int minimumWidth () const ;int maximumWidth () const ;void setFixedWidth (int w) ;void setMaximumWidth (int maxw) ;void setMinimumWidth (int minw) ;
2.3 窗口标题、图标、资源文件 设置和获取窗口的标题,直接使用如下两个函数即可:
1 2 3 QString windowTitle () const ;void setWindowTitle (const QString &) ;
设置窗口的图标,需要一个QIcon对象,如下:
1 2 3 4 5 6 7 8 QIcon windowIcon () const ;void setWindowIcon (const QIcon &icon) ;QIcon::QIcon (const QString &fileName);
2.4 获取父控件/子控件 1 2 3 QWidget *QWidget::parentWidget () const const QObjectList &QObject::children () const
2.5 信号槽 1 2 3 4 5 6 7 8 9 10 11 void showMaximized () ;void showMinimized () ;void showNormal () ;bool close () ;
3. 从零实现 从零写代码实现整体效果,以演示标签的属性以及信号槽的用法
3.1 布局 在UI设计师界面,拖拽对应的控件,修改显示的文字、控件的名称,然后完成布局
即可完成以下效果,多操作自然就熟练了(完成后的代码,会一并共享给大家的~)
布局完成效果如下:
3.2 添加资源文件 把用到的图标,作为资源文件添加到项目中,如下:
3.3 代码实现 接下来,开始写代码实现以上效果。
3.3.1 内嵌窗口、独立窗口 首先,添加字体设置和颜色设置对应的布局
在项目名右击->【Add New…】->【Qt】->【Qt Widgets Designer Form Class】,创建出新的QWidget布局和源文件,如下:
此时,新建的两个QWidget布局文件,如下:
然后,在fontform.h/.cpp文件中,实现对应的信号槽,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class FontForm : public QWidget {signals: void fontChanged (bool bold, bool italic, bool underline) ; private slots: void onChkFontClicked () ; }; FontForm::FontForm (QWidget *parent) : QWidget (parent), ui (new Ui::FontForm) { ui->setupUi (this ); connect (ui->chkBold, &QCheckBox::clicked, this , &FontForm::onChkFontClicked); connect (ui->chkItalic, &QCheckBox::clicked, this , &FontForm::onChkFontClicked); connect (ui->chkUnderline, &QCheckBox::clicked, this , &FontForm::onChkFontClicked); } void FontForm::onChkFontClicked () { emit fontChanged (ui->chkBold->isChecked(), ui->chkItalic->isChecked(), ui->chkUnderline->isChecked()) ; }
然后,在colorform.h/.cpp文件中,实现对应的信号槽,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <QButtonGroup> class ColorForm : public QWidget {signals: void colorChanged (int id) ; private slots: void onBtnGroupColorClicked (int id) ; private : QButtonGroup *btnGroupColor; }; ColorForm::ColorForm (QWidget *parent) : QWidget (parent), ui (new Ui::ColorForm) { ui->setupUi (this ); btnGroupColor = new QButtonGroup (this ); btnGroupColor->addButton (ui->radioRed, 0 ); btnGroupColor->addButton (ui->radioGreen, 1 ); btnGroupColor->addButton (ui->radioBlue, 2 ); connect (btnGroupColor, &QButtonGroup::idClicked, this , &ColorForm::onBtnGroupColorClicked); ui->radioRed->click (); } void ColorForm::onBtnGroupColorClicked (int id) { emit colorChanged (id) ; }
最后,在widget.h/.cpp文件中,实现对应的信号槽,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 #include <QButtonGroup> #include "colorform.h" class Widget : public QWidget {private slots: void onBtnGroupAlignmentClicked (int id) ; void onFontChanged (bool bold, bool italic, bool underline) ; void onColorChanged (int id) ; private : QButtonGroup *btnGroupAlignment; ColorForm *colorForm; }; #include <QPushButton> #include "fontform.h" Widget::Widget (QWidget* parent) : QWidget (parent), ui (new Ui::Widget) { ui->setupUi (this ); ui->lineEditTime->setText ("2024-12-12 12:10:00" ); btnGroupAlignment = new QButtonGroup (this ); btnGroupAlignment->addButton (ui->radioAlignLeft, 0 ); btnGroupAlignment->addButton (ui->radioAlignCenter, 1 ); btnGroupAlignment->addButton (ui->radioAlignRight, 2 ); connect (btnGroupAlignment, &QButtonGroup::idClicked, this , &Widget::onBtnGroupAlignmentClicked); ui->radioAlignCenter->click (); FontForm* fontForm = new FontForm (); ui->widgetSet->layout ()->addWidget (fontForm); fontForm->setWindowTitle ("字体设置" ); connect (fontForm, &FontForm::fontChanged, this , &Widget::onFontChanged); QPushButton* btnColor = new QPushButton ("颜色设置" ); btnColor->setStyleSheet ("QPushButton { font-size: 14px; }" ); ui->widgetSet->layout ()->addWidget (btnColor); connect (btnColor, &QPushButton::clicked, this , [=] { colorForm->show (); }); colorForm = new ColorForm (); colorForm->setWindowTitle ("颜色设置" ); colorForm->setFixedWidth (300 ); connect (colorForm, &ColorForm::colorChanged, this , &Widget::onColorChanged); ui->lineEditTime->setStyleSheet ("QLineEdit {color: red};" ); } void Widget::onBtnGroupAlignmentClicked (int id) { if (id == 0 ) { ui->lineEditTime->setAlignment (Qt::AlignLeft); } else if (id == 1 ) { ui->lineEditTime->setAlignment (Qt::AlignCenter); } else if (id == 2 ) { ui->lineEditTime->setAlignment (Qt::AlignRight); } } void Widget::onFontChanged (bool bold, bool italic, bool underline) { QFont font = ui->lineEditTime->font (); font.setBold (bold); font.setItalic (italic); font.setUnderline (underline); ui->lineEditTime->setFont (font); } void Widget::onColorChanged (int id) { if (id == 0 ) { ui->lineEditTime->setStyleSheet ("QLineEdit {color: red};" ); } else if (id == 1 ) { ui->lineEditTime->setStyleSheet ("QLineEdit {color: green};" ); } else if (id == 2 ) { ui->lineEditTime->setStyleSheet ("QLineEdit {color: blue};" ); } }
3.3.2 窗口位置、大小 首先,在widget.h文件中,声明槽函数,如下:
1 2 3 4 5 6 7 class Widget : public QWidget {private slots: void on_btnGetWindowGeometry_clicked () ; void on_btnResize_clicked () ; void on_btnMoveWindow_clicked () ; };
然后,在widget.cpp文件中,实现槽函数,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 void Widget::on_btnGetWindowGeometry_clicked () { QRect rect = this ->geometry (); QPoint topLeft = rect.topLeft (); int width = rect.width (); int height = rect.height (); ui->lineEditWindowGeometry->setText (QString ("左上角(%1,%2), 宽高(%3*%4)" ).arg (topLeft.x ()).arg (topLeft.y ()).arg (width).arg (height)); } void Widget::on_btnResize_clicked () { this ->resize (400 , 400 ); } void Widget::on_btnMoveWindow_clicked () { this ->move (100 , 100 ); }
3.3.3 窗口标题、图标 首先,在widget.h文件中,声明槽函数,如下:
1 2 3 4 5 6 class Widget : public QWidget {private slots: void on_btnSetWindowTitle_clicked () ; void on_btnUpdateWindowIcon_clicked () ; };
然后,在widget.cpp文件中,实现槽函数,如下:
1 2 3 4 5 6 7 8 9 10 11 12 QStringList icons = {":/res/star1.png" , ":/res/star2.png" , ":/res/star3.png" , ":/res/star4.png" }; int index = 0 ;void Widget::on_btnSetWindowTitle_clicked () { this ->setWindowTitle (ui->lineEditWindowTitle->text ().trimmed ()); } void Widget::on_btnUpdateWindowIcon_clicked () { this ->setWindowIcon (QIcon (icons[index++ % 4 ])); }