QT学习笔记

这里写目录标题

  • [第0课 - 开发环境搭建](#第0课 - 开发环境搭建)
  • [第1课 - GUI 程序原理分析](#第1课 - GUI 程序原理分析)
  • [第2课 - GUI 程序实例分析](#第2课 - GUI 程序实例分析)
  • [第3课 - QT 的诞生和本质](#第3课 - QT 的诞生和本质)
  • [第4课 - Hello QT](#第4课 - Hello QT)
  • [第5课 - Qt Creator工程介绍](#第5课 - Qt Creator工程介绍)
  • [第6课 - 窗口部件及窗口类型](#第6课 - 窗口部件及窗口类型)
  • [第7课 - Qt 中的坐标系统](#第7课 - Qt 中的坐标系统)
  • [第8课 - 启航!第一个应用实例](#第8课 - 启航!第一个应用实例)
  • [第9课 - 计算器界面代码重构](#第9课 - 计算器界面代码重构)
  • [第10课 - 初探 Qt 中的消息处理](#第10课 - 初探 Qt 中的消息处理)
  • [第11课 - Qt 中的字符串类](#第11课 - Qt 中的字符串类)
  • [第12课 - 计算器核心解析算法(上)](#第12课 - 计算器核心解析算法(上))
  • [第13课 - 计算器核心解析算法(中)](#第13课 - 计算器核心解析算法(中))
  • [第14课 - 计算器核心解析算法(下)](#第14课 - 计算器核心解析算法(下))
  • [第15课 - 用户界面与业务逻辑的分离](#第15课 - 用户界面与业务逻辑的分离)
  • [第16课 - Qt 对象间的父子关系](#第16课 - Qt 对象间的父子关系)
  • [第17课 - 对话框及其类型](#第17课 - 对话框及其类型)
  • [第18课 - 登录对话框实例分析](#第18课 - 登录对话框实例分析)
  • [第19课 - Qt 中的标准对话框(上)](#第19课 - Qt 中的标准对话框(上))
  • [第20课 - Qt 中的标准对话框(中)](#第20课 - Qt 中的标准对话框(中))
  • [第21课 - Qt 中的标准对话框(下)](#第21课 - Qt 中的标准对话框(下))
  • [第22课 - 布局管理器(一)](#第22课 - 布局管理器(一))
  • [第23课 - 布局管理器(二)](#第23课 - 布局管理器(二))
  • [第24课 - 布局管理器(三)](#第24课 - 布局管理器(三))
  • [第25课 - 布局管理器(四)](#第25课 - 布局管理器(四))
  • [第26课 - 布局管理综合实例](#第26课 - 布局管理综合实例)
  • [第27课 - 应用程序中的主窗口](#第27课 - 应用程序中的主窗口)
  • [第28课 - 主窗口中的工具栏](#第28课 - 主窗口中的工具栏)
  • [第29课 - 主窗口中的状态栏](#第29课 - 主窗口中的状态栏)
  • [第30课 - Qt 中的文本编辑组件](#第30课 - Qt 中的文本编辑组件)
  • [第31课 - 软件开发流程简介](#第31课 - 软件开发流程简介)
  • [第32课 - Qt 中的文件操作](#第32课 - Qt 中的文件操作)
  • [第33课 - 文本流和数据流](#第33课 - 文本流和数据流)
  • [第34课 - 缓冲区操作与目录操作](#第34课 - 缓冲区操作与目录操作)
  • [第35课 - 文本编辑器中的数据存取](#第35课 - 文本编辑器中的数据存取)
  • [第36课 - 文本编辑器中的功能交互](#第36课 - 文本编辑器中的功能交互)
  • [第37课 - 深度解析 QMap 与 QHash](#第37课 - 深度解析 QMap 与 QHash)
  • [第38课 - Qt 中的事件处理(上)](#第38课 - Qt 中的事件处理(上))
  • [第39课 - Qt 中的事件处理(下)](#第39课 - Qt 中的事件处理(下))
  • [第40课 - 拖放事件深度剖析](#第40课 - 拖放事件深度剖析)
  • [第41课 - 编辑交互功能的实现](#第41课 - 编辑交互功能的实现)
  • [第42课 - 文本打印与光标定位](#第42课 - 文本打印与光标定位)
  • [第43课 - 发送自定义事件(上)](#第43课 - 发送自定义事件(上))
  • [第44课 - 发送自定义事件(下)](#第44课 - 发送自定义事件(下))
  • [第45课 - 创建查找对话框](#第45课 - 创建查找对话框)
  • [第46课 - 查找对话框的功能实现](#第46课 - 查找对话框的功能实现)
  • [第47课 - Qt 中的调色板](#第47课 - Qt 中的调色板)
  • [第48课 - 替换对话框的设计与实现](#第48课 - 替换对话框的设计与实现)
  • [第49课 - 文本编辑器项目持续开发](#第49课 - 文本编辑器项目持续开发)
  • [第50课 - 关于对话框(About)](#第50课 - 关于对话框(About))
  • [第51课 - 程序中的配置文件](#第51课 - 程序中的配置文件)
  • [第52课 - 命令行参数的应用](#第52课 - 命令行参数的应用)
  • [第53课 - 应用程序的打包与发布](#第53课 - 应用程序的打包与发布)
  • [第54课 - Qt 中的多页面切换组件](#第54课 - Qt 中的多页面切换组件)
  • [第55课 - 模型视图设计模式(上)](#第55课 - 模型视图设计模式(上))
  • [第56课 - 模型视图设计模式(中)](#第56课 - 模型视图设计模式(中))
  • [第57课 - 模型视图设计模式(下)](#第57课 - 模型视图设计模式(下))
  • [第58课 - 自定义模型类(上)](#第58课 - 自定义模型类(上))
  • [第59课 - 自定义模型类(中)](#第59课 - 自定义模型类(中))
  • [第60课 - 自定义模型类(下)](#第60课 - 自定义模型类(下))
  • [第61课 - 模型视图中的委托(上)](#第61课 - 模型视图中的委托(上))
  • [第62课 - 模型视图中的委托(下)](#第62课 - 模型视图中的委托(下))
  • [第63课 - 深入解析视图与委托(上)](#第63课 - 深入解析视图与委托(上))
  • [第64课 - 深入解析视图与委托(下)](#第64课 - 深入解析视图与委托(下))
  • [第65课 - 深入浅出信号与槽](#第65课 - 深入浅出信号与槽)
  • [第66课 - 基础图形绘制(上)](#第66课 - 基础图形绘制(上))
  • [第67课 - 基础图形绘制(中)](#第67课 - 基础图形绘制(中))
  • [第68课 - 基础图形绘制(下)](#第68课 - 基础图形绘制(下))
  • [第69课 - 图像处理与绘制](#第69课 - 图像处理与绘制)
  • [第70课 - 文本绘制技巧](#第70课 - 文本绘制技巧)
  • [第71课 - 登录对话框的改进](#第71课 - 登录对话框的改进)
  • [第72课 - 进程与线程的概念](#第72课 - 进程与线程的概念)
  • [第73课 - Qt 中的多线程编程](#第73课 - Qt 中的多线程编程)
  • [第74课 - 多线程间的同步](#第74课 - 多线程间的同步)
  • [第75课 - 多线程间的互斥(上)](#第75课 - 多线程间的互斥(上))
  • [第76课 - 多线程间的互斥(下)](#第76课 - 多线程间的互斥(下))
  • [第77课 - 银行家算法的分析与实现](#第77课 - 银行家算法的分析与实现)
  • [第78课 - 多线程中的信号与槽(上)](#第78课 - 多线程中的信号与槽(上))
  • [第79课 - 多线程中的信号与槽(中)](#第79课 - 多线程中的信号与槽(中))
  • [第80课 - 多线程中的信号与槽(下)](#第80课 - 多线程中的信号与槽(下))
  • [第81课 - 信号与槽的连接方式](#第81课 - 信号与槽的连接方式)
  • [第82课 - 线程的生命期问题](#第82课 - 线程的生命期问题)
  • [第83课 - 另一种创建线程的方式](#第83课 - 另一种创建线程的方式)
  • [第84课 - 多线程与界面组件的通信(上)](#第84课 - 多线程与界面组件的通信(上))
  • [第85课 - 多线程与界面组件的通信(下)](#第85课 - 多线程与界面组件的通信(下))

第0课 - 开发环境搭建

第1课 - GUI 程序原理分析

第2课 - GUI 程序实例分析

增加点击X,退出程序的功能

cpp 复制代码
static HWND MainWindow = NULL; // 主窗口句柄标  移动位置
void App_Exit()
{
	PostQuitMessage(0);
}

void Button_handler(int i,int e)
{
	if((i==BUTTON_ID)&& (e==BN_CLICKED))
	{
		MessageBox(MainWindow,L"My button is clicked",L"Click message",0);

	}
	

}

//static HWND MainWindow = NULL; // 主窗口句柄标 移动到上面
.......

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if(message==WM_DESTROY)
	{
		//PostQuitMessage(0);
		App_Exit();//
	}

	if(message==WM_COMMAND)
	{
		
		Button_handler(LOWORD(wParam),HIWORD(wParam));//获取id值
	}
    /* 调用系统提供的默认消息处理函数 */
    return DefWindowProc(hWnd, message, wParam, lParam);
}

MFC应用程序创建







cpp 复制代码
void CMFCdemoDlg::OnClickedMyButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	MessageBox(L"my button is clicked");
}

在字符串前加一个L作用: unicode字符集是两个字节组成的。L告示编译器使用两个字节的 unicode 字符集。

如 L"我的字符串" 表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节。

第3课 - QT 的诞生和本质

上一课的代码使用的是面向过程的方法,所以只有一个文件

这节课是面向对象的方法,多个cpp文件

cpp 复制代码
#pragma once//??啥意思来着 这个文件只能编译一次

#include <windows.h>

class Application
{
public:
    Application(HINSTANCE hInstance, LPSTR lpCmdLine);
    bool exec();
};

第4课 - Hello QT

条件断点

第5课 - Qt Creator工程介绍

第6课 - 窗口部件及窗口类型

cpp 复制代码
#include <QLabel>
//#include <QtGui>//qlabel 版本不一样 
#include "Widget.h"
#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
   // QWidget w;//Widget w;
   // QWidget w(NULL,Qt::Dialog);
    //QWidget w(NULL,Qt::Window);
   // QWidget w(NULL,Qt::SplashScreen);

    //QWidget w(NULL,Qt::Window|Qt::WindowStaysOnTopHint);
    QWidget w(NULL,Qt::Window|Qt::WindowStaysOnTopHint|Qt::WindowContextHelpButtonHint);
QLabel l(&w);
l.setText("this is a label");

    w.setWindowTitle("title");
    w.show();/**/

/*label也可以是窗体
QLabel l;
l.setText("this is a label");

    l.setWindowTitle("title");
    l.show();*/

    return a.exec();
}

第7课 - Qt 中的坐标系统


第8课 - 启航!第一个应用实例

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H


#include "widget.h"
#include "ui_widget.h"

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

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


cpp 复制代码
//#include "widget.h"
#include <QApplication>
#include<QWidget>
#include<QLineEdit>
#include<QPushButton>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //Widget w;
    QWidget *w=new QWidget(NULL,Qt::WindowCloseButtonHint);//窗口最大化优化 WindowMaximizeButtonHint

    QLineEdit *e=new QLineEdit(w);
    e->setReadOnly(true);
    e->resize(240,30);
    e->move(10,10);
    QPushButton* button[20]={0};
    const char* texts[20]={
        "7","8","9","+","(",
        "4","5","6","-",")",
        "1","2","3","*","<-",
        "0",".","=","/","C",
    };
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<5;j++)
        {
            button[i*5+j]=new QPushButton(w);
            button[i*5+j]->resize(40,40);
            button[i*5+j]->move(10+(10+40)*j,50+(10+40)*i);
            button[i*5+j]->setText(texts[i*5+j]);

        }
    }

    int ret=0;
    //w.show();
    w->show();
    w->setFixedSize(w->width(),w->height());//放在show后面

    //return a.exec();
    ret=a.exec();
    delete w;


    return ret;


}

第9课 - 计算器界面代码重构

c 复制代码
#include "calculatorui.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //Widget w;
    /*
    QWidget *w=new QWidget(NULL,Qt::WindowCloseButtonHint);//窗口最大化优化 WindowMaximizeButtonHint

    QLineEdit *e=new QLineEdit(w);
    e->setReadOnly(true);
    e->resize(240,30);
    e->move(10,10);
    QPushButton* button[20]={0};
    const char* texts[20]={
        "7","8","9","+","(",
        "4","5","6","-",")",
        "1","2","3","*","<-",
        "0",".","=","/","C",
    };
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<5;j++)
        {
            button[i*5+j]=new QPushButton(w);
            button[i*5+j]->resize(40,40);
            button[i*5+j]->move(10+(10+40)*j,50+(10+40)*i);
            button[i*5+j]->setText(texts[i*5+j]);

        }
    }
*/
    CalculatorUI * c1=CalculatorUI::newInstance();

    int ret=-1;
    if(c1!=NULL)
    {
        c1->show();
        ret=a.exec();
        delete c1;
    }

    //w.show();
    /*
    w->show();
    w->setFixedSize(w->width(),w->height());//放在show后面
*/
    //return a.exec();

    //delete w;


    return ret;


}
c 复制代码
#ifndef _CALCULATORUI_H
#define _CALCULATORUI_H
#include <QApplication>
#include<QWidget>
#include<QLineEdit>
#include<QPushButton>

class CalculatorUI:public QWidget
{
private:
    QLineEdit *m_e;
    QPushButton* m_button[20];
    CalculatorUI();
    bool construct();
public:
    static CalculatorUI* newInstance();
    void show();
    ~CalculatorUI();


};

#endif // CALCULATORUI_H
c 复制代码
#include "calculatorui.h"

CalculatorUI::CalculatorUI():QWidget(NULL,Qt::WindowCloseButtonHint)
{
    //非系统变量

}
bool CalculatorUI::construct()
{
    bool ret=true;
    const char* texts[20]={
        "7","8","9","+","(",
        "4","5","6","-",")",
        "1","2","3","*","<-",
        "0",".","=","/","C",
    };

    m_e=new QLineEdit(this);
    if(m_e!=NULL)
    {
        m_e->setReadOnly(true);
        m_e->resize(240,30);
        m_e->move(10,10);
        //ret=true;

    }
    else
    {
        ret=false;
    }



    for(int i=0;(i<4)&&ret;i++)//&&ret
    {
        for(int j=0;(j<5)&&ret;j++)
        {
            m_button[i*5+j]=new QPushButton(this);
            if(m_button[i*5+j]!=NULL)
            {
                m_button[i*5+j]->resize(40,40);
                m_button[i*5+j]->move(10+(10+40)*j,50+(10+40)*i);
                m_button[i*5+j]->setText(texts[i*5+j]);
               // ret=true;

            }
            else
            {
                ret=false;
            }


        }
    }
    return ret;


}

CalculatorUI* CalculatorUI::newInstance()
{
    CalculatorUI* ret=new CalculatorUI();
    if((ret==NULL)||ret->construct()==false)//CalculatorUI::construct()==false
    {
        delete ret;
        ret=NULL;
    }

    return ret;

}
void CalculatorUI::show()//CalculatorUI* obj
{
    QWidget::show();//obj->  QWidget::   CalculatorUI::XXX 死循环??
    setFixedSize(width(),height());
}

CalculatorUI::~CalculatorUI()
{
    delete(m_e);
    for(int i=0;i<20;i++)
    {
        delete(m_button[i]);
    }


}

第10课 - 初探 Qt 中的消息处理





第11课 - Qt 中的字符串类

c 复制代码
#include <QDebug>

void Sample_1()
{
    QString s = "add";

    s.append(" ");    // "add "
    s.append("Qt");   // "add Qt"
    s.prepend(" ");   // " add Qt"
    s.prepend("C++"); // "C++ add Qt"

    qDebug() << s;

    s.replace("add", "&"); // "C++ & Qt"

    qDebug() << s;
}

void Sample_2()
{
    QString s = "";
    int index = 0;

    s.sprintf("%d. I'm %s, thank you!", 1, "Delphi Tang"); // "1. I'm Delphi Tang, thank you!"

    qDebug() << s;

    index = s.indexOf(",");

    s = s.mid(0, index);   // "1. I'm Delphi Tang"

    qDebug() << s;

    index = s.indexOf(".");

    s = s.mid(index + 1, s.length()); // " I'm Delphi Tang"
    s = s.trimmed();                  // "I'm Delphi Tang"

    qDebug() << s;

    index = s.indexOf(" ");

    s = s.mid(index + 1, s.length()); // "Delphi Tang"

    qDebug() << s;
}

void Sample_3(QString* a, int len)
{
    for(int i=0; i<len; i++)
    {
        for(int j=i+1; j<len; j++)
        {
            if( a[j] < a[i] )
            {
                QString tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }
        }
    }
}

int main()
{
    qDebug() << "Sample_1:";

    Sample_1();

    qDebug() << endl;
    qDebug() << "Sample_2:";

    Sample_2();

    qDebug() << endl;
    qDebug() << "Sample_3:";

    QString company[5] =
    {
        QString("Oracle"),
        QString("Borland"),
        QString("Microsoft"),
        QString("IBM"),
        QString("D.T.Software")
    };

    Sample_3(company, 5);

    for(int i=0; i<5; i++)
    {
        qDebug() << company[i];
    }

    return 0;
}

第12课 - 计算器核心解析算法(上)

第13课 - 计算器核心解析算法(中)

遇到问题

"+9.11"

"+"

"-"

"3"

"-"

"1"

"*"

"-"

"5" 应该是-5

c 复制代码
QQueue<QString> CalculatorDec::split(const QString& exp)// 日期:8/28
 {
     QQueue<QString> ret;
     QString num="";
     QString pre="";

     for(int i=0;i<exp.length();i++)
     {
         if(isDigitorDot(exp[i]))//数字和点
         {
             num+=exp[i];  //QString  Qchar
             pre=exp[i];
         }
         else if(isSymbol(exp[i]))//加减乘除括号  isOperator    QString转换为Qchar类型XXX  本来就是Qchar
         {
             if(!num.isEmpty())//有内容,数值丢到队列去   num!=""!num.isEmpty()
             {
                 ret.enqueue(num);
                 num.clear();//="";
             }
             if(isSign(exp[i]) &&((pre=="")||isOperator(pre)||("("==pre)))//当前是否是正负号(首位,前面是加减乘除,前面是括号)  isSign(exp[i]) &&    duole ||isRight(pre)
             {
                 num+=exp[i];//

             }
             else
             {
                 ret.enqueue(exp[i]);

             }
             pre=exp[i];

         }
         //pre=exp[i];不能放这里
     }
     if( !num.isEmpty() )//防止最后一位数值漏了
     {
             ret.enqueue(num);
    }
/*
     for(int i=0; i<exp.length(); i++)
        {
            if( isDigitorDot(exp[i]) )
            {
                num += exp[i];
                pre = exp[i];
            }
            else if( isSymbol(exp[i]) )
            {
                if( !num.isEmpty() )
                {
                    ret.enqueue(num);

                    num.clear();
                }

                if( isSign(exp[i]) && ((pre == "") || (pre == "(") || isOperator(pre)) )
                {
                    num += exp[i];
                }
                else
                {
                    ret.enqueue(exp[i]);
                }

                pre = exp[i];
            }
        }

        if( !num.isEmpty() )
        {
            ret.enqueue(num);
        }
*/
     return ret;

 }


bool QCalculatorDec::transform(QQueue& exp, QQueue& output)

{

bool ret = match(exp);

QStack stack;

output.clear();

while( ret && !exp.isEmpty() )
{
    QString e = exp.dequeue();

    if( isNumber(e) )
    {
        output.enqueue(e);
    }
    else if( isOperator(e) )
    {
        while( !stack.isEmpty() && (priority(e) <= priority(stack.top())) )
        {
            output.enqueue(stack.pop());
        }

        stack.push(e);
    }
    else if( isLeft(e) )
    {
        stack.push(e);
    }
    else if( isRight(e) )
    {
        while( !stack.isEmpty() && !isLeft(stack.top()) )
        {
            output.enqueue(stack.pop());
        }

        if( !stack.isEmpty() )
        {
            stack.pop();
        }
    }
    else
    {
        ret = false;
    }
}

while( !stack.isEmpty() )
{
    output.enqueue(stack.pop());
}

if( !ret )
{
    output.clear();

第14课 - 计算器核心解析算法(下)



c 复制代码
QString QCalculatorDec::calculate(QString l, QString op, QString r)
{
    QString ret = "Error";

    if( isNumber(l) && isNumber(r) )
    {
        double lp = l.toDouble();
        double rp = r.toDouble();

        if( op == "+" )
        {
            ret.sprintf("%f", lp + rp);
        }
        else if( op == "-" )
        {
            ret.sprintf("%f", lp - rp);
        }
        else if( op == "*" )
        {
            ret.sprintf("%f", lp * rp);
        }
        else if( op == "/" )
        {
            const double P = 0.000000000000001;

            if( (-P < rp) && (rp < P) )
            {
                ret = "Error";
            }
            else
            {
                ret.sprintf("%f", lp / rp);
            }

        }
        else
        {
            ret = "Error";
        }
    }

    return ret;
}

QString QCalculatorDec::calculate(QQueue<QString>& exp)
{
    QString ret = "Error";
    QStack<QString> stack;

    while( !exp.isEmpty() )
    {
        QString e = exp.dequeue();

        if( isNumber(e) )
        {
            stack.push(e);
        }
        else if( isOperator(e) )
        {
            QString rp = !stack.isEmpty() ? stack.pop() : "";
            QString lp = !stack.isEmpty() ? stack.pop() : "";
            QString result = calculate(lp, e, rp);

            if( result != "Error" )
            {
                stack.push(result);
            }
            else
            {
                break;
            }
        }
        else
        {
            break;
        }
    }

    if( exp.isEmpty() && (stack.size() == 1) && isNumber(stack.top()) )
    {
        ret = stack.pop();
    }

第15课 - 用户界面与业务逻辑的分离

第16课 - Qt 对象间的父子关系

第17课 - 对话框及其类型

第18课 - 登录对话框实例分析

第19课 - Qt 中的标准对话框(上)

第20课 - Qt 中的标准对话框(中)

第21课 - Qt 中的标准对话框(下)

第22课 - 布局管理器(一)

第23课 - 布局管理器(二)

第24课 - 布局管理器(三)

第25课 - 布局管理器(四)

第26课 - 布局管理综合实例

第27课 - 应用程序中的主窗口

第28课 - 主窗口中的工具栏

第29课 - 主窗口中的状态栏

第30课 - Qt 中的文本编辑组件

第31课 - 软件开发流程简介

第32课 - Qt 中的文件操作

第33课 - 文本流和数据流

第34课 - 缓冲区操作与目录操作

第35课 - 文本编辑器中的数据存取

第36课 - 文本编辑器中的功能交互

第37课 - 深度解析 QMap 与 QHash

第38课 - Qt 中的事件处理(上)

第39课 - Qt 中的事件处理(下)

第40课 - 拖放事件深度剖析

第41课 - 编辑交互功能的实现

第42课 - 文本打印与光标定位

第43课 - 发送自定义事件(上)

第44课 - 发送自定义事件(下)

第45课 - 创建查找对话框

第46课 - 查找对话框的功能实现

第47课 - Qt 中的调色板

第48课 - 替换对话框的设计与实现

第49课 - 文本编辑器项目持续开发

第50课 - 关于对话框(About)

第51课 - 程序中的配置文件

第52课 - 命令行参数的应用

第53课 - 应用程序的打包与发布

第54课 - Qt 中的多页面切换组件

第55课 - 模型视图设计模式(上)

第56课 - 模型视图设计模式(中)

第57课 - 模型视图设计模式(下)

第58课 - 自定义模型类(上)

第59课 - 自定义模型类(中)

第60课 - 自定义模型类(下)

第61课 - 模型视图中的委托(上)

第62课 - 模型视图中的委托(下)

第63课 - 深入解析视图与委托(上)

第64课 - 深入解析视图与委托(下)

第65课 - 深入浅出信号与槽

第66课 - 基础图形绘制(上)

第67课 - 基础图形绘制(中)

第68课 - 基础图形绘制(下)

第69课 - 图像处理与绘制

第70课 - 文本绘制技巧

第71课 - 登录对话框的改进

第72课 - 进程与线程的概念

第73课 - Qt 中的多线程编程

第74课 - 多线程间的同步

第75课 - 多线程间的互斥(上)

第76课 - 多线程间的互斥(下)

第77课 - 银行家算法的分析与实现

第78课 - 多线程中的信号与槽(上)

第79课 - 多线程中的信号与槽(中)

第80课 - 多线程中的信号与槽(下)

第81课 - 信号与槽的连接方式

第82课 - 线程的生命期问题

第83课 - 另一种创建线程的方式

第84课 - 多线程与界面组件的通信(上)

第85课 - 多线程与界面组件的通信(下)

相关推荐
Magnetic_h30 分钟前
【iOS】单例模式
笔记·学习·ui·ios·单例模式·objective-c
华清远见成都中心33 分钟前
哪些人适合学习人工智能?
人工智能·学习
重生之我在20年代敲代码1 小时前
HTML讲解(二)head部分
前端·笔记·html·web app
天下无贼!1 小时前
2024年最新版TypeScript学习笔记——泛型、接口、枚举、自定义类型等知识点
前端·javascript·vue.js·笔记·学习·typescript·html
秋秋秋叶1 小时前
Python学习——【2.3】for循环
python·学习
Deryck_德瑞克1 小时前
Java集合笔记
java·开发语言·笔记
YHPsophie2 小时前
ATGM331C-5T杭州中科微BDS/GNSS全星座定位授时模块应用领域
经验分享·笔记·单片机·信息与通信·交通物流
月夕花晨3742 小时前
C++学习笔记(30)
c++·笔记·学习