记载一些学习C/C++语法,库函数,开发框架等
1. 好用的方法:
1. PixmapToRound函数
将QPixmap的图像转换为圆形,美化界面用,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #ifndef ROUNDIMG_H #define ROUNDIMG_H #include <QPixmap> #include <QPainter> #include <QPainterPath> QPixmap PixmapToRound(const QPixmap &src, int radius) { if (src.isNull()) { return QPixmap(); }
QPixmap pixmapa; if(src.width() != radius || src.height() != radius) { pixmapa = src.scaled(radius, radius, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } else { pixmapa = src; } QPixmap pixmap(radius,radius); pixmap.fill(Qt::transparent);
QPainter painter(&pixmap); painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
QPainterPath path; path.addEllipse(0, 0, radius, radius); painter.setClipPath(path); painter.drawPixmap(0, 0, radius, radius, pixmapa);
return pixmap; } #endif
QPixmap img; img.load("://res/login.jpg"); QPixmap pixMap= img.scaled(100,100, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); pixMap = PixmapToRound(pixMap, 50); ui->label_img->setPixmap(pixMap);
|
2. 使用正则表达式规定输入规范
1 2
| ui->lineEdit_1->setValidator(new QRegularExpressionValidator(QRegularExpression("[0-9]+$"))); ui->lineEdit_1->setValidator(new QRegularExpressionValidator(QRegularExpression("[A-Fa-f0-9]{1,12}")));
|
3. 使用花指令增加逆向破解难度:
1 2 3 4 5 6
| __asm__("test $0,%eax\n" "jz label\n" "add $0xff,%esp\n" ".byte 0xe8,0x80,0x80,0x80\n" "label:\n" );
|
4. 与数据库互通的一些操作:
CMakeList.txt文件里写入:find_package(Qt6 COMPONENTS Sql REQUIRED)
target_link_libraries(TeamProject PRIVATE Qt6::Sql)
连接数据库,代码段里写入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void MainWindow::linkDatabase() { database=QSqlDatabase::addDatabase("QMYSQL"); database.setHostName("192.168.76.1"); database.setPort(3306); database.setUserName("root"); database.setPassword("123456"); database.setDatabaseName("test"); database.open(); if(!database.isOpen()) { setWindowTitle("数据库没有连接成功呐!"); } }
|
5. 给Qt生成的可执行文件设置图标,以及窗口左上角图标:
给可执行文件设置图标,先在cpp同级目录下创建一个ico.rc文件(后缀一定要是.rc),然后再CMake.txt文件下写入文件编译区,然后再Source Files下找到该文件并写入 IDI_ICON_LOGO ICON DISCARDABLE "res/logo.ico"
,双引号里面是图标的相对路径,.ico文件可在 D:\Pixillion
软件中进行图片格式转换。
窗口左上角图标设置:setWindowIcon(QIcon(":/res/R-C2.jpg"));
。
在Qt中调用其他系统命令或执行文件时,可用QProcess函数:
1 2 3 4
| QProcess process(this); QString str = QApplication::applicationDirPath(); str += "/firmware_upgrade_v1.0.0.exe"; process.startDetached(str);
|
6. 数据库查询和写入操作
1 2 3 4 5 6 7 8 9 10
| QSqlQuery query; QString s = QString("select * from users where id='%1'").arg(id); QString s2 = QString("INSERT INTO users (id,passwordMD5,`password`,name)VALUES ('%1','%2','%3','%4')").arg(user).arg(pwdMD5).arg(pwd).arg(name); query.exec(s); if(!query.first()) {} else {}
|
7. QThreadPool线程池的使用
先创建一个继承QRunable和QObject的线程类,在类中定义一个public的void run()函数,然后在主线程创建类对象,用QThreadPool::globalInstance()调用类对象实现多线程,示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| thread1 *thread = new thread1; QThreadPool::globalInstance()->start(thread);
#include <QObject> #include <QRunnable> class thread1 : public QObject,public QRunnable { Q_OBJECT public: explicit thread1(QObject *parent = nullptr); void run(); signals:
};
#include "m_thread.h" #include "gamehall.h" thread1::thread1(QObject *parent) : QObject{parent},QRunnable() { }
void thread1::run() { GameHall* gamehall = new GameHall(); gamehall->show();
}
|
2. Qt中一些好用的部件属性对应的qss代码:
1. LineEdit部件:
设置形成的是一个浅绿色圆角编辑框。
1 2 3 4 5
| ui->lineEdit_1->setStyleSheet("font: 25 14pt '微软雅黑 Light';" "color: rgb(31,31,31);" "padding-left:20px;" "background-color: rgb(255, 255, 255);" "border:2px solid rgb(20,196,188);border-radius:15px;");
|
设置形成的是一个浅绿色按钮,鼠标悬浮或摁下有不同颜色
1 2 3 4
| ui->signup->setStyleSheet("QPushButton{font: 25 14pt '微软雅黑 Light';color: rgb(255,255,255);background-color: rgb(20,196,188);" "border: none;border-radius:5px;}" "QPushButton:hover{background-color: rgb(22,218,208);}" "QPushButton:pressed{background-color: rgb(17,171,164);}");
|
设置的是一个蓝白渐变色的按钮,鼠标悬浮有不同的颜色
1 2 3 4 5 6 7
| ui->signUp->setStyleSheet("QPushButton{background-color: qlineargradient(spread:pad, x1:0.52, y1:1, x2:0.54, y2:0," "stop:0.0112994 rgba(64, 145, 252, 255),stop:1 rgba(255, 255, 255, 255));" "color: rgb(255, 255, 255);" "border:0px groove gray;border-radius:7px;padding:2px 4px;" "font: 10pt 'Candara';}" "QPushButton:hover{background-color: qlineargradient(spread:pad, x1:0.52, y1:1, x2:0.54, y2:0," "stop:0.0112994 rgba(66, 175, 255, 255),stop:1 rgba(255, 255, 255, 255))};");
|
设置是一个蔚蓝色的按钮,按动悬浮有不同颜色
1 2 3 4 5 6 7
| ui->pushButton->setStyleSheet("QPushButton{background:qlineargradient(spread:pad, x1:0.460227, y1:0, x2:0.465818, y2:0.875, stop:" "0 rgba(170, 255, 255, 255), stop:1 rgba(255, 255, 255, 255));" "border-radius:8px;" "border:2px solid rgb(0, 170, 255);" "color:rgb(17,17,17);}" "QPushButton:hover{background:qlineargradient(spread:pad, x1:0.460227, y1:0, x2:0.443091, y2:0.898, stop:0 rgba(0, 255, 255, 255), stop:1 rgba(255, 255, 255, 255))}" "QPushButton:hover:pressed{background:qlineargradient(spread:pad, x1:0.460227, y1:0, x2:0.465818, y2:0.875, stop:0 rgba(170, 255, 255, 255), stop:1 rgba(255, 255, 255, 255));}");
|
3. 遇到的一些问题:
2023/5/23->在Qt的两个窗口头文件中都调用了相同的一个头文件,然后报了multiple definition of ~的错,分析是因为两个函数重复定义了。
解决办法是:新建了一个.cpp文件,然后将.h文件中全部内容转到cpp文件中,然后.h文件只包含函数的定义.
2023/5/24->在注册成功窗口想要直接将注册窗口和本窗口同时关闭并且转到登录窗口时遇到了问题——如何在子窗口中通过按钮将父窗口也关闭。
解决办法是:在父窗口调用子窗口前增加一个信号槽连接,信号由子窗口.h文件中定义并在按按钮之后发出,槽函数在父窗口中声明并实现,从而实现信号通过子窗口发出并在父窗口中做出关闭操作。
核心代码:
1 2 3 4
| SignSucess *signsucess = new SignSucess(); connect(signsucess,&SignSucess::Close,this,&LoginWindow::Close); signsucess->exec();
|
2023/5/24->在写记住密码功能时,用到QSetting库,然后通过该库与本地ini文件交互,但是把ini文件放在源代码目录下则无法保存修改,查了网上的有关说法,利用sync()函数或者重构closeEvent函数(该函数在右上角关闭窗口时自动起作用),或者在该窗口的析构函数中servalue,最终都没很好的解决我的问题。
解决办法是:将init.ini文件放在exe程序目录下(撒花!)
绝对路径可以这样在父类头文件窗口直接定义:
1
| QString inipath= QCoreApplication::applicationDirPath() + "/init.ini"
|
2023/5/24->Qt6编译生成的exe程序无法打开,显示缺少一些dll文件。
解决办法是:打开编译器对应的命令行,这里对应的是MinGW64(已加入环境变量),先新建一个文件夹,将exe程序单独放进去,然后”cd [exe程序所在文件夹的路径]”,输入windeployqt exe文件名
,例如windeployqt TeamProject.exe
。
2023/5/24->Qt6打包生成exe文件后,打开exe程序不能连接数据库的问题。
解决办法是:在编译器(这里对应的是MinGW64)对应的bin目录下找到libmysql.dll文件,复制到exe程序的同级目录下即可。
2023/5/25->Qt6打包生成的exe文件在远端虚拟机上无法连接数据库成功的问题。
解决办法是:在Mysql文件夹的MysqlServer文件bin中所有文件转移到exe文件同级目录下
2023/5/25->Qt6打包生成的exe文件在远端虚拟机上连接上了数据库,但是远端正常机上连不上
解决办法是:把代码中 database.setHostName("192.168.123.120");
ip地址设置为无线局域网适配器 WLAN的IPv4地址(本机ip地址)。
2023/6/10->QMovie播放gif时,想要使得同一个label通过按钮切换gif时出现gif暂停不切换的情况
解决办法是:在gif切换时movie->start(),前加入movie->stop()。
2023/6/11->在提升控件类时,运行出现无法找到头文件的情况
解决办法是:在cmake.txt文件中加入 INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})
运行报错点击“忽略错误”。
2023/6/11->QToolButton重写鼠标进入事件 void HallBtn::enterEvent(QEnterEvent *event)
2023/6/14->连接阿里云数据库后,查询表时navicate报“lost connection …during query”错误
解决办法是:换校园网。。
2023/6/24->实现邮箱辅助账号注册时,引用QTcpSocket时报错 QTcpSocket file not found
解决办法是:CMakeList.txt中添加
1 2 3 4
| find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network) find_package(Qt${QT_VERSION_MAJOR} REQUIRED Network COMPONENTS Core) target_link_libraries(TeamProject PRIVATE Qt${QT_VERSION_MAJOR}::Core) target_link_libraries(TeamProject PRIVATE Qt6::Network)
|
4. Windows编程:
LPCVOID
是一个Windows API数据类型,它是一个指向常量(只读)void的指针。在Windows API中,LPCVOID
通常用于指向要读取的数据的缓冲区
LPVOID
是一个Windows API数据类型,它是一个指向void的指针。在Windows API中,LPVOID
通常用于指向要读取或写入的数据的缓冲区
ReadProcessMemory
函数是Windows API的一部分,它允许一个进程读取另一个进程的内存区域。该函数的语法如下:
1 2 3 4 5 6 7
| BOOL ReadProcessMemory( HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead );
|
其中,hProcess
参数是要读取内存的进程的句柄,lpBaseAddress
参数是要读取的内存地址(读取目标地址),lpBuffer
参数是用于存储读取数据的缓冲区(保存读取结果),nSize
参数是要读取的字节数,lpNumberOfBytesRead
参数是指向变量的指针(没有用到则填NULL),该变量将接收实际读取的字节数。
WriteProcessMemory
函数是Windows API的一部分,它允许一个进程向另一个进程的内存区域写入数据。该函数的语法如下:
1 2 3 4 5 6 7
| BOOL WriteProcessMemory( HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten );
|
其中,hProcess
参数是要读取内存的进程的句柄,lpBaseAddress
参数是要读取的内存地址(读取目标地址),lpBuffer
参数是用于存储读取数据的缓冲区(保存读取结果),nSize
参数是要读取的字节数,lpNumberOfBytesWritten
参数是指向变量的指针(没有用到则填NULL),该变量将接收实际读取的字节数。
获得指定进程PID的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| DWORD MainWindow::getProcessId(const QString& processName) { PROCESSENTRY32 entry; entry.dwSize = sizeof(PROCESSENTRY32); HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (Process32First(snapshot, &entry)) { do { if (QString::fromWCharArray(entry.szExeFile) == processName) { CloseHandle(snapshot); return entry.th32ProcessID; } } while (Process32Next(snapshot, &entry)); } CloseHandle(snapshot); return 0; }
|
用法:DWORD pid=getProcessId(processname);
获取进程的总基地址的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| PVOID MainWindow::GetProcessBase(DWORD dwProcessId) { PVOID pProcessImageBase = NULL; HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); if (NULL == hProcess) { return pProcessImageBase; } HMODULE hModule[100] = { 0 }; DWORD dwRet = 0; BOOL bRet; bRet = EnumProcessModulesEx(hProcess, (HMODULE*)(hModule), sizeof(hModule), &dwRet, NULL); if (FALSE == bRet) { CloseHandle(hProcess); return pProcessImageBase; } pProcessImageBase = hModule[0]; CloseHandle(hProcess); return pProcessImageBase; }
|
用法:long long baseAddress = (long long)GetProcessBase(Pid)//进程对应PID
获取进程句柄:HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
5. C++语法:
1. 虚继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include<iostream>
class A { public: int flagA; int test; A() { test = 0x666666; flagA = 0x111111; } };
class B :virtual public A { public: int flagB; B() { flagB = 0X222222; } };
class C :virtual public A { public: int flagC; C() { flagC = 0x3333333; } };
class D :virtual public B,virtual public C { public: int flagD; D() { flagD = 0x444444; } }; int main() { B b; C c; D d; d.flagA = 0x5555555; printf("%d\n", sizeof(d)); system("pause"); }
|
2. 友元函数
在类内声明友元函数,关键词 friend
,从而使类外定义的非成员函数可以访问该类的私有成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| #include<iostream>
class Student { public: Student(const char* name); ~Student(); private: char name[20]; friend void printName(Student &stu); };
Student::Student(const char* name) { strcpy_s(this->name, 20, name); }
Student::~Student() { }
void printName(Student &stu) { std::cout << stu.name << std::endl; }
int main() { Student stu("I am Kvancy"); printName(stu); system("pause"); }
|
3. 重载运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| #include<iostream>
using std::ostream; class A { public: A(const char* name); ~A(); void printName(); char* get_name(); friend A operator+(A& a1, A& a2); friend ostream& operator<<(ostream& os, A& a1); private: char* name;
};
A::A(const char* name) { if (this->name = (char*)malloc(strlen(name) + 1)) { strcpy_s(this->name, strlen(name) + 1, name); }
}
A::~A() { free(this->name); }
void A::printName() { std::cout << this->name << std::endl; } char* A::get_name() { return this->name; } A operator+(A &a1, A &a2) { A a3(""); char* buff = nullptr; int len = strlen(a1.name) + strlen(a2.name); if (buff = (char*)malloc(len + 1)) { strcpy_s(buff, len + 1, a1.name); strcat_s(buff, len + 1, a2.name); } a3.name = buff; return a3; } ostream& operator<<(ostream& os, A &a1) { os << a1.name; return os; }
int main() { A a1("我是A1"); A a2("我是A2"); A a3 = a1 + a2; std::cout << a3 << std::endl; system("pause"); return 0; }
|
4. 虚函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include<iostream>
class Animal { public: Animal(); ~Animal(); virtual void make_sound () const { printf("Animal:make\n"); } };
Animal::Animal() { }
Animal::~Animal() { }
class Bird:public Animal { public: Bird(); ~Bird(); void make_sound() const override { printf("Bird:make\n"); } };
Bird::Bird() { } Bird::~Bird() { } int main() { Animal* animal = new Animal(); Bird bird; animal = &bird; animal->make_sound(); system("pause"); delete animal; return 0; }
|
5. 模版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include<iostream>
template<typename T> T sum(T a, T b) { return a + b; }
template<typename T,typename T2> void swap(T &a,T2 &b) { T c; c = b; b = a; a = c; }
template<typename T> class A { public: T getValue() { return value; } void setValue(T va); A(T value); ~A();
private: T value; };
template<typename T> A<T>::A(T value) { this->value = value; } template<typename T> A<T>::~A() { } template<typename T> void A<T>::setValue(T va) { value = va; } int main() { char a = 1; char b = 2; printf("第一种:%d\n",sum(a, b)); swap(a, b); printf("第二种:a:%d,b:%d\n", a, b); A<int> c(1); c.setValue(2); printf("第三种:%d\n", c.getValue()); system("pause"); return 0; }
|
6. 异常处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include<iostream>
double fun(double a, int b) { if (b == 0) { throw 2; } return a/b; } int main() { try { fun(2, 0); }
catch (...) { printf("我是万能的!\n"); } system("pause"); return 0; }
|
perror(char*) 显示报错信息,例如 perror("wrong!:")
打印出 “wrong!:+为什么报错”
6. C++算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| #include<iostream> #include<vector> #include <algorithm> using namespace std; vector<int>ve; void visit(int out) { cout << out << " "; }
class print2 { public: void operator()(int out) { cout << out << " "; } }; class trans { public: int operator()(int out) { return ++out; } }; int main() { ve = { 0,1,2,3,4,5 }; int in[6] = { 0,1,2,3,4,5 }; for (auto it : in)cout << it << " "; cout << endl; for_each(in, in + 6, visit); cout << endl; for (auto it : ve){cout << it<<" ";} cout << endl; for_each(ve.begin(), ve.end(), visit); cout << endl; for_each(ve.begin(), ve.end(), print2()); cout << endl; vector<int>ve2; ve2.resize(ve.size()); transform(ve.begin(), ve.end(), ve2.begin(), trans()); for (auto it : ve2)cout << it << " " ; cout << endl; }
|
2. 查找算法 find,find_if,count,count_if,binary_serach
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| #include<iostream> #include<vector> #include <algorithm> using namespace std; vector<int>ve; class Person { public: string name; int age; bool operator==(const Person& person1) { return person1.name == this->name && person1.age == this->age; } };
class equal1 { public: bool operator()(const Person &person1) { return person1.name == "p2" && person1.age == 5; } }; class equal2 { public: bool operator()(int out) { return out > 5; } }; class count_cmp { public: bool operator()(int out) { return out > 5; } }; int main() { ve = { 2,3,4,5,6,7 }; auto it = find(ve.begin(), ve.end(),5); cout << *it << endl; Person person1 = { "p1",5 }; Person person2 = { "p2",5 }; Person person3 = { "p1",5 }; vector<Person>ve2; ve2.push_back(person1); ve2.push_back(person2); ve2.push_back(person3); auto it2 = find(ve2.begin(), ve2.end(),person2 ); cout <<it2->name << " " << it2->age << endl; auto it3 = find_if(ve.begin(), ve.end(), equal2()); cout << *it3 << endl; auto it4 = find_if(ve2.begin(), ve2.end(), equal1()); cout << it4->name << " " << it4->age << endl; auto it5 = binary_search(ve.begin(), ve.end(), 7); cout << it5 << endl; auto it6 = binary_search(ve.begin(), ve.end(), 8); cout << it6 << endl; int cnt = count(ve.begin(), ve.end(), 2); cout << cnt << endl; cnt = count_if(ve.begin(), ve.end(), count_cmp()); cout << cnt << endl; }
|
3. 排序算法 sort,rand_shuffle,merge,reverse
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| int main() { sort(ve.begin(), ve.end()); sort(ve.begin(), ve.end(), greater<int>()); sort(ve.begin(), ve.end(), cmpl); random_shuffle(ve.begin(), ve.end()); srand((unsigned int)time(NULL)); random_shuffle(ve.begin(), ve.end()); merge(ve.begin(), ve.end(), ve1.begin(), ve1.end(), ve2.begin()); reverse(ve2.begin(), ve2.end()); }
|
4. 拷贝替换算法 copy replace replace_if
1 2 3 4
| copy(ve.begin(), ve.end(), ve2.begin()); replace(ve.begin(), ve.end(), 0, 5); replace_if(ve.begin(), ve.end(), cmp, 5); swap(ve, ve2);
|
5. 常用集合算法 set_intersection set_union set_difference
1 2 3
| auto it2 = set_intersection(ve.begin(), ve.end(), ve2.begin(), ve2.end(), ve3.begin()); auto it3 = set_union(ve.begin(), ve.end(), ve2.begin(), ve2.end(), ve3.begin()); auto it4 = set_difference(ve.begin(), ve.end(), ve2.begin(), ve2.end(), ve3.begin());
|
7. 运算符优先顺序:
运算符由高到低: |
第一级:圆括号 ()、下标运算符 []、结构体成员运算符 . 和 -> |
第二级:逻辑非 !、按位取反 ~、自增自减 ++ 和 –、负号 -、类型转换 (类型)、指针运算符 * 和 &、长度运算符 sizeof |
第三级:乘法运算符 *、/ 和 % |
第四级:加法运算符 + 和 - |
第五级:移位运算符 << 和 >> |
第六级:关系运算符 <、<=、> 和 >= |
第七级:相等运算符 == 和 != |
第八级:按位与 & |
第九级:按位异或 ^ |
第十级:按位或 |
第十二级:逻辑或 |
第十四级:赋值运算符 =、+=、-=、*=、/=、%=、&=、^=、 |
第十五级:逗号运算符 , |
|
8. MFC
通过空项目创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include<afxwin.h>
class Myapp:public CWinApp { public: virtual BOOL InitInstance();
private:
};
class MyFrame:public CFrameWnd { public: MyFrame(); afx_msg void OnLButtonDown(UINT, CPoint point); private:
DECLARE_MESSAGE_MAP() };
#include"mfc.h"
Myapp app;
BOOL Myapp::InitInstance() { MyFrame* frame = new MyFrame; frame->ShowWindow(SW_SHOWNORMAL); frame->UpdateWindow(); m_pMainWnd = frame; return 1; }
BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd) ON_WM_LBUTTONDOWN() END_MESSAGE_MAP()
MyFrame::MyFrame() { Create(NULL, TEXT("Crackk")); }
VOID MyFrame::OnLButtonDown(UINT, CPoint point) { TCHAR buf[1024]; wsprintf(buf, TEXT("X = %d,Y = %d"), point.x, point.y); MessageBoxW(buf); }
|
通过MFC应用程序模版创建–基于对话框
在app的子类里有首界面的创建
1 2 3 4 5 6
| CMFC2Dlg dlg; m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK)
|
如果要修改首界面可以添加界面类(先创建资源,再创建类)
但是新界面没有最小化和最大化和拖拽功能
如果想要在界面类里访问其他控件,例如staticText类,需要在ui界面添加变量,然后就可以通过名称来访问该控件
1 2 3 4 5 6 7 8 9 10
| void CMFC2Dlg::OnBnClickedClick() { static int count = 0; count++; if (count >= 5) { hint.SetWindowTextW(TEXT("flag{1111}")); } }
|
这里代码块实际做的操作有两处
第一处:在父界面类的头文件中包含该控件
第二处:在父界面类的源文件中DoDataExchange函数里添加控件关联
1
| DDX_Control(pDX, IDC_HINT, hint);
|
给按钮添加事件处理程序时,代码层实际修改了三处代码
所属界面类的头文件中包含该事件处理函数
1 2
| afx_msg void OnBnClickedClick(); afx_msg void OnBnClickedDClick();
|
在源文件消息队列声明(BEGIN_MESSAGE_MAP)后添加消息声明
1 2
| ON_BN_CLICKED(IDC_Click, &CMFC2Dlg::OnBnClickedClick) ON_BN_CLICKED(IDC_DClick, &CMFC2Dlg::OnBnClickedDClick)
|
在源文件中添加处理函数的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void CMFC2Dlg::OnBnClickedClick() { static int count = 0; count++; if (count >= 5) { hint.SetWindowTextW(TEXT("flag{1111}")); } }
void CMFC2Dlg::OnBnClickedDClick() { hint.SetWindowTextW(TEXT("you are so smart!!")); }
|
如何格式化SetwindowTextW的参数TEXT,参数为CSting形式,等于LPCTSTR(),TEXT(),_T(),可以用Format来格式化text
1 2 3
| CString text; text.Format(_T("gogogogo!%d"), count); hint.SetWindowTextW(text);
|
9. QML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
| import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls Window { width: 640 height: 480 visible: true title: qsTr("Hello World") property int myvalue: 0
minimumHeight: 400 maximumHeight: 540 minimumWidth: 540 maximumWidth: 720
onWidthChanged: { console.log("width:",width); } onMyvalueChanged: { console.log("myvalue:",myvalue); }
Button{ id: btn1 objectName: "btn1" x: 100 width: 50 height: 50 background: Rectangle{ border.color: btn1.focus?"blue":"black" } Keys.onLeftPressed: { btn1.focus = false } } Button{ id: btn2 objectName: "btn2" x: 100 y: 100 width: 50 height: 50 background: Rectangle{ border.color: btn2.focus?"blue":"black" } Keys.onLeftPressed: { btn2.focus = true } } onActiveFocusItemChanged: { console.log("active focus item changed:",activeFocusItem) }
Rectangle{ x: 100 y: 100 z: 2 width: 100 height: 100 color: "blue" focus: true
MouseArea { anchors.fill: parent onClicked: { console.log("on clicked") } } Keys.onReturnPressed: { console.log("on return pressed") } }
Rectangle { id: rect1 width: 100 height: 50 color: "black"
anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter rotation: 60 scale: 2 antialiasing: false border.width: 2 border.color: "red" radius: 30 gradient: Gradient { GradientStop { position: 0.0; color: "lights teelblue" } GradientStop { position: 1.0; color: "blue"} } }
Rectangle { id: rect2 width: 100 height: 50 anchors.left: rect1.right anchors.leftMargin: 20 anchors.top: rect1.top color: "blue" } Rectangle { id: root width: 100; height: 100 state: "red_color" states: [ State { name: "red_color" PropertyChanges { root.color: "red" } }, State { name: "blue_color" PropertyChanges { root.color: "blue" } } ] MouseArea { anchors.fill: parent onPressed: { root.state = "blue_color" } onReleased: { root.state = "red_color"
} } transitions: [ Transition { from: "red_color" to: "blue_color"
ColorAnimation { target: root duration: 1000 } }, Transition { from: "blue_color" to: "red_color"
ColorAnimation { target: root duration: 1000 } } ] } Rectangle { id: flashingblob width: 100 height: 100 color: "blue" opacity: 1.0
SequentialAnimation on color {
ColorAnimation {
to: "red" duration: 200 }
ColorAnimation {
to: "blue" duration: 200 } }
MouseArea { anchors.fill: parent onClicked: { animateColor.start() animateOpacity.start() } }
PropertyAnimation { id: animateColor; target: flashingblob properties: "color" to: "green" duration: 1000 }
NumberAnimation { id: animateOpacity target: flashingblob property: "opacity" duration: 1000 from: 1.0 to: 0.5 } PropertyAnimation on x { to: 100 duration: 1000 }
}
Component { id: com Rectangle { width: 100 height: 100 color: "blue" Component.onCompleted: { console.log("Completed") } Component.onDestruction: { console.log("Destruction") } } }
Component { id: com2 Image { id: img source: "/login2.jpg" } }
Component { id: com3 AnimatedImage { id: gif source: "/GIF-1.gif" speed: 10 } }
Loader { id: load sourceComponent: com3
onStateChanged: { console.log("status:",status) } } Button { id: button width: 50 height: 50 x: 200 onClicked: { load.item.paused = !load.item.paused } }
MouseArea { id: mousearea width: 100 height: 100 enabled: true acceptedButtons: Qt.LeftButton | Qt.RightButton cursorShape: Qt.CrossCursor hoverEnabled: true
Rectangle { anchors.fill: parent color: "blue" } onClicked: { console.log("clicked") } onHoveredChanged: { console.log("Onhoverchanged") }
onPressed: { var ret = pressedButtons & Qt.LeftButton var ret2 = pressedButtons & Qt.RightButton if(ret == Qt.LeftButton) console.log("LEFT") else console.log("RIGHT") console.log("pressed") } onReleased: { console.log("released") } onPressAndHold: { console.log("hold") }
}
Rectangle { id: rect width: 50 height: 50 color: "red" opacity: (600.0 - rect.x) / 600 MouseArea { anchors.fill: parent drag.target: rect drag.axis: Drag.XAxis drag.minimumX: 0 drag.maximumX: container.width - rect.width
} }
}
|
Libxl使用
引入库
1 2 3
| #include "libxl-3.1/libxl-3.1.0/include_cpp/libxl.h" #pragma comment(lib,"libxl-3.1/libxl-3.1.0/lib/libxl.lib") using namespace libxl;
|
读取文件
1 2 3
| Book* book = xlCreateBook(); book->load("xxx.xls"); Sheet* sheet = book->getSheet(0);
|
读取文件大小
1 2 3 4
| int rowfirst = sheet->firstRow(); int rowlast = sheet->lastRow(); int colfirst = sheet->firstCol(); int collast = sheet->lastCol();
|
读取文件内容(表格左上角为(0,0))
1 2
| double date1 = sheet->readNum(0, 0); const char* date2 = sheet->readStr(0, 1);
|
创建新sheet
1 2
| Book* book1 = xlCreateBook(); Sheet* sheet1 = book1->addSheet("sheet1");
|
设置行宽列高
1 2
| sheetM->setCol(0, 0, 20); sheetM->setRow(0 , 20);
|
合并单元格
1
| sheet->setMerge(0,0,1,2);
|
设置字体
1 2 3 4 5 6 7 8 9
| Font *titleFont = bookM->addFont(); titleFont->setName("宋体"); titleFont->setSize(16); titleFont->setBold(true); Format* titleFormat = bookM->addFormat(); titleFormat->setAlignH(ALIGNH_CENTER); titleFormat->setFont(titleFont); titleFormat->setWrap(true); titleFormat->setAlignV(ALIGNV_DISTRIBUTED);
|
向文件写入内容
1 2
| sheet->writeStr(1,0,"xxx"); sheet->writeNum(1,1, 123);
|
保存结束
1 2
| book->save("文件保存路径"); book->release();
|
JSONCPP
这篇博客概括的很全
https://www.coonote.com/cplusplus-note/jsoncpp.html