Qt入门(C++)

C++/QT学习笔记 C++自带的命名空间std,要声明using namespace std;才可使用,里面是C++语言基本的APInamespace 自定义名称 {这里面可以是数据,函数,与项目相关的一些算法等 } 有点类似C语言的结构体,但又比结构体功能强大,定义到头文件中,使用时要包含头文件还要声明。 阅读详情

创建项目基类的选择

在这里插入图片描述

对于基类的选择有三个选项,分别是QMainWindow、QWidget、QDialog

基类说明
QMainWindow主窗⼝类,⼀般⽤于较为复杂的应⽤程序,除了中央客⼾区界⾯,还包括菜单栏、⼯具栏、状态栏以及多个可停靠的⼯具对话框等
QWidget最简单、最基本的窗体程序,⾥⾯可以放置多个控件实现程序功能
QDialog基于对话框的程序,对话框⼀般⽤于弹窗,也可以⽤于主界⾯显⽰。对话框是从QWidget继承⽽来的,并丰富了⼀些功能,如模态显⽰和返回值等

项目结构

在这里插入图片描述

main.cpp

主函数:
在这里插入图片描述
1.mian函数的形参是命令行参数,具体在Linux中会讲到
2.Qapplication 编写QT程序自带的类
3.创建一个控件对象并且显示出来
4.返回Qapplicaion类的对象a中的exec函数的返回值,此exec是用于让程序执行起来的

widget.h

在这里插入图片描述
1.这里的#ifndef 和 #define 是header gurad,保证头文件只被包含一次,更推荐#pragma once,因为不知道在大工程项目中会不会有与文件名重名的现象
2.class Widget: public Qwidget 创建项目时,选择的父类 ps:qt中的类和头文件名字一样.
3.QT_OBJECT是qt内置的宏,本质上是文本替换,如果某个类要使用信号和槽就需要写入这个
4.Widget(Qwidget *parent = nullptr) QT中引入了“对象树”机制,创建Qt的对象,就可以把这个对象挂到对象树上,需要通过制定父节点的方式去挂。
5.Ui:: Widget *ui是用于与form file交互的,form file 是指Forms文件夹中的文件

widget.cpp

在这里插入图片描述
1.#include "widget.h"创建项目时的头文件
2.#include "ui_widget.h" form file被qmake生成的头文件
3.后面的ui(new Ui::Widget)和 ui->setupUi(this)用于将form file生成的界面和当前的widget关联起来

widget.ui(form flie)

用于设计界面。
在这里插入图片描述
在代码层面用的是xml文件的形式编写。
在这里插入图片描述
xml的标签含义是由程序员自定义的,这里看到的标签是qt开发者制定的,类似于linux网络原理中的自定义应用层协议。

.pro(类似于linux的Makefile文件)

在这里插入图片描述
QT项目的工程文件,也是qmake工具构建的依据(qmake:一种元编程)
QT += core gui:要引入qt的模块,后面学习到一些内容的时候可能要回修改这里
CONFIG += c++11:编译选项

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

这里描述了当前项目中,参与构建的文件都有什么。会自动生成

编译过程中生成的中间文件

在这里插入图片描述
在运行一次程序之后,就会在项目目录并列的地方,多出来一个“build-xxx”目录,这个目录里面就是该项目运行过程中,生成的一些临时文件。
在这里插入图片描述

ui_widget.h

创建项目时候自动生成的,里面包含了一个 ui_widget.h的类,在widget.h和widget.cpp中都用使用到,也是用于生成界面的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在widget.cpp中widget类的构造方法使用setipUi去生成界面

.exe文件

最终生成的可执行的程序,如果直接运行,效果就是和之前的在Qt Creater中运行时相同的效果

对象树

在这里插入图片描述
问:我把代码改成这样还能够正常显示吗?答:不能
这里就不得不提出对象树这样的概念。
假设我们有现在这样的一个界面:
在这里插入图片描述
对应的对象树就是这个样子(他是一个n叉树)
在这里插入图片描述

用label实现hello world

在这里插入图片描述
代码实现:
在这里插入图片描述
问:这里的代码会不会导致内存泄露?答:不会
因为:label对象会在合适的时候被析构函数释放

在qt中用n叉树来管理控件对象,方便于在窗口关闭的时候统一释放。所以在这句代码中QLabel* label = new QLabel(this); 在new调用构造传参传this就是交给qt的对象树去管理。这里也解释了为什么上述代码会不能显示hello world,因为这里的label的作用域是在栈上的,生命周期只在构造函数中,出了构造函数就会自动销毁,所以,在窗口关闭之前就销毁了。我们就看不见。

我们可以利用以下这个小例子去证实,我们自己去新建一个mylabel类去继承Qlabel类,然后在mylabel类中实现析构函数去输出日志信息,观看是否自动调用析构函数(在关闭窗口的时候)

mylabel.h

#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
#include <iostream>

class mylabel : public QLabel
{
public:
    mylabel(QWidget* parent);
    ~mylabel();
};

#endif // MYLABEL_H

这里继承了 QLabel,在构造函数中加入传参QWidget* parent这个参数,参数用于将自己新建的对象挂到qt的对象树上,统一管理析构

mylabel.cpp

#include "mylabel.h"

mylabel::mylabel(QWidget* parent):QLabel(parent)
{

}

mylabel:: ~mylabel()
{
    std::cout<<"mylabel 被销毁了"<<std::endl;
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <mylabel.h>
#include <QLabel>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

//    QLabel* label = new QLabel(this);
//    label->setText("hello world");
//    QLabel label(this);
//    label.setText("hello world");
    mylabel* label = new mylabel(this);//传入widget的this作为parent,统一析构
    label->setText("hello world");
}

Widget::~Widget()
{
    delete ui;
}

对象树, Qt 中通过对象树, 来统一的释放界面的控件对象.Qt 还是推荐使用 new 的方式在堆上创建对象,通过对象树, 统一释放对象.创建对象的时候,在构造函数中,指定父对象(此时才会挂到对象树上)如果你的对象没有挂到对象树上,就必须要记得手动释放!!
面向对象“继承”,本质上是对现有代码进行的“扩展”

乱码解决问题

但是这里出现一个问题就是在应用程序输出的文字出现了乱码
在qt中打印日志一般都不会用cout,而是用qDebug()工具
在这里插入图片描述
后续再 Qt 中,如果想通过打印日志的方式, 输出一些调试信息,都优先使用 qDebug.虽然使用 cout 也行,但是 cout 对于编码的处理不太好,在windows 上容易出现乱码(如果是 Linux 使用 Qt Creator,一般就没事了,Linux 默认的编码一般都是 utf8)
qDebug()还可以统一关闭,因为qDebug()是一个宏封装了QDebug()对象,所以可以通过编译开关,来实现一键式关闭。

在 Qt 中打印日志,作为调试信息,使用 cout 固然可以, 但是并不是上策 (字符编码处理的不好,也不方便统一进行关闭)Qt 中推荐使用 qDebug()完成日志的打印.

初步认识connet函数

用Push button实现hello world

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    void handleClick();
    ~Widget();

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <mylabel.h>
#include <QLineEdit>
#include <QLabel>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick);
}

void Widget::handleClick()
{
    //当按钮被点击后,改变按钮文本
    if(ui->pushButton->text()== QString("hello world"))
    {
        ui->pushButton->setText("hello qt");
    }
    else
    {
        ui->pushButton->setText("hello world");
    }
}

Widget::~Widget()
{
    delete ui;
}

如何让按钮点击后有效果呢?使用qt中的信号槽机制(本质上就是给按钮点击操作,关联上一个处理函数,当用户点击的时候,就会执行这个处理函数)
使用QT中的connect函数来实现按钮点击逻辑(connet是QObject这个类提供的静态函数.这个函数的作用就是“连接信号”和“槽”)
connect(ui->pushButton,&QPushButton::clicked,this,&Widget::handleClick);
第一个参数的作用:谁发出的信号(对象)
第二个参数的作用:发出了个什么信号(这个对象的成员函数)
第三个参数的作用:谁来处理这个信号(处理信号的对象)
第四个参数的作用:具体怎么处理(处理信号对象的成员函数)

ui->pushButton代码解释:可以访问到 form fil(ui文件中的控件),在Qt designer 中创建一个控件的时候,此时就会给这个控件分配一个objectName属性,这个属性的值,要求是在界面中得到是唯一的。qmake在预处理.ui文件的时候,就会根据这里的objectName生成对应的C++代码。C++代码中改QPushButton对象的变量名字就是这里的objectName.

问:这里的objectName是怎么变成ui里面的属性(为什么ui可以->pushButtom)
在工程文件中找到该工程生成的中间文件夹里面的ui_widget.h,这个文件就是根据我们的widget.ui生成的文件,里面是一个类,而我们在UI界面中添加控件,就在这里类里面添加成员变量(成员变量的名字就是该控件的Objectname)这里值得注意的是这里的ui_widget.h中的类ui_widget被一个widget类继承了(仅仅是封装而已,并没有做出扩展,在ui_widget.h后面看到),所以我一开始看项目中的widget类时,不禁迷惑为什么是同一个名字,但是其实是两个不同类ui_widget.h的那个类被ui namespace包住了。

ui_widget.h

/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 5.14.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/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QWidget>

QT_BEGIN_NAMESPACE

class Ui_Widget
{
public:
    QLabel *label;
    QLineEdit *lineEdit;
    QPushButton *pushButton;

    void setupUi(QWidget *Widget)
    {
        if (Widget->objectName().isEmpty())
            Widget->setObjectName(QString::fromUtf8("Widget"));
        Widget->resize(800, 600);
        label = new QLabel(Widget);
        label->setObjectName(QString::fromUtf8("label"));
        label->setGeometry(QRect(360, 230, 181, 161));
        label->setLayoutDirection(Qt::LeftToRight);
        label->setAlignment(Qt::AlignCenter);
        lineEdit = new QLineEdit(Widget);
        lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
        lineEdit->setGeometry(QRect(230, 160, 151, 61));
        lineEdit->setAlignment(Qt::AlignCenter);
        pushButton = new QPushButton(Widget);
        pushButton->setObjectName(QString::fromUtf8("pushButton"));
        pushButton->setGeometry(QRect(150, 320, 141, 71));

        retranslateUi(Widget);

        QMetaObject::connectSlotsByName(Widget);
    } // setupUi

    void retranslateUi(QWidget *Widget)
    {
        Widget->setWindowTitle(QCoreApplication::translate("Widget", "Widget", nullptr));
        label->setText(QCoreApplication::translate("Widget", "hello world", nullptr));
        lineEdit->setText(QCoreApplication::translate("Widget", "hello world", nullptr));
        pushButton->setText(QCoreApplication::translate("Widget", "hello world", nullptr));
    } // retranslateUi

};

namespace Ui {
    class Widget: public Ui_Widget {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_WIDGET_H

初步认识Qt窗口坐标体系

在这里插入图片描述
规则一:坐标系的原点(0,0)就是屏幕的左上角/窗口的左上角
规则二:给Qt的某个控件,设置位置,就需要指定坐标,对于这个控件来说,坐标系原点就是相对于父窗口/控件的。如果该控件上根节点那么它的坐标系原点就是相对于整个显示器桌面。
在这里插入图片描述

代码练习:
widget.h

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    QPushButton* button = new QPushButton(this);
    button->setText("按钮");
    button->move(200,300);
}

Widget::~Widget()
{
    delete ui;
}

总结:通过控件的成员函数中move成员函数来确定控件位置,move(水平方向偏移(向右),垂直方向偏移(向下))单位是像素。

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

相关推荐

C++QT入门_c++ qt

​ Qt 是一个跨平台的C++图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。常见GUI:QT:支持多平台开发;支持css;面向对象特性体现突出;发展趋势良好。MFC:只能在windows开发;运行程序效率高;库的安全性好;public slots: // 添加槽函数private:// 重新更新// 设置 完成之后可以拉伸。

2401_87555420的博客 1743

QT/C++从新手到老手系列之QT基础篇

本系列课程励志于带领你学习QT5/C++,从开发环境(QTCreator和VS2013两种)搭建到实际项目实战,从入门到精通。每一个部分均有理论知识介绍、接口讲解、实例代码讲解,讲解过程中不断穿插老师在开发过程中遇到的问题及解决方法。本阶段主要学习Qt开发环境搭建(QTCreator及VS)、程序的发布、GUI控件的属性、方法、布局管理、容器类、QT事件处理等,学完本阶段后可以开发小型的应用程序。

Qt(C++)入门学习

本文适用于在c++ cmake项目中使用qt,需要快速入门的同学。

m0_47096428的博客 8483

C++ Qt编程

本课程以C++编程为导向来详细介绍Qt编程,课程包括十四个部分,分别介绍Qt的编程环境、窗体应用、控件应用、组件应用、文件操作、图形图像操作、多媒体应用、对系统操作、对注册表操作、数据库应用,网络应用开发、进程与线程应用、数据的加密与解密以及Qt程序打包部署;课程全部以现场编程教学,手把手的教会大家C++ Qt的编程,欢迎大家来学习。

【QT从入门helloworld到进阶QT(C++)部署YOLOV5】

Q_OBJECTpublic:private:第 7 行,定义名称空间 Ui ,里面有一个类 MainWindow ,这个 MainWindow 和第 10 行里的 MainWindow 不是同一个对象。实际上,这个文件里的 MainWindow 类有一个成员*ui 就是指向第 19 行的 Ui::MainWindow 的指针。这都是为了使用.ui 文件设计界面的。第 12 行,MainWindow 的声明中第一行是 Q_OBJECT,这是一个宏,由 Qt 进行处理,这。

weixin_47869094的博客 2126

【小白入门】Qt界面设计:利用QChart显示折线图(QT+VS C++)

【Qt软件设计(C++)】 利用QChart显示折线图QChart写在前面(可以不看)属性与配置附加包含目录显示QChart添加曲线 本文仅梳理总结自己在学习过程中的一些理解和思路,水平有限,理解粗鄙浅薄且不一定正确。文章所有观点均不保证绝对正确,请酌情参考。如果各位朋友发现任何错误请及时告诉我,大家一起讨论共同提高。 版本:QT 5.8.0+VS2013 (我的意思是如果使用其他版本出现各种问题的话,来问我也大概率没办法帮你解决问题,因为我是一只菜狗) QChart 写在前面(可以不看) 全网教程全部都是

Alvarez的博客 4195

Qt(c++)入门知识总结

qt(c++) 基础总结

weixin_45054115的博客 7410

秋招上位机开发选C#还是Qt?应届生技术路线对比与选择指南

上位机开发是工控与设备软件领域的核心岗位方向,常见技术栈分为C#与Qt两条路线。C#凭借WinForm/WPF拖拽式开发能快速产出串口助手、Modbus调试工具等项目,适合短期积累工程经验;Qt则依托C++的跨平台能力与渲染性能,在视觉检测、工业软件等岗位中更受青睐。两者均需掌握基础的串口通信、Modbus/TCP协议、PLC对接及异常处理等实践技能,而秋招求职的关键在于结合目标行业与城市岗位分布,构建可展示协议细节与项目深度的作品集。本文从技术原理、招聘门槛、项目实践到面试差异逐项拆解,为应届生提供可执行

weixin_34072296的博客 332

qt web混合编程_VS+QT混合编程(C/C++)----1入门应用,动态计算器

简介对于界面新手而言,想要玩转qt还是需要多加磨炼的,为便于学习,特开本栏,在后期学习中,也会不断更新。先看下新建完项目后会有哪些文件:在这里,新建一个名为qt的项目,生成项目中包含的文件如图所示:qt.ui为界面所在的文件qt.h为头文件qt.cpp为函数实现文件main.cpp为主函数从文件构造来看,与C/C++并没有太多的区别,老实说,确实也没有太多的区别,重点在于如何实现qt.ui中的组件...

weixin_35130354的博客 201

基于Qt实现的简易计算器(C++)

本人刚学Qt时实现了一个计算器的简单应用程序,刚好最近的程序设计训练有计算器这道题目,于是便完善了一下,拿出来分享给大家, 说不定有和我选一样的同学看到。 这是运行后的应用程序,由于我的电脑是Win7系统,所以我就参考Win7自带的应用计算器设计开发。 本程序参考《设计模式》将用户界面与业务逻辑分离开,并通过业务接口关联。 设计原则:功能模块之间需要进行解耦。 核心思想:强内聚,弱耦合...

weixin_41477765的博客 5881

基于QT(C++)实现的坦克大战

该游戏总共有35关,每关有20个敌方坦克,玩家每关3条命,因为是在个人电脑上玩所以仅实现了单人游戏击败20个敌人自动进入下一关,通过35关游戏胜利,当生命数为0或大本营被击中游戏失败玩家坦克由键盘W、S、A、D键控制移动方向,J键发射子弹,敌方坦克则自动控制我们的全局参数主要是枚举类型方向,地图数组,图像的单位尺寸,窗口长和宽用一个config.h头文件来设置这些全局参数,并由其他类进行include在动手写程序之前,要在脑中有清晰的思路。想要程序去做什么(1) 首先自己要明确自己想做什么。

神仙别闹的自留地 1254

自学技术笔记目录

Qt回顾: 第一章:Qt的概述 第二章:在Ubuntu编写第一个Qt程序 第三章:Qt的字符串和字符编码 第四章:Qt的信号和槽 第五章:Qt容器窗口(父窗口) 第六章:面向对象的Qt编程 第七章:Qt设计师使用(designer) 第八章:Qt创造器的使用(qtcreator) 第九章:资源和图像 第十章:目录与定时器 第十一章:鼠标和键盘事件 第十二章:Qt数据库(sqlite) 第十三章:QT多线程(QThread) 第十四章:Qt网络编程 第十五章:实战项目 UC回顾:(Unix和标C) UC成长之

weixin_42284219的博客 130

Qt5(C++)高级篇之6:QML常用控件自定义组件及多媒体入门

课程目标: 学习QML的标准控件编程和自定义组件编程,包括美化效果,并动手实践,自己写出代码 课程简介: 1.带领您深入学习QT5/C++:QML常用控件编程、QML的多媒体入门、逐步提升Qml编程水平。 2.所有章节均有理论知识介绍、接口讲解、实例代码讲解,讲解过程中不断穿插老师在开发过程中遇到的问题及解决方法(可以下载所有的电子课件与源码)。 课程大纲-Qt5(C++)高级篇之6:QML常用控件自定义组件及多媒体入门资料下载 第1章 QML的标准控件系列之1 (1小时23分钟 7节)

福优学苑@音视频+流媒体 1207

QT(C++)面试总结

参考博客 QT信号槽机制的优缺点 (1)问题: 为什么Qt使用信号与槽机制而不是传统的回调函数机制进行对象间的通信呢? 回调函数的本质是“你想让别人的代码执行你的代码,而别人的代码你又不能动”这种需求下产生的。 回调函数是函数指针的一种用法,如果多个类都关注某个类的状态变化,此时需要维护一个列表,以存放多个回调函数的地址。对于每一个被关注的类,都需要做类似的工作,因此这种做法效率低,不灵活。 (2)解决办法 Qt使用信号与槽机制来解决这个问题,程序员只需要指定一个类含有哪些信号函数、哪些槽函数,Qt会处理信

qq_40433783的博客 2万+

12、Qt5与GTK4框架基础入门

本文介绍了Qt5与GTK4两个用于X Window System客户端应用程序开发的框架。Qt5基于C++,提供信号和槽机制,支持丰富的GUI开发;GTK4使用C语言,作为中间层工具包简化X协议交互。文章涵盖框架安装、基础示例、信号与槽机制、观察者模式实现及简单小部件创建,并给出学习建议,帮助开发者快速入门GUI应用开发。

n7o8p的博客 94

视频教程---Qt5(C++)小白变大牛原理与实战之初级篇

视频教程---Qt5(C++)小白变大牛原理与实战之初级篇学习有效期:永久观看 学习计划:14天 ☛点击立即跟老师学习☚ 「金牌讲师带队学习,让你的问题不过夜」 讲师姓名:梅老师(技术总监、技术架构师) 讲师介绍:软件项目开发16年经验,熟练掌握QT C++,qss,java,ssh,python,html等技术,能够十分清楚的将个人掌握的技术传达给团队中的其他软件开发人员,掌握软件开发(需求-设计-开发-测试)整个流程技巧,使项目开发更加简单、、准确。 「你将学到什么?」 能够掌握QT开.

福优学苑@音视频+流媒体 879

QT(C++)游戏之坦克大战(二)

前言 上篇博客讲了整体的一个框架,这次来说一下界面设计,地图的实现,以及玩家坦克的移动。 实现 界面大小设计 根据从手机上获取的截屏,自己在根据一定的比换算,最终确定了整个界面的大小为1280x960。整个界面如果按大块来算的话是13x13的规格。其他的相关参数见表(这些参数是经历过好几次修改,最终确定下来的,废了不少的时间): 宏定义 说明 SIZE_WIDTH 1280 整个界...

CSDN-ZCL 4919

CHARLS数据库下载避坑指南:从注册到数据获取的完整流程(2023最新版)

本文提供2023年最新版CHARLS数据库下载与使用全流程指南,涵盖从注册、数据申请到清洗的高效实践。重点解析邮箱选择、协议签署等关键步骤,并分享多线程下载、格式转换等实用技巧,助力研究者快速获取并处理这一中国中老年健康研究的黄金标准数据。

red88的博客 905
上一篇: C++多态
下一篇: Qt信号与槽
Jaxsen_Huang
博客等级 码龄7年 396粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值