QT 成长笔记

一、简介

1.1 什么是Qt

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

Qt框架除了QML和Qt Creator外,‌还包括多个重要的组件和工具,‌如:‌

  • Qt Designer‌:‌用于可视化设计Qt Widgets窗口UI界面,‌支持拖放控件和布局,‌自动生成C++代码。‌
  • Qt Linguist‌:‌用于应用程序的国际化,‌支持翻译Qt应用程序中的字符串。‌
  • Qt Assistant‌:‌提供Qt框架的文档浏览器,‌帮助开发人员快速查找API文档和教程。‌
  • qmake‌:‌Qt的构建系统,‌用于自动化生成Makefile文件,‌简化编译过程。‌
  • Qt Quick Designer‌(‌在Qt Design Studio中)‌:‌专门用于设计Qt Quick应用程序的可视化工具。‌

Qt的优点

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

Qt成功案例

  1. Linux桌面环境 KDE
  2. WPS Office 办公软件
  3. Skype 网络电话
  4. Google Earth 谷歌地图
  5. VLC多媒体播放器
  6. VirtualBox虚拟机软件

1.2 什么是 Qt Creator

Qt Creator是一个跨平台的集成开发环境(‌IDE)‌,‌专为使用Qt框架进行应用程序开发而设计‌。‌它支持在Linux、‌macOS和Windows操作系统上运行,‌帮助开发者为桌面、‌移动端和嵌入式平台创建软件。‌(当前教程)

1.3 什么是qml 

  • QML(‌Qt Meta-Object Language)‌‌:‌是Qt Quick技术的一部分,‌一种声明式编程语言,‌用于描述用户界面。‌QML允许开发者以简洁的方式定义用户界面,‌同时支持与Qt原生C++代码的交互。‌之后会详细做笔记。

1.4 什么是minGW 

MinGW(‌Minimalist GNU for Windows)‌是Qt下的一种编译器工具链,‌它将经典的开源C/C++编译器GCC移植到了Windows平台,‌并包含了Win32API,‌允许开发者在Windows环境下使用GNU工具链进行开发和构建,‌生成Windows下的可执行程序‌。‌MinGW是开源免费的,‌生成的软件遵循GNU开源许可协议,‌适合用于跨平台开发或偏好开源工具链的项目。‌在Qt中,‌MinGW与MSVC是两种常用的编译方式,‌它们各有特点,‌开发者可以根据项目需求和个人偏好选择使用‌。

2、下载地址

1、官网下载: Index of /official_releases/online_installers

2、其它方法:

关注微信号:Qt君

网盘:链接:https://pan.baidu.com/s/1DaHmaEmh-Bn31TMlKs9Hww
提取码:1i13

3、配置编译套件

 

b、默认安装是minGW,如需msvc需要安装2015版本的,如果是其它版本的vs编译器,需要进行相关配置,作者qt是5.12版本的,msvc是2017的, 如下

首先克隆图中选中的 c编译器,接着进行相关配置,msvc版本是多少位的就选多少位,这里我的是msvc2017 32位版本的,配置如下,名字可以更改。

c++编译器也要进行相关配置,好了之后如下:

之后把刚刚配置好的编译器配置到构建套件中,就可以了

 4、相关文件简介

补充:

创建工程时最好不要有中文路径或者中文名字,可能会有未定义行为

 .pro文件

.pro就是工程文件(project),它是qmake自动生成的用于生产makefile的配置文件

.pro文件的写法如下:

注释  从“#”开始,到这一行结束

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

TARGET = QtDemo

  1. #工程中包含的头文件

HEADERS += include/painter.h

  1. #工程中包含的.ui设计文件

FORMS += forms/painter.ui

  1. #工程中包含的源文件

SOURCES += sources/main.cpp sources

  1. #工程中包含的资源文件

RESOURCES += qrc/painter.qrc

  1. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

这条语句的含义是,如果QT_MAJOR_VERSION大于4(也就是当前使用的Qt5更高版本)需要增加widgets模块。如果项目仅需支持Qt5也可以直接添加“QT += widgets”一句。不过为了保持代码兼容,最好还是按照QtCreator生成的语句编写。

#配置信息

CONFIG用来告诉qmake关于应用程序的配置信息。

CONFIG += c++11 //使用c++11的特性

在这里使用“+=”,是因为我们添加我们的配置选项到任何一个已经存在中。这样做比使用“=”那样替换已经指定的所有选项更安全。

解释:

  1. Qt系统提供的标准类名声明头文件没有.h后缀
  2. Qt一个类对应一个头文件,类名就是头文件名
  3. QApplication应用程序类
    1. 管理图形用户界面应用程序的控制流和主要设置。
    2. 是Qt的整个后台管理的命脉它包含主事件循环,在其中来自窗口系统和其它资源的所有事件处理和调度。它也处理应用程序的初始化和结束,并且提供对话管理
    3. 对于任何一个使用Qt的图形用户界面应用程序,都正好存在一个QApplication 对象,而不论这个应用程序在同一时间内是不是有0、1、2或更多个窗口。
  4. a.exec()

程序进入消息循环,等待对用户输入进行响应。这里main()把控制权转交给Qt,Qt完成事件处理工作,当应用程序退出的时候exec()的值就会返回。在exec()中,Qt接受并处理用户和系统的事件并且把它们传递给适当的窗口部件。

 运行效果如下开始学习把!!!

5、qt项目转vs

增加qmake环境

使用cmd命令 :qmake -tp vc   filename.pro    //注意: filenam为你的文件名字

二、基础

1、常用控件

QPushbutton (按钮)

 代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include<QPushButton>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setFixedSize(400,300); //设置主窗口尺寸
    this->setWindowTitle("Hell Qt");
    //创建按钮1
    QPushButton *pushBUtton1=new QPushButton("pushBUtton1",this);
    pushBUtton1->setGeometry(10,10,100,30);  //设置位置和大小
    //创建按钮2
    QPushButton *pushBUtton2=new QPushButton("pushBUtton2");
    pushBUtton2->setGeometry(10,100,100,30);
    pushBUtton2->setParent(this);
    
//    delete(pushBUtton1);
//    delete(pushBUtton2);
}

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

主要代码和运行效果如下:

补充:

QPushButton 需要加上对应头文件,Qt一个类对应一个头文件(没有.h结尾),类名就是头文件名.

QDockWidget
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include<QDockWidget>
#include<QPalette>
#include<QLabel>
#include<QComboBox>
#include<QPushButton>
#include<QGridLayout>

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

    QDockWidget *pDockwidget=new QDockWidget("Dock Widget",this);
    pDockwidget->setMaximumSize(400,300);
    pDockwidget->setAutoFillBackground(true);

    //使用调色板设置颜色
    QPalette pal;
    pal.setColor(QPalette::Background,Qt::cyan);
    pDockwidget->setPalette(pal);


    QLabel *pLabel=new QLabel("学历:",this);
    QComboBox *pCombx=new QComboBox(this);
    pCombx->addItem("小学:");
    pCombx->addItem("初中:");
    pCombx->addItem("高中:");

    QPushButton *pPushbt1=new QPushButton("985");
    QPushButton *pPushbt2=new QPushButton("211");

    //布局管理
    QGridLayout *pGridlayout=new QGridLayout;
    pGridlayout->addWidget(pLabel,0,0);
    pGridlayout->addWidget(pCombx,0,1);
    pGridlayout->addWidget(pPushbt1);
    pGridlayout->addWidget(pPushbt2);

    pGridlayout->setHorizontalSpacing(10);
    pGridlayout->setVerticalSpacing(10);
    pGridlayout->setContentsMargins(30,30,30,30);

    //创建部件将其放入到铆接部件中,
    QWidget *pWidget=new QWidget ;
    pWidget->setLayout(pGridlayout); //设置布局
    pDockwidget->setWidget(pWidget);

}

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

QFrame
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include<QDockWidget>
#include<QPalette>
#include<QLabel>
#include<QComboBox>
#include<QPushButton>
#include<QGridLayout>
#include<QVBoxLayout>

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

    //创建中心部件
    QWidget *pwidget_center=new QWidget;
    this->setCentralWidget(pwidget_center);

    //创建2个框架
    QFrame *qFrame1=new QFrame;
    qFrame1->setStyleSheet("background-color:yellow");
    qFrame1->setLineWidth(4);
    qFrame1->setMidLineWidth(1);
    qFrame1->setFrameShape(QFrame::Box);
    qFrame1->setFrameShadow(QFrame::Raised);//用于设置框架的“凸起”阴影效果
    QFrame *qFrame2=new QFrame;
    qFrame2->setStyleSheet("background-color:cyan");
    qFrame2->setLineWidth(1);
    qFrame2->setMidLineWidth(4);
    qFrame2->setFrameShape(QFrame::Box);
    qFrame2->setFrameShadow(QFrame::Sunken); //3D凹陷效果


    QPushButton *pPushbt=new QPushButton(qFrame1);
    pPushbt->setGeometry(20,20,40,20);

    QVBoxLayout *pVboxlt=new QVBoxLayout;
    pVboxlt->addWidget(qFrame1);
    pVboxlt->addWidget(qFrame2);

    //将部件添加到中心部件中
    pwidget_center->setLayout(pVboxlt);

}

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

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

     //组合框1:
    QGroupBox *pGroupbox1=new QGroupBox("Grop1");
    QRadioButton *pRadioBt1=new QRadioButton("Bt1");
    QRadioButton *pRadioBt2=new QRadioButton("Bt2");
    QRadioButton *pRadioBt3=new QRadioButton("Bt3");

    QVBoxLayout *pVBoxlayout=new QVBoxLayout;
    pVBoxlayout->addWidget(pRadioBt1);
    pVBoxlayout->addWidget(pRadioBt2);
    pVBoxlayout->addWidget(pRadioBt3);
    pGroupbox1->setLayout(pVBoxlayout);

    //组合框2
    QGroupBox *pGroupbox2=new QGroupBox("Grop2");
    QCheckBox *qCheckBox1=new QCheckBox("CheckBox1");
    QCheckBox *qCheckBox2=new QCheckBox("CheckBox2");
    QCheckBox *qCheckBox3=new QCheckBox("CheckBox3");
    QVBoxLayout *pVBoxlayout2=new QVBoxLayout;
    pVBoxlayout2->addWidget(qCheckBox1);
    pVBoxlayout2->addWidget(qCheckBox2);
    pVBoxlayout2->addWidget(qCheckBox3);
    pGroupbox2->setLayout(pVBoxlayout2);

    QHBoxLayout *qHBoxLayout=new QHBoxLayout;
    qHBoxLayout->addWidget(pGroupbox1);
    qHBoxLayout->addWidget(pGroupbox2);
    //创建中心部件
    QWidget *qWidget=new QWidget(this);
    qWidget->setLayout(qHBoxLayout);
    this->setCentralWidget(qWidget);
}

QCommandLinkButton 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setGeometry(20,20,500,400);
    this->setStyleSheet("QMainWindow {background-color:rgba(80,80,120,88%);}");

     QCommandLinkButton *qCommandBt=new QCommandLinkButton("test","clicked",this);
     qCommandBt->setGeometry(50,100,250,60);

     connect(qCommandBt,&QCommandLinkButton::clicked,this,[](){
        QDesktopServices::openUrl(QUrl("https://www.baidu.com/"));
     });

}

QDialogButtonBox 按钮盒
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QDialogButtonBox *pDialogBtBox=new QDialogButtonBox(this );
    pDialogBtBox->setGeometry(100,100,200,200);
    pDialogBtBox->addButton(QDialogButtonBox::Cancel);
    pDialogBtBox->button(QDialogButtonBox::Cancel)->setText("cancle");

    QPushButton *pPushBt=new QPushButton("PushBt");
    pDialogBtBox->addButton(pPushBt,QDialogButtonBox::ActionRole);
}

QScrollArea  滚动区域
#include<QScrollArea>
#include<QGridLayout>
#include<QPicture>

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

    //创建LAbel
    QLabel *pLabel=new QLabel();
    // pLabel->setScaledContents(true); // 设置标签内容缩放以适应标签大小
    QImage Timage("C:\\Users\\86173\\Desktop\\3.png");
    pLabel->setPixmap(QPixmap::fromImage(Timage));

    QScrollArea* pScrollAre=new QScrollArea;
    pScrollAre->setAlignment(Qt::AlignCenter); //剧中
    pScrollAre->setWidgetResizable(true);//设置部件可调整尺寸

    pScrollAre->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);// 设置水平滚动条始终显示
    pScrollAre->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    pScrollAre->setWidget(pLabel);

    //添加布局
    QGridLayout *pGridlayout=new QGridLayout;
    pGridlayout->addWidget(pScrollAre);

    QWidget *qWidgetCenter=new QWidget;
    qWidgetCenter->setLayout(pGridlayout);
    this->setCentralWidget(qWidgetCenter);
}

QTreeWidget  树控件
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    QTreeWidget *treeWidget =new QTreeWidget(this);

    treeWidget->setGeometry(100,100,200,200);
    // 1:添加第一级节点
      QTreeWidgetItem *topItem1=new QTreeWidgetItem( treeWidget);
      topItem1->setText(0,"清华大学.");
      topItem1->setCheckState(0,Qt::Checked);



       treeWidget->addTopLevelItem(topItem1);

      // 隐藏表头
      treeWidget->setHeaderHidden(true);
      // 展开节点
       treeWidget->expandAll();

      // 2:二级节点添加到一级节点的topItem1
      QTreeWidgetItem *item11=new QTreeWidgetItem(topItem1);
      item11->setText(0,"清华大学建筑学院.");
      item11->setCheckState(0,Qt::Checked);

      QTreeWidgetItem *item12=new QTreeWidgetItem(topItem1);
      item12->setText(0,"清华大学建筑学院.");
      item12->setCheckState(0,Qt::Checked);

      QTreeWidgetItem *item13=new QTreeWidgetItem(topItem1);
      item13->setText(0,"清华大学土木学院.");
      item13->setCheckState(0,Qt::Checked);

      QTreeWidgetItem *item14=new QTreeWidgetItem(topItem1);
      item14->setText(0,"清华大学信息科学技术学院.");
      item14->setCheckState(0,Qt::Checked);

      QTreeWidgetItem *item15=new QTreeWidgetItem(topItem1);
      item15->setText(0,"清华大学马克思主义学院.");
      item15->setCheckState(0,Qt::Checked);


      // 3:添加第一级节点
      QTreeWidgetItem *topItem2=new QTreeWidgetItem( treeWidget);
      topItem2->setText(0,"北京大学.");
      topItem2->setCheckState(0,Qt::Checked);
       treeWidget->addTopLevelItem(topItem2);

      QTreeWidgetItem *item21=new QTreeWidgetItem(topItem2);
      item21->setText(0,"北京大学数学科学学院.");
      item21->setCheckState(0,Qt::Checked);

      QTreeWidgetItem *item22=new QTreeWidgetItem(topItem2);
      item22->setText(0,"北京大学软件与微电子学院.");
      item22->setCheckState(0,Qt::Checked);

      QTreeWidgetItem *item23=new QTreeWidgetItem(topItem2);
      item23->setText(0,"北京大学新闻与传播学院.");
      item23->setCheckState(0,Qt::Checked);

      QTreeWidgetItem *item24=new QTreeWidgetItem(topItem2);
      item24->setText(0,"北京大学光华管理学院.");
      item24->setCheckState(0,Qt::Checked);

      QTreeWidgetItem *item25=new QTreeWidgetItem(topItem2);
      item25->setText(0,"北京大学医学部.");
      item25->setCheckState(0,Qt::Checked);
}

QTreeView 树视图

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

    // 1:构造model
    QStandardItemModel *sItemMode = new QStandardItemModel ;
    //设置列头
    sItemMode->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("编号.") << QStringLiteral("初中部|高中部."));

    // 创建一级节点,将它加入到sItemModel
    QList<QStandardItem*> item11;
    QStandardItem *item1=new QStandardItem(QString::number(1));
    QStandardItem *item2=new QStandardItem("初中部.");
    item11.append(item1);
    item11.append(item2);
    sItemMode->appendRow(item11);


    // 二级节点,添加到第一个一级节点
    QList<QStandardItem*> item112;
    QStandardItem *item1121=new QStandardItem(QString::number(2));
    QStandardItem *item1122=new QStandardItem(QStringLiteral("一年级."));

    item112.append(item1121);
    item112.append(item1122);
    item1->appendRow(item112);

    // 三级节点,添加到第一个二级节点
    QList<QStandardItem*> item1231;
    QStandardItem *item12311=new QStandardItem(QString::number(3));
    QStandardItem *item12312=new QStandardItem(QStringLiteral("一班."));
    item1231.append(item12311);
    item1231.append(item12312);
    item1121->appendRow(item1231);

    QList<QStandardItem*> item1232;
    QStandardItem *item12321=new QStandardItem(QString::number(3));
    QStandardItem *item12322=new QStandardItem(QStringLiteral("二班."));
    item1232.append(item12321);
    item1232.append(item12322);
    item1121->appendRow(item1232);

    QList<QStandardItem*> item1233;
    QStandardItem *item12331=new QStandardItem(QString::number(3));
    QStandardItem *item12332=new QStandardItem(QStringLiteral("三班."));
    item1233.append(item12331);
    item1233.append(item12332);
    item1121->appendRow(item1233);

    // 创建一级节点,将它加入到sItemModel
    QList<QStandardItem*> item12;

    QStandardItem *item3=new QStandardItem(QString::number(2));
    QStandardItem *item4=new QStandardItem("高中部.");

    item12.append(item3);
    item12.append(item4);
    sItemMode->appendRow(item12);

    // 2:给QTreeView应用model
    QTreeView* pTreeView=new QTreeView(this) ;
    pTreeView->setGeometry(120,120,400,300);
    pTreeView->setModel(sItemMode);
}

QStackedWidget 堆栈部件
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QListWidget* qlist=new QListWidget(this);
    qlist->setGeometry(160,160,260,200);
    qlist->insertItem(0,"Linux1");
    qlist->insertItem(1,"Linux2");
    qlist->insertItem(2,"Linux3");
    qlist->insertItem(3,"Linux4");
    qlist->insertItem(4,"Linux5");

    QLabel*    lab1=new QLabel("Linux1 Qt");
    QLabel*   lab2=new QLabel("Linux2 Qt");
    QLabel*    lab3=new QLabel("Linux3 Qt");
    QLabel*  lab4=new QLabel("Linux4 Qt");
    QLabel*  lab5=new QLabel("Linux5 Qt");


    static QStackedWidget*    statcks=new QStackedWidget(this);
    statcks->setGeometry(30,30,120,100);
    statcks->addWidget(lab1);
    statcks->addWidget(lab2);
    statcks->addWidget(lab3);
    statcks->addWidget(lab4);
    statcks->addWidget(lab5);
    statcks->insertWidget(5,lab5);
    statcks->setCurrentIndex(0); // 显示窗口

    static int num=0;
    //添加布局器
    QHBoxLayout *mlayout=new QHBoxLayout ;
    QPushButton *ptn=new QPushButton(this);
    connect(ptn,&QPushButton::clicked,[&]()mutable{
                num=num%5;
                statcks->setCurrentIndex(num++);
            });

     mlayout->setMargin(10);
     mlayout->setSpacing(20);

     mlayout->addWidget(qlist);
     mlayout->addWidget(statcks,0,Qt::AlignCenter);
     mlayout->addWidget(ptn);
    //设置比例因子
     mlayout->setStretchFactor(qlist,1);
     mlayout->setStretchFactor(statcks,5);

     QWidget *pWidget=new QWidget;
     pWidget->setLayout(mlayout);
     this->setCentralWidget(pWidget);
}

2、信号和槽机制

a、使用系统自带的信号和槽,核心代码如下:
#include<QPushButton>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setFixedSize(400,300); //设置主窗口尺寸
    this->setWindowTitle("Hell Qt");
    //创建按钮1
    QPushButton *pushBUtton1=new QPushButton("pushBUtton1",this);
    pushBUtton1->setGeometry(10,10,100,30);  //设置位置和大小

    //第一种
   //connect(pushBUtton1,&QPushButton::clicked,this,&MainWindow::close);
    //第二种
    connect(pushBUtton1,SIGNAL(clicked(bool)),this,SLOT(close()));
}
b.使用自定义信号和槽传递参数

自定义类:

class CTeacher:public QObject
{
    Q_OBJECT
public:
    CTeacher(QObject* object=nullptr):QObject(object)
    {
        void (CTeacher::*pSingProc)(QString str)=&CTeacher::sing_eat;
        void (CTeacher::*pSlotProc)(QString str)=&CTeacher::onslo_eat;
        connect(this,pSingProc,this,pSlotProc);
        // connect(this,SIGNAL(sing_eat(QString)),this,SLOT(onslo_eat(QString)));
    }
public slots:
     void onslo_eat(QString str)  //自定义槽函数
     {
          qDebug()<<str;
     }
signals:
    void sing_eat(QString str); //信号
};

创建对象并且使用:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setFixedSize(300,200);

    CTeacher *Ct=new CTeacher;
    emit Ct->sing_eat("Hello World!");  // 直接触发信号
}

运行效果

3.lambda表达式

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setFixedSize(300,200);
    static QPushButton *pushbutton=new QPushButton(this);
    pushbutton->setGeometry(80,80,60,30);

    //lambda 的使用1
    [](){
       qDebug()<<"lambda!";
    }();

    //lambda 的使用2
    static int number=10;
    auto MyLambdaFunc=[&](int  num=-1)mutable {
        number=number+num-1;
       pushbutton->setText(QString::number(number));
    };
    connect(pushbutton,&QPushButton::clicked,MyLambdaFunc);
}
运行结果

信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。

注意:

  1. 发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
  2. 信号和槽函数返回值是 void
  3. 信号只需要声明,不需要实现
  4. 槽函数需要声明也需要实现
  5. 槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
  6. 使用 emit 在恰当的位置发送信号;
  7. 使用connect()函数连接信号和槽。
  8. 任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数
  9. 信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。
  10. 如果信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少)。

4、QMainWindow

QMainWindow 是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个锚接部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。

创建菜单栏(一个)

//创建菜单栏
void MainWindow::OnCreateMenuBar()
{
    //创建菜单栏
    m_menuBar =new QMenuBar;
    //m_menuBar=this->menuBar();
    this->setMenuBar(m_menuBar);

    //创建菜单1
    QMenu *menu1=new QMenu ;
    menu1->setTitle("menu1");  //设置子菜单名字
    menu1->addAction("open");
    menu1->addAction("exit");
    //添加菜单1到菜单栏中
    m_menuBar->addMenu(menu1);

    QMenu *menu2=m_menuBar->addMenu("menu2");
    menu2->addAction("pasue");
    menu2->addAction("stop");

    //void QMenu::triggered(QAction *action)
    connect(menu1,&QMenu::triggered,this,&MainWindow::slot_clickMenu);
}

创建工具栏(多个)

void MainWindow::OnCreateToolBar()
{
    //创建工具栏
    m_toolBar=new QToolBar ;
    this->addToolBar(Qt::BottomToolBarArea,m_toolBar);
    //使用setAllowedAreas()函数指定停靠区域:
    m_toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::BottomToolBarArea);
    //m_toolBar->setMovable(false);  //禁止停靠

    //增加按钮动作
    QAction *action_=new QAction(QIcon("C:\\Users\\86173\\Desktop\\3.png"),"help");
    m_toolBar->addAction(action_);
    m_toolBar->addAction("Tool_edit");

    // void actionTriggered(QAction *action);
    connect(m_toolBar,&QToolBar::actionTriggered,this,&MainWindow::Slot_StopMove);
}

创建状态栏

void MainWindow::OnCreatStatuBar()
{
    //        QStatusBar *m_statubar=new QStatusBar;
    //        this->setStatusBar(m_statubar);

    // 创建一个QLabel作为状态栏的小部件
    QLabel *permanentWidget1 = new QLabel("tile1");
    QLabel *permanentWidget2 = new QLabel("tile2");
    // 获取状态栏指针
    QStatusBar *statusBar = this->statusBar();
    statusBar->addWidget(permanentWidget1);
    statusBar->addPermanentWidget(permanentWidget2);
    // 显示一条简单消息,‌注意这可能会覆盖或隐藏之前添加的小部件
    statusBar->showMessage("Ready", 2000); // 2000毫秒后自动消失
}

创建铆接部件(可以有多个)
QDockWidget * dock = new QDockWidget("MyDocWidget",this);
   this->addDockWidget(Qt::LeftDockWidgetArea,dock);
   //设置停靠
   dock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
   

创建中心部件

   QLineEdit *p_lineedit_=new QLineEdit;
   this->setCentralWidget(p_lineedit_);
总体效果图

5、QString 

// 构造QString
    QString str1{"Hello world!"};
    QString str2=str1;
    qDebug()<<str1;

    // append 追加
    QString str3="China";
    str3.append(str2);
    qDebug()<<qPrintable(str2);//去除""

    //sprintf 格式化参数
    str1="";
    str1.sprintf("%s:%s","Data","Year");
    qDebug()<<qPrintable(str1)<<qPrintable(QString::number(2024));// QString::number(2024)

    //arg 替换占位符
    str2.clear();
    str1=QString("%1 was born in %2").arg("sunny").arg(2000);

    // startwith   用于检查字符串是否以指定的前缀开始
    str2="hello world!";
    qDebug()<<str2.startsWith("Hello");   //默认考虑大小写。‌
    qDebug()<<str2.startsWith("hello",Qt::CaseInsensitive);  //不区分大小写
    qDebug()<<str2.startsWith("Hello",Qt::CaseInsensitive);

    //QString::contains 检查字符串中是否包含某个特定的子字符串或字符。‌
    str3="hello word!";
    qDebug()<<str3.contains("wor",Qt::CaseInsensitive);

    //toint  qstring->int
    QString strnumber{"1997"};
    bool bvalue;
    int inumber=strnumber.toInt(&bvalue);
    qDebug()<<inumber;

    //QString -> ascll
    QString strTemp="ABC abc";
    QByteArray arrByte=strTemp.toUtf8();
    for(auto i:arrByte)
        qDebug()<<i;

    //QDateTime 类
    QDateTime CTime=QDateTime::currentDateTime();
    qDebug()<<CTime;
    QString strDT=CTime.toString("yyyy-mm-dd hh:mm:ss");
    qDebug()<<strDT;

三、进阶

1、无边框拖拽移动窗口

#ifndef FRAMELESSWIDGET_H
#define FRAMELESSWIDGET_H

#include <QWidget>
#include <windows.h>        //注意头文件
#include <windowsx.h>
#include <QMouseEvent>
class FramelessWidget : public QWidget
{
    Q_OBJECT

public:
    FramelessWidget(QWidget *parent = 0);
    ~FramelessWidget();
protected:
    bool nativeEvent(const QByteArray &eventType, void *message, long *result);
    void mousePressEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
private:
    int boundaryWidth;
    QPoint clickPos;
};

#endif // FRAMELESSWIDGET_H
#include "widget.h"

FramelessWidget::FramelessWidget(QWidget *parent)
    : QWidget(parent)
{
    boundaryWidth=4;                                    //设置触发resize的宽度
    this->setWindowFlags(Qt::FramelessWindowHint);      //设置为无边框窗口
    this->setMinimumSize(45,45);                        //设置最小尺寸
    this->setStyleSheet("background:#D1EEEE");          //设置背景颜色
}
FramelessWidget::~FramelessWidget()
{

}

bool FramelessWidget::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    MSG* msg = (MSG*)message;
    switch(msg->message)
        {
        case WM_NCHITTEST:
            int xPos = GET_X_LPARAM(msg->lParam) - this->frameGeometry().x();
            int yPos = GET_Y_LPARAM(msg->lParam) - this->frameGeometry().y();
            if(xPos < boundaryWidth && yPos<boundaryWidth)                    //左上角
                *result = HTTOPLEFT;
            else if(xPos>=width()-boundaryWidth&&yPos<boundaryWidth)          //右上角
                *result = HTTOPRIGHT;
            else if(xPos<boundaryWidth&&yPos>=height()-boundaryWidth)         //左下角
                *result = HTBOTTOMLEFT;
            else if(xPos>=width()-boundaryWidth&&yPos>=height()-boundaryWidth)//右下角
                *result = HTBOTTOMRIGHT;
            else if(xPos < boundaryWidth)                                     //左边
                *result =  HTLEFT;
            else if(xPos>=width()-boundaryWidth)                              //右边
                *result = HTRIGHT;
            else if(yPos<boundaryWidth)                                       //上边
                *result = HTTOP;
            else if(yPos>=height()-boundaryWidth)                             //下边
                *result = HTBOTTOM;
            else              //其他部分不做处理,返回false,留给其他事件处理器处理
               return false;
            return true;
        }
        return false;         //此处返回false,留给其他事件处理器处理
}


void FramelessWidget::mousePressEvent(QMouseEvent *e)
{
    if(e->button()==Qt::LeftButton)
        clickPos=e->pos();
}
void FramelessWidget::mouseMoveEvent(QMouseEvent *e)
{
    if(e->buttons()&Qt::LeftButton)
        move(e->pos()+pos()-clickPos);
}

2、序列化结构体

#include <QDataStream>
#include <QFile>
#include <QDebug>


struct MyStruct {
    int id;
    QString name;
    float value;

    // 为了方便,‌我们可以添加一个构造函数来初始化结构体
    MyStruct(int id = 0, const QString &name = QString(), float value = 0.0f)
        : id(id), name(name), value(value) {}
};

// 写入结构体到QDataStream
QDataStream &operator<<(QDataStream &out, const MyStruct &structData) {
    out << structData.id << structData.name << structData.value;
    return out;
}

// 从QDataStream读取结构体
QDataStream &operator>>(QDataStream &in, MyStruct &structData) {
    in >> structData.id >> structData.name >> structData.value;
    return in;
}

// 写入结构体到文件
void writeStructToFile(const MyStruct &data, const QString &filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly)) {
        qWarning("Could not open file for writing.");
        return;
    }

    QDataStream out(&file);
    out << data;

    file.close();
}

// 从文件读取结构体
MyStruct readStructFromFile(const QString &filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning("Could not open file for reading.");
        return MyStruct();
    }

    QDataStream in(&file);


    MyStruct data;
    in >> data;
 
    file.close();
    return data;
}

// 使用示例
int main() {

    MyStruct originalData = {1, "Example", 3.14f};
    QString filePath = "C:/Users/86173/Desktop/test/qt/qianfen/untitled62/struct_data.dat";

    // 写入结构体到文件
    writeStructToFile(originalData, filePath);

    // 从文件读取结构体
    MyStruct readData = readStructFromFile(filePath);

    // 输出读取的结构体数据
    qDebug() << "Read struct:" << readData.id << readData.name << readData.value;

    return 0;
}

四、小型项目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值