QT学习笔记
这里写目录标题
- 第0课 - 开发环境搭建
- 第1课 - GUI 程序原理分析
- 第2课 - GUI 程序实例分析
- 第3课 - QT 的诞生和本质
- 第4课 - Hello QT
- 第5课 - Qt Creator工程介绍
- 第6课 - 窗口部件及窗口类型
- 第7课 - Qt 中的坐标系统
- 第8课 - 启航!第一个应用实例
- 第9课 - 计算器界面代码重构
- 第10课 - 初探 Qt 中的消息处理
- 第11课 - Qt 中的字符串类
- 第12课 - 计算器核心解析算法(上)
- 第13课 - 计算器核心解析算法(中)
- 第14课 - 计算器核心解析算法(下)
- 第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课 - 多线程与界面组件的通信(下)
第0课 - 开发环境搭建
第1课 - GUI 程序原理分析
第2课 - GUI 程序实例分析
增加点击X,退出程序的功能
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应用程序创建
void CMFCdemoDlg::OnClickedMyButton1()
{// TODO: 在此添加控件通知处理程序代码MessageBox(L"my button is clicked");
}
在字符串前加一个L作用: unicode字符集是两个字节组成的。L告示编译器使用两个字节的 unicode 字符集。
如 L"我的字符串" 表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节。
第3课 - QT 的诞生和本质
上一课的代码使用的是面向过程的方法,所以只有一个文件
这节课是面向对象的方法,多个cpp文件
#pragma once//??啥意思来着 这个文件只能编译一次#include <windows.h>class Application
{
public:Application(HINSTANCE hInstance, LPSTR lpCmdLine);bool exec();
};
第4课 - Hello QT
条件断点
第5课 - Qt Creator工程介绍
第6课 - 窗口部件及窗口类型
#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课 - 启航!第一个应用实例
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic: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;
}
//#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);//窗口最大化优化 WindowMaximizeButtonHintQLineEdit *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课 - 计算器界面代码重构
#include "calculatorui.h"
int main(int argc, char *argv[])
{QApplication a(argc, argv);//Widget w;/*QWidget *w=new QWidget(NULL,Qt::WindowCloseButtonHint);//窗口最大化优化 WindowMaximizeButtonHintQLineEdit *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;}
#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
#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 中的字符串类
#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
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 Qcharpre=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课 - 计算器核心解析算法(下)
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();}