首页 > 其他分享 >Qt 入门

Qt 入门

时间:2024-09-30 17:34:10浏览次数:6  
标签:窗口 Qt 对象 应用程序 信号 按钮 入门

1、概述

1.1、什么是Qt

Qt是一个跨平台的C++图形用户界面应用程序框架,它为应用程序开发者提供建立艺术级图形界面的所有功能,它是完全面向对象的,很容易扩展,并且允许真正的组件编程。

1.2、Qt的发展史

1991年Qt最早由奇趣科技开发;

1996年进入商业领域,它也是目前流行的Linux桌面环境KDE的基础;

2008年,奇趣科技被诺基亚公司收购,Qt称为诺基亚旗下的编程语言;

2012年,Qt又被Digia公司收购;

2014年4月,跨平台的集成开发环境Qt Creator 3.1.0 发布,同年5月20日配发了Qt5.3正式版,至此Qt实现了对ios、Android、WP等个平台的全面支持。当前Qt版本为5.9.0.

1.3、支持的平台

Windows - XP、Vista、Win7、Win8、Win2008、Win10;

Unix、X11 - Linux、Sun Solaris、HP-UX、Compaq Tru64 UNIX、IBM ATX、SGI IRIX、FreeBSD、BSD/OS 和其他很多X11平台。

Macintosh - Mac OS X;

Embedded - 有帧缓冲支持的嵌入式Linux平台,WIndows CE。

1.4、Qt 版本

Qt 按照不同的版本发行,分为商业版和开源版。

商业版:为商业软件提供开发,它们提供传统商业软件发行版,并且提供在商业有效期内的免费升级和技术支持服务;

开源的LGPL版本:为了开发自有而设计的开放源码软件,它提供了和商业版本同样的功能,在GNU通用公共许可下,它是免费的。

1.5、Qt 的下载与安装

下载地址:http://www.qt.io/download-open-source/

1.6、Qt 的优点

  • 跨平台,几乎支持所有的平台;
  • 接口简单,容易上手,学习Qt框架对学习其他框架有参考意义;
  • 一定程度上简化了内存回收机制;
  • 开发效率高,能够快速地构建应用程序;
  • 有很好地社区氛围,市场份额在缓慢上升;
  • 可以进行嵌入式开发。

1.7、成功案例

  • Linux 桌面环境KDE;
  • WPS Office 办公软件;
  • Skype 网络电话;
  • Google Earth 谷歌地图;
  • VLC 多媒体播放器;
  • VirtualBox 虚拟机软件。

2、创建 Qt 项目

#include "mywidget.h"

#include <QApplication> // 包含一个应用程序类的头文件
#include <QLocale>
#include <QTranslator>

// main 程序入口 argc命令行变量的数量 argv  命令行变量的数组
int main(int argc, char *argv[])
{
    // 应用程序对象,在Qt中应用程序对象有且仅有一个
    QApplication a(argc, argv);
    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "TestDesktopProject_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }
    
    // 窗口对象 MyWidget父类 继承自 QWidget
    MyWidget w;
    // 窗口对象 默认不会显示,必须要调用show方法显示窗口
    w.show();

    // 让应用程序进入消息循环,让代码“阻塞”到这行
    return a.exec();
}

2.1、.pro 文件

QT       += core gui # Qt包含的模块,包含core和gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets # 如果Qt的主版本号大于4,则包含widget模块

TARGET = TestDesktopProjecttttt # 目标,生成的.exe程序的名称
TEMPLATE = app # 应用程序模板 Application,告诉qmake为这个应用程序生成哪种makefle。
# 下面是可供使用的选择
# app - 建立一个应用程序的makefile。这是默认值,所以如果模板没有被指定,这个将被使用
# lib - 建立一个库的makefile
# vcapp - 建立一个应用程序的VisualStudio项目文件
# vclib - 建立一个库的VisualStudio项目文件
# subdirs - 这是一个特殊的模板,它可以创建一个能够进入特定目录并且为一个项目文件生成makefile并且为它调用make的makefile

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

# 源文件
SOURCES += \
    main.cpp \
    mainwindow.cpp \
    mywidget.cpp

# 头文件
HEADERS += \
    mainwindow.h \
    mywidget.h

FORMS += \
    mainwindow.ui

TRANSLATIONS += \
    TestDesktopProject_zh_CN.ts
CONFIG += lrelease
CONFIG += embed_translations

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

2.2、快捷键

注释:ctrl + /
运行:ctrl + r
编译:ctrl + b
字体缩放:ctrl + 鼠标滚轮
查找:ctrl + f
整行移动:ctrl + shift + ↑或者↓
帮助文档:F1
自动对齐:ctrl + i
同名之间的.h和.cpp切换:F4

3、常用 API

3.1、按钮 QPushButton

// 自定义控件
class MyWidget: public QWidget {
    Q_OBJECT // Q_OBJECT宏,允许类中使用信号和槽的机制
public:
    MyWidget(QWidget* parent = 0) {
        // 设置窗口的标题
        setWindowTitle("这是窗口的标题");
        // 重置窗口的大小(用户可以拖拽)
        resize(400, 300);
        // 设置窗口的固定大小(用户无法拖拽)
        setFixedSize(400, 400);

        // 创建一个按钮
        QPushButton* btn = new QPushButton();
        // 让btn对象依赖在 MyWidget 窗口中
        btn->setParent(this);
        // 显示文本
        btn->setText("第一个按钮");
        btn->resize(100, 50);
        btn->show(); // 以顶层的方式弹出窗口控件

        // 创建第二个按钮 按照控件的大小窗口
        QPushButton* btn2 = new QPushButton("第二个按钮", this);
        // 移动按钮位置
        btn2->move(0, 100);

    }

    ~MyWidget() {}
};

4、对象模型(对象树)

在Qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个parent到底是干什么的。

QObject是以对象树的形式组织起来的。

  • 当你创建一个QObject对象时,会看到QObject的构造函数接收一个QObject指针作为参数,这个参数就是parent,也就是父对象指针。这相当于,在创建QObject对象会有自动添加到其父对象的children()列表;
  • 当父对象析构的时候,这个列表中的所有父对象也会被析构(注意,这里的父对象并不是继承意义上的父类!这种机制在GUI程序设计中相当有用,例如,一个按钮有一个QShortcut(快捷键)对象作为其子对象,当我们删除按钮的时候,这个快捷键理应被删除,这是合理的;

QWidget是能够在屏幕上显示的一切组件的父类。

  • QWidget继承自QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。例如,当用户关闭一个对话框的对象,应用程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该一起被删除,事实就是如此,因为这些都是对话框的子组件。

当创建的对象在堆区的时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作,该对象会放入到对象树中,这一定程度上简化了内存回收机制。

5、Qt 窗口坐标体系

坐标体系:以左上角为原点(0,0),X向右增加,Y向下增加。

对于嵌套窗口,其坐标是相对于父窗口来说的。

6、信号和槽

connect(信号的发送者, 发送的具体信号, 信号的接收者, 信号的处理(槽函数))

信号和槽的优点:松散耦合,信号发送端和接收端本身是没有关联的,通过connect连接在一起。

当信号和槽出现重载:需要利用函数指针,明确指向函数的地址。

// 自定义控件
class MyWidget: public QWidget {
    Q_OBJECT // Q_OBJECT宏,允许类中使用信号和槽的机制
public:
    MyWidget(QWidget* parent = 0): QWidget(parent) {
        // 设置窗口的标题
        setWindowTitle("这是窗口的标题");
        // 重置窗口的大小(用户可以拖拽)
        resize(400, 300);
        // 设置窗口的固定大小(用户无法拖拽)
        setFixedSize(400, 400);

        // 创建一个自己的按钮
        MyPushButton* btn3 = new MyPushButton(this);
        btn3->setText("我自己的按钮");
        btn3->move(200, 0);

        // 需求:点击我的按钮,关闭窗口
        // 参数1:信号的发送者;参数2:发送的信号(函数的地址);参数3:信号的接受者;参数4:信号处理函数(槽函数)
        connect(btn3, &MyPushButton::clicked, this, &MyWidget::close);
        // 也可以使用父类函数地址:connect(btn3, &QPushButton::clicked, this, &QWidget::close);
    }

    ~MyWidget() {
        qDebug() << "MyWidget析构函数";
    }
};

案例2:

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr) {}

signals:

public slots:
    // 早期Qt版本,必须写到public slots下,高级版本可以写到public或者全局下
    // 返回值void,需要声明,也需要实现
    // 可以有参数,也可以发生重载
    void treat()
    {
        qDebug() << "请老师吃饭";
    }

    void treat(const QString& foodName) {
        qDebug() << "请老师吃" << foodName;
    }

};

class Teacher: public QObject
{
    Q_OBJECT
public:
    Teacher(QObject* parent = nullptr) {}

signals:
    // 自定义信号,写道signals下
    // 返回值是void,只需要声明,不需要实现
    // 可以有参数,可以重载
    void hungry();

    void hungry(const QString& foodName);
public slots:

};

namespace Ui {

class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = 0)
        : QWidget{parent}
    {
        // 创建一个老师对象
        this->mTeacher = new Teacher(this);

        // 创建一个学生对象
        this->mStudent = new Student(this);

        // 老师饿了,学生请客吃饭的连接
        void(Teacher::*teacherSignal1)(void) = &Teacher::hungry;
        void(Student::*studentSlot1)(void) = &Student::treat;
        connect(mTeacher, teacherSignal1, mStudent, studentSlot1);

        // 带参数的连接
        // 函数指针 -> 函数地址
        void(Teacher::*teacherSignal2)(const QString&) = &Teacher::hungry;
        void(Student::*studentSlot2)(const QString&) = &Student::treat;
        connect(mTeacher, teacherSignal2, mStudent, studentSlot2); // 注意信号和槽函数的参数要一致

        // 调用下课函数
        classIsOver();

        // 点击一个 下课的按钮,再触发下课
        QPushButton* btn = new QPushButton("下课", this);
        // 重置窗口大小
        this->resize(600, 400);
        connect(btn, &QPushButton::clicked, mTeacher, teacherSignal1); // 点击按钮,触发下课
        
        // 断开信号
        disconnect(mTeacher, teacherSignal2, mStudent, studentSlot2);
        
        // 拓展
        // 1、信号是可以连接信号的
        // 2、一个信号可以连接多个槽函数
        // 3、多个信号可以连接同一个槽函数
        // 4、信号和槽函数的参数,必须类型一一对应
        // 5、信号和槽的参数个数:信号的参数个数可以多于槽函数的参数个数
        
        // 6、Qt4版本以前的信号和槽的连接方式
        // connect(信号发送者, SIGNAL(信号函数()), 信号接收者, SLOT(槽函数()));
        // Qt4版本优点:参数直观;缺点:类型不做检测
        // Qt5以上支持Qt4的版本写法,反之不支持
    }

    ~Widget() {}

signals:

private:
    Teacher* mTeacher;
    Student* mStudent;

    /**
     * @brief 下课了,触发老师饿了的信号
     */
    void classIsOver()
    {
        // 下课函数调用后,触发老师饿了的信号,使用emit关键字
        emit mTeacher->hungry();
        emit mTeacher->hungry("宫保鸡丁");
    }
};
}

 

 

 

 

 

 

 

 

1

标签:窗口,Qt,对象,应用程序,信号,按钮,入门
From: https://www.cnblogs.com/aoe1231/p/18441541

相关文章

  • Docker入门实践(五)
    什么是容器?定义容器是每个应用组件的独立进程,它完全和你机器的其他东西隔离。独立性:每个容器包含所有它需要的功能,不依赖于主机上预安装的依赖项。隔离行:由于容器是隔离运行的,它们对主机和其他容器的影响最小,增加了应用的安全性。独立性:每个容器独立管理,删除一个容器不会......
  • WPF MVVM入门系列教程(二、依赖属性)
    说明:本文是介绍WPF中的依赖属性功能,如果对依赖属性已经有了解了,可以浏览后面的文章。 为什么要介绍依赖属性在WPF的数据绑定中,密不可分的就是依赖属性。而MVVM又是跟数据绑定紧密相连的,所以在学习MVVM之前,很有必须先学习一下依赖属性。 依赖属性(DepencencyProperty)是什......
  • 基于PyQt5和SQLite的数据库操作程序
    基于PyQt5和SQLite的数据库操作程序:功能解析在现代办公和数据处理中,数据库操作是不可或缺的一部分。然而,传统的数据库管理工具往往界面复杂,操作繁琐,对于非专业人士来说存在一定的学习曲线。为了解决这个问题,我们开发了一款基于PyQt5和SQLite的数据库操作程序。该程序提供了一......
  • Qt项目中,在main.cpp中定义了一个自定义组件,但是在编译的时候报错`undefined reference
    1、问题描述我在测试Qt项目的main.cpp中编写了如下代码:classMyWidget1:publicQWidget{Q_OBJECT};//main程序入口argc命令行变量的数量argv命令行变量的数组intmain(intargc,char*argv[]){//应用程序对象,在Qt中应用程序对象有且仅有一个QAppl......
  • MongoDB入门
    MongoDB是一个基于分布式文件存储的数据库,由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。下载DownloadMongoDBCommunityServer|MongoDBMongoDB的基本操作添加数据db.collection.insertOne(document)//插入单个文档db.collection.insertMany([......
  • Qt/C++ 音视频开发 - FFmpeg 安卓版
    Qt/C++音视频开发-FFmpeg安卓版介绍FFmpeg是一个开源的多媒体框架,它可以用来录制、转换和流式传输音视频。在Qt/C++开发中,FFmpeg可以用于处理各种音视频任务,例如转码、推流等。将FFmpeg集成到安卓平台上,可以实现强大的移动端音视频处理功能。应用使用场景视频......
  • [Python数据分析]最通俗入门Kmeans聚类分析,可视化展示代码。
     什么是k-means分析?【头条@William数据分析,看原版】    想象一下,你有一堆五颜六色的糖果,你想把它们按照颜色分成几堆。k-means分析就是这么一个自动分类的过程。它会根据糖果的颜色特征,把它们分成若干个组,每个组里的糖果颜色都比较相似。更专业一点说,k-means分析是一......
  • 快速入门Java中的HTTP请求
    1.使用java.net.HttpURLConnectionJava标准库中的HttpURLConnection是最基本的方式,用于发送HTTP请求。示例:发送GET请求发送POST请求2.使用ApacheHttpClientApacheHttpClient是一个强大的HTTP客户端库,支持高级HTTP通信功能。添加依赖如果你使用Maven,添加以下依赖到你......
  • C++入门
    第1节:开发环境的搭建与配置1.1目标在本节课中,学生将学习如何在Windows上搭建一个现代化的C++开发环境,并使用VSCode和CMake工具进行C++程序的开发与调试。学生将掌握以下内容:安装VSCode及C++插件安装MinGW或其他C++编译器安装并配置CMake创建并编译第一个C++项目使用VSCod......
  • 从入门到精通,一份完整的黑客技术成长清单
    在2017年,一个名叫“AwesomeHacking”的GitHub项目曾引发大量网友的关注,这个项目是由@HackwithGithub维护的,这是一个经常会发布一些最新安全开源项目和黑客技巧的Twitter账户。“AwesomeHacking”是一份完整的黑客技术成长清单,里边索引了数十个不同方向的黑客技能图谱。如......