点击 <C 语言编程核心突破> 快速C语言入门
Qt学习总结
- 前言
- 五 Hello Qt!
- 六 Qt控件和事件
- 七 Qt信号和槽
- 八 Qt自定义信号和槽
- 总结
前言
要解决问题: 学习qt最核心知识, 多一个都不学.
五 Hello Qt!
现在我们已经有了一个空窗口工程, 传统上, 我们要实现一个"Hello Qt !"的程序,
双击Widget.ui
, 进入设计界面
鼠标右键点击Label
不要松手, 拖入右边的界面中
双击TextLabel
, 改成Hello Qt !
,
鼠标右键Hello Qt !
, 点击改变格式文本, 更改文字的字号,大小.
更改字体: 点击Hello Qt !
在属性中点击font
字体, 调整字体.
运行程序:
效果:
恭喜你, 写了第一个Qt
程序.
六 Qt控件和事件
Qt的控件可以分为基本控件和高级控件两种类型,其中基本控件包括按钮、标签、文本框、进度条等常用控件,
高级控件包括表格、树形控件、列表、对话框等更加复杂的控件。
通过这些控件的组合和设置属性,我们可以实现我们所需的用户界面。
Qt的事件机制允许我们在用户交互时捕捉到相应的事件,如按钮被单击、鼠标移动、键盘按下等。
我们可以通过重载控件的事件处理函数来处理这些事件,例如QPushButton的clicked()信号就是当用户单击该按钮时触发的事件。
Qt的控件和事件机制为我们设计和实现用户界面提供了强大的支持,使得我们可以轻松地实现复杂的图形化交互应用程序。
七 Qt信号和槽
Qt信号和槽是一种重要的机制,用于在对象之间进行通信。
它们是Qt框架中最强大的特性之一。
信号是一种事件,当发生某些特定的情况时,对象发射信号。
例如,当用户单击按钮或窗口关闭时,对象会发射相应的信号。
槽是一种方法,当一个信号发射时,与之相关联的槽将被调用。
槽可以执行任何操作,例如更改部件属性、计算数据等等。
一个对象可以有多个信号和槽,它们可以相互连接。
通过使用信号和槽,Qt提供了一种非常方便的方法来实现事件处理和通信。
它可以减少代码的重复性,使程序更加模块化和易于维护。
使用信号和槽需要遵循以下步骤:
-
定义信号:在类中声明信号,以便对象可以发射它。
-
定义槽:在类中声明槽,以便当信号被发射时可以调用它.
3. 连接信号和槽:使用QObject::connect()函数连接信号和槽。
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 链接信号与槽 谁发出信号 发出什么信号 谁处理信号 怎么处理connect(ui->CancelButton, &QPushButton::clicked, this,&Widget::on_CancelButton_clicked);
}
以下是一个简单的示例代码:
Widget.h
, 除了pushButton_clicked()
函数, 其余的基本自动给出
#ifndef WIDGET_H
#define WIDGET_H#include <QMessageBox>
#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui
{
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void pushButton_clicked();private:Ui::Widget *ui;
};
#endif // WIDGET_H
main.cpp
, 全部自动给出
#include "Widget.h"#include <QApplication>
#include <QLocale>
#include <QTranslator>int main(int argc, char *argv[])
{QApplication a(argc, argv);QTranslator translator;const QStringList uiLanguages = QLocale::system().uiLanguages();for (const QString &locale : uiLanguages) {const QString baseName = "Learn_10_" + QLocale(locale).name();if (translator.load(":/i18n/" + baseName)) {a.installTranslator(&translator);break;}}Widget w;w.show();return a.exec();
}
Widget.cpp
, 除了自己实现pushButton_clicked()
, 以及连接clicked
信号与pushButton_clicked
槽函数, 其余自动给出
#include "Widget.h"
#include "./ui_Widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// button发出clicked信号, widget接收到信号, 运行pushButton_clickedconnect(ui->pushButton, &QAbstractButton::clicked, this,&Widget::pushButton_clicked);
}Widget::~Widget()
{delete ui;
}void Widget::pushButton_clicked()
{QMessageBox::information(this, "信息", "按钮被点击");
}
Learn_10_zh_CN.ts
, 全部自动给出
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN"></TS>
ui_Widget.h
, 拖控件, 改字体, 其余全部自动给出.
/********************************************************************************
** Form generated from reading UI file 'Widget.ui'
**
** Created by: Qt User Interface Compiler version 6.5.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/#ifndef UI_WIDGET_H
#define UI_WIDGET_H#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>QT_BEGIN_NAMESPACEclass Ui_Widget
{
public:QWidget *widget;QVBoxLayout *verticalLayout;QLabel *label;QPushButton *pushButton;void setupUi(QWidget *Widget){if (Widget->objectName().isEmpty())Widget->setObjectName("Widget");Widget->resize(271, 126);widget = new QWidget(Widget);widget->setObjectName("widget");widget->setGeometry(QRect(20, 10, 227, 107));verticalLayout = new QVBoxLayout(widget);verticalLayout->setObjectName("verticalLayout");verticalLayout->setContentsMargins(0, 0, 0, 0);label = new QLabel(widget);label->setObjectName("label");QFont font;font.setFamilies({QString::fromUtf8("\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B")});font.setBold(true);label->setFont(font);verticalLayout->addWidget(label);pushButton = new QPushButton(widget);pushButton->setObjectName("pushButton");QFont font1;font1.setFamilies({QString::fromUtf8("\351\230\277\351\207\214\345\267\264\345\267\264\346\231\256\346\203\240\344\275\223 B")});font1.setPointSize(14);font1.setBold(true);pushButton->setFont(font1);verticalLayout->addWidget(pushButton);retranslateUi(Widget);QMetaObject::connectSlotsByName(Widget);} // setupUivoid retranslateUi(QWidget *Widget){Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));label->setText(QCoreApplication::translate("Widget", "<html><head/><body><p><span style=\" font-size:36pt; font-weight:700;\">Hello QT !</span></p></body></html>", nullptr));pushButton->setText(QCoreApplication::translate("Widget", "PushButton", nullptr));} // retranslateUi};namespace Ui {class Widget: public Ui_Widget {};
} // namespace UiQT_END_NAMESPACE#endif // UI_WIDGET_H
以上代码基本都是Qtcreator
的框架自动给出的, 真正需要我们编写的只是UI
部分(拖动控件改个名字)和信号与槽连接的部分, 及槽函数, 看着很多, 其实如果熟悉流程, 不会超过五分钟.
运行效果:
总之,信号和槽是Qt的核心特性之一,使得对象之间的通信变得非常简单。在编写Qt应用程序时,通常需要使用信号和槽机制来实现事件处理和数据通信。
八 Qt自定义信号和槽
Qt提供了一些常见的信号和槽, 如按钮的clicked()
信号和QTimer
的timeout()
信号,但有时你需要定义自己的信号和槽。
以下是定义自定义信号和槽的步骤:
- 定义信号:在类中声明一个信号,可以理解为一个函数声明,但没有实现。
注意,使用自定义信号和槽时,必须在类定义中包含Q_OBJECT
宏,并且该类必须是QObject
的子类。
#ifndef MYCLASS_H
#define MYCLASS_H#include <QDebug>
#include <QObject>class MyClass : public QObject
{Q_OBJECTpublic:explicit MyClass(QObject *parent = nullptr);void myMethod();signals:void mySignal(int);public slots:void mySlot();
};#endif // MYCLASS_H
- 激发信号:在类的某个方法中使用
emit
关键字来激发该信号。
void MyClass::myMethod()
{int value = 1000;emit mySignal(value);
}
- 定义槽:在类中声明一个槽,可以理解为一个函数,必须在类外有定义, 且为public, 否则无法调用。
void MyClass::mySlot()
{qDebug() << "mySlot:";
}
- 连接信号和槽:在应用程序的合适位置使用
connect()
方法来连接信号和槽。
连接一个信号和槽,使得当信号激发时,槽函数将被自动调用。
这种connet()
的方法是将信号放在SIGNAL
这个宏中, 宏将函数扩展为字符串"mySignal(int)"
, 注意, 对于含有参数的信号, 其格式要求是函数名(形参类型)
, mySignal(int)
对于槽函数则放在SLOT
宏中, 也会将函数扩展为字符串, 函数格式要求与信号一致.
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);myc = new MyClass;myt = new QTimer;// 谁, 发出信号, 谁, 接收信号做什么connect(myc, SIGNAL(mySignal(int)), myt, SLOT(start(int)));connect(myt, SIGNAL(timeout()), myc, SLOT(mySlot()));
}
- 设计一个按钮
pushbutton
, 按下调用myMethod()
函数, 设计一个stop
按钮, 按下调用Qtimer的stop()
函数.
void Widget::on_pushButton_clicked()
{this->myc->myMethod();
}void Widget::on_stopButton_clicked()
{this->myt->stop();
}
在上面的例子中,当按下pushbutton
时, mySignal
信号被激发,接着QTimer
的start()
方法将被调用,而在QTimer
超时时,mySlot
方法将被调用, 输出 "mySlot"
。
当按下stop
按钮时, 计时器中断, 不再调用mySlot()
.
使用自定义信号和槽可以使Qt应用程序更加灵活和可扩展,因为你可以定义和连接任何你需要的信号和槽,以实现特定的功能和交互。
总结
五 Hello Qt!
六 Qt控件和事件
七 Qt信号和槽
八 Qt自定义信号和槽
点击 <C 语言编程核心突破> 快速C语言入门