2022.7.26
1.程序崩溃 要么访问超出了 要么指针没有分配内存/或者没有释放,所以访问的时候 和 创建指针的时候一定要分配内存 和 释放内存;如果断点看不出来就用gdb调试。
sudo gdb ./test
r
bt
c
2.业务上的要多问同事,不要不懂装懂,害人害己,一有时间就多去了解业务和代码,别自己写的程序都还不会用,平时学习也要多看文档,多自己百度查,同事说你的地方正是你不足的地方,一定要接受,并纠正自己
3.有的时候qtcreator莫名奇妙的错误 可以尝试clean再重新编译,还有路径是中文的项目,debug模式不能调试
2022.8.23
1.process start 用来启动外部程序
外部程序启动后,将随着主程序的退出而退出!
2.还可以查看CUP id 指令
QProcess p;
p.start("sh", QStringList() << "-c" << "dmidecode -t 4 | grep ID |sort -u |awk -F': ' '{pri nt $2}'
);
p.waitForFinished();
QString str = p.readAllStandardOutput();
qDebug() << str
2022.8.12
首页样式表
QPushButton{
border-style:outset;
border-color:rgb(243, 246, 246);
color:rgb(255,255,255);
}
QPushButton:hover{
background-color:qlineargradient(spread:pad, x1:0, x2:0, y1:0, y2:1,
stop: 0 rgb(239, 243, 243),
stop: 1 rgb(153, 221, 249));
}
QPushButton:pressed{
background-color:qlineargradient(spread:pad, x1:0, x2:0, y1:0, y2:1,
stop: 0 rgb(243, 245, 245),
stop: 1 rgb(74, 147, 234));
}
7.qt线程
pthread_create(&share_interface_pthread, nullptr, my_pthread_encryption_interface_work, static_ cast
void*>(pthread_data));
pthread_detach(share_interface_pthread);
第一个参数 线程要存放的新的位置或标记,第二个一般置空,第三个线程函数,第四个线程参数个数
8.pthread_create是(Unix、Linux、Mac OS X)等操作系统的创建线程的函数。它的功能是创建线程(实际上就是确定调用该线程函数的入口点)
在线程创建以后,就开始运行相关的线程函数。
#include <pthread.h>
int pthread_create
(
pthread_t *restrict tidp, //新创建的线程ID指向的内存单元。
const pthread_attr_t *restrict attr, //线程属性,默认为NULL
void *(*start_rtn)(void *), //新创建的线程从start_rtn函数的地址开始运行
void *restrict arg //默认为NULL。若上述函数需要参数,将参数放入结构中并将地址作为arg传入。
);
注意创建多线程的参数 不能是变量,也不能被主线程影响的变量传入进去否则引起不可预知的错误
解决办法就是 开辟新的内存地址, 传入的线程函数 第一个就是 存入需要传递的参数,再将这个地址作为arg传入 void *arg既是传入也是传出 因为
向的是同一个嘛
再然后就是望你定义的结构体里面 传入对应参数
PthreadData *pthread_data = static_cast<PthreadData*>(arg);
ScheduleInterface *schedule_nterface = pthread_data->schedule_interface;
QStringList *files = pthread_data->files;
KeyDevice *keydevice = pthread_data->keydevice;
int *type = pthread_data->type;
struct PthreadData
{
ScheduleInterface *schedule_interface;
QStringList *files;
bool *is_close;
KeyDevice *keydevice;
int *type;
QString *passwd;
KeyInterface *keyInterface;
MainInterface *mainInterface;
};
2022.8.26
1.以后一定要记得你工作上哪些事情没有做完,别到时候 丢三落四
2.还有什么有异议的地方要去问,多想一下哪里没做好,记得给自己争取时间
6.
void Aes::ByteToQString(QString &out, BYTE *in, int size)
{
out.clear();
for(int i = 0; i < size; i++)
{
BYTE tmp1 = in[i] >> 4;
if(tmp1 > 9)
{
tmp1 = tmp1 + 'A' - 10;
}
else
{
tmp1 = tmp1 + '0';
}
out.append(QChar(tmp1));
BYTE tmp2 = in[i] % 16;
if(tmp2 > 9)
{
tmp2 = tmp2 + 'A' - 10;
}
else
{
tmp2 = tmp2 + '0';
}
out.append(QChar(tmp2));
}
}
void Aes::QStringToByte(BYTE* out, QString in, int &size)
{
int i, j;
BYTE tmp;
size = 0;
for(i = 0; i < in.size() / 2; i++)
{
tmp = 0;
for(j = 0; j < 2; j++)
{
tmp = tmp << 4;
tmp |= Char2Num(in.at(i*2+j).toLatin1());
}
out[i] = tmp;
size ++;
}
2023.2.07
1.写任何功能前都要先做好规划,先交流好把需求尽量想完整,包括后面自己再自测的时间,以及这个功能会不会影响其他功能,这些都根你的预估时间有关的,更不要不好意思问同事,那样只会让自己更尴尬,还有遇到问题不要怕,结合自己的经验和多查然后去一步一步分模块实现,所以庆幸你已经慢慢走过来了,一定要牢记自己的经验,不是越做越糊涂是我之前压根就没理解,所以平时不要嘻嘻哈哈的 多去了解一些业务逻辑 !!!!!
同事在旁边的时候不要紧张,你越紧张越想快就越空白,不如打开代码一行一行看,然后尽量边看变表达自己的思路 然后理清代码
而不是 一片空白 慌的一批!!!!
2.那card就是 公私钥解密,组和上下级都是 对应的id
2023.2.08
一.项目笔记
1.数据库加载
1.1
class Database
{
public:
Database();
static Database * instance()
{
static Database db;
return &db;
}
bool initDB();
void closeDB();
private:
QSqlDatabase m_db;
};
bool XXDataStorage::initDB()
{
qDebug() << QString::fromLocal8Bit("数据库初始化");
QSettings iniFile("config.ini", QSettings::IniFormat);
QString ipaddr = iniFile.value("/mysql/ipaddr").toString();
int port = iniFile.value("/mysql/port").toInt();
QString username = iniFile.value("/mysql/user").toString();
QString dbname = iniFile.value("/mysql/dbname").toString();
m_db.setHostName(ipaddr);
m_db.setPort(port);
m_db.setDatabaseName(dbname);
m_db.setUserName(username);
m_db.setPassword(XX_MYSQL_LOGIN_PWD);
if (!m_db.open())
{
qDebug() << QString::fromLocal8Bit("数据库[%1 - %2:%3]连接失败[%4]").arg(dbname).arg(ipaddr).arg(port).arg(m_db.lastError().text());
return false;
}
else
{
qDebug() << QString::fromLocal8Bit("数据库[%1 - %2:%3]连接成功").arg(dbname).arg(ipaddr).arg(port);
return true;
}
}
void XXDataStorage::closeDB()
{
m_db.close();
qDebug() << QString::fromLocal8Bit("数据库关闭");
}
XXDataStorage::XXDataStorage()
{
//qDebug() << QSqlDatabase::drivers();
if (QSqlDatabase::contains("qmysql_test"))
{
m_db = QSqlDatabase::database("QMYSQL", "qmysql_test");
}
else
{
m_db = QSqlDatabase::addDatabase("QMYSQL", "qmysql_test");
}
}
bool XXDataStorage::insertCipherLog_data(int type, int pid, QString path, int result)
{
QSqlQuery query = QSqlQuery(m_db);
QString sql;
bool is_ok = false;
int createTime = QDateTime::currentDateTime().toTime_t();
sql = QString("insert into w_tasklog(type, pid, savepath, result, createtime) values(%1, %2, '%3', %4, %5);")
.arg(type).arg(pid).arg(path).arg(result).arg(createTime);
is_ok = query.exec(sql);
if(!is_ok)
{
qDebug() << sql <<query.lastError().text();
return false;
}
return is_ok;
}
bool XXDataStorage::getFileManage_data(int pid, QList<fileList> &List)
{
QSqlQuery query = QSqlQuery(m_db);
QString sql;
bool is_ok = false;
sql = QString("select * from w_taskfilelist where pid = %1 ;")
.arg(pid);
is_ok = query.exec(sql);
if(!is_ok)
{
qDebug() << sql <<query.lastError().text();
return false;
}
while(query.next())
{
fileList tempList;
tempList.id = query.value(0).toInt();
tempList.pid = query.value(1).toInt();
tempList.filePath = query.value(2).toString();
tempList.fileSize = query.value(3).toLongLong();
tempList.modifyTime = query.value(4).toInt();
tempList.isDir = query.value(5).toInt();
tempList.isEncryptd = query.value(6).toInt();
tempList.savaPath = query.value(7).toString();
List.append(tempList);
}
return true;
}
2.动态库加载
2.1
QLibrary *pModule[3];
pModule[i] = new QLibrary(path);
if(pModule[i] == nullptr)
{
qDebug() << QString::fromLocal8Bit("动态库[%1]加载失败!nullptr").arg(path);
return false;
}
3.鼠标事件
1.
protected:
void mouseMoveEvent(QMouseEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
private:
Ui::UpEncipherMode *ui;
QPoint press_point;//鼠标按下去的点
bool is_move;
void UpEncipherMode::mouseMoveEvent(QMouseEvent *e)
{
if((e->buttons() == Qt::LeftButton) && is_move)
{
QWidget::mousePressEvent(e);
QPoint mouseP = e->globalPos();
QPoint endP(mouseP.x() - press_point.x(), mouseP.y() - press_point.y());
this->move(endP);
}
}
void UpEncipherMode::mousePressEvent(QMouseEvent *e)
{
press_point = QPoint();
QWidget::mousePressEvent(e);
QPoint mouseP = e->globalPos();
int x = this->geometry().topLeft().x();
int y = this->geometry().topLeft().y();
int x_w = mouseP.x() - x;
int y_w = mouseP.y() - y;
press_point.setX(x_w);
press_point.setY(y_w);
is_move = true;
}
void UpEncipherMode::mouseReleaseEvent(QMouseEvent *e)
{
if(is_move)
{
is_move = false;
}
}
4.窗口风格
4.1
UpEncipherMode::UpEncipherMode(QWidget *parent) :
QWidget(parent),
ui(new Ui::UpEncipherMode)
{
ui->setupUi(this);
this->setWindowTitle(QString("例子"));
this->setWindowIcon(QIcon(QApplication::applicationDirPath() + QString("/") + "image/mainframe.ico"));
this->setWindowModality(Qt::ApplicationModal);
this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
modeid_text = -1;
}
2023.2.09
1.任何时候都要学会给自己争取时间,这样才有时间去学习别的
2.英语重结构,汉语重语义
3.tablewidget 只需要设置表的属性,添加表内容,并在点击表中任意一行的时候调用函数返回出对应行数,就可以做相对操作了
4.还有提交测试的时候 尽量把自己的功能说明 测试需求 和测试用例写出来,让测试方便了解你增加的新功能
5.后面的新功能代码可以不写,但一定要提前想,想这个功能的逻辑怎么实现
文件管理选择器:void (QFileDialog::*fileSelecteds)(const QStringList &files) = &QFileDialog::filesSelected;connect(file_dialog, fileSelecteds,[&](const QStringList &files){}
2023.2.10
1.linux创建线程
pthread_t my_pthread;
void pthread_myFunc();
pthread_create(&my_pthread, nullptr, pthread_myFunc, static_cast<void *>(this));
pthread_detach(my_pthread);
//myFunc(void* arg){
MainInterface *mainInterface = static_cast<MainInterface*>(arg);
}
//第三个参数static_cast<void*> 是强制转换,向基类转换默认是安全的,所以this是父亲基类,所以是安全的这也叫做向上转换,
//当然this 也可以是一个结构体 这样在my_Func中就要在开启线程前把函数结构体放进来
struct pthread_data{
对象 1;
对象 2;
}
//这里注意 函数里的参数
//myFunc(void* arg){
pthread_data *pthread_data = static_cast<pthread_data*>(arg);
}
pthread_create(&my_pthread, nullptr, pthread_myFunc, static_cast<void *>(pthread_data));
pthread_detach(my_pthread);
//pthread_detach 是线程分离,即新开的线程与主线程资源不共享,自己拷贝了一份儿
2.函数调用的参数为指针时候,注意传参 如果你传的直接是一个int型 那参数那就要加上取地址符号& 这样即表示指针也代表了指针有家即int的地址,如果你传的是指针就要看看你传的指针有没有指向有效地址,别随手写了个临时指针就去那传进去函数了,这样你的指针是野指针并没有有效地址!!!
3.QFile
QFile tmpFile("/tmp/test.txt);
if(tmpFile.exists())
{
tmpFile.remove();
}
或者
QFile myfile;
myfile.setFileName(path);
myfile.open(QIODevice::ReadOnly);
char buffer[100];
myfile.read(buffer,100);
while(!myfile.atEnd())
{
char buffer[666];
myfile.read(buffer,666);
}
2023.2.14
1.复习网站
http://c.biancheng.net/view/2228.html
多画流程图
还有我们做新功能的时候,尽量多思考最后写代码!!!!!
2.关于explictit
explicit 取消了隐式转换,直接传参显示,赋值给 隐式
所以如果类的构造函数 用了explicit显示声明了构造函数, 则子类调用的时候必须 显式调用 否则出错
还有explicit 只对函数声明 单个参数时候有效, 0个或多个的时候 expicit无效
explicit关键字只需用于类内的单参数构造函数前面。由于无参数的构造函数和多参数的构造函数总是显示调用,这种情况在构造函
前加explicit无意义。
google的c++规范中提到explicit的优点是可以避免不合时宜的类型变换,缺点无。所以google约定所有单参数的构造函数都必须
显示的,只有极少数情况下拷贝构造函数可以不声明称explicit。例如作为其他类的透明包装器的类。
effective c++中说:被声明为explicit的构造函数通常比其non-explicit兄弟更受欢迎。因为它们禁止编译器执行非预期(往
也不被期望)的类型转换。除非我有一个好理由允许构造函数被用于隐式类型转换,否则我会把它声明为explicit,鼓励大家遵循
同的政策
3.关于提交测试
1.当我们写完或者增加新功能后,提交测试时,最好写个说明,
说明一下,我们的测试模块:即那个是新增加的功能
第二个就是列出测试项,这个功能会影响别的什么功能吗
2023.2.15
1.代码的质量和整洁度成正比 ,要写美的软件,美的软件反而更省时省力,
2023.2.20
1.所以还是要多读书,看完敏捷软件开发 30%,之后我在做新的需求的时候,尽量遵循单一,开放封闭原则,把代码结构设计整洁,
2.其次就是 作需求的时候 先完成一个测试用例,我是先把,主要功能实现,最后再去增加ui界面什么的,我感觉这样的写代码也是一种思路,或者我们先设计好整个结构,再去写,这可能就是一些大的项目工程了,我这种小需求,我就先把核心功能代码写出来,我感觉更舒服,能简单就简单
2023.2.23
1.Visual Studio
1.用vs创建qt工程的时候 debug路径就用默认系统的 不然调试会出醋
2.记得备份一下在做未知的操作 否则文件被你删了都不知道
3.还有 class ui 是你qt设计师里面的 类名 需要对应上 不然 你 new Ui::MainInterace失败
4. vs程序默认路径是根本地 exe同级目录下的
5.如果我们加载动态库 需要放在同级目录下跟exe 否则就会报错无法查找或打开PDB文件
6.写类的时候 构造函数也要cpp里写出来 不然vs会编译会出奇怪的错误
2.今天做新的需求差点忘啦体现画好需求图,幸好想起来了,以后要养成画图的好习惯
3.有进步哦,今天第二次画需求规划图,我就联想到了 读的敏捷软件开发里的 我们在画完流程图开始写代码前,先写测试用例(即 能用最短的代码 表述勾勒出核心功能,能跑通,后面再逐步完善
4.我还想到了把测试需求 顺便列出来
第一是这样能更有助于我们理解需求
第二也方便到时候提交测试的时候,测试人员阅读
2023.3.1
1.结构体 传输数据是很方便的 尤其数据解析的时候
比如我们 定义一个结构体 然后memcpy的时候 强制转化成(BYTE*) 最后 我们的结构体还是不变的,说白了 字节该怎么存放数据还是怎么存放数据, 其实结构体就是把字节划分成一块儿一块儿的了
2.果然好使,就是和别人交流的时候 脑子画副图 这样会更清晰反映更快 更容易理解
3.#ifdef.......#else......#endif
QT:坑
1.在有些国产机系统上 不可以直接用
this->setWindowFlags(Qt::FramelessWindowHint);
需要写成this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
2.qt不可以在QThread的子类中创建带有QWidget的 类 如果需要则需要发射信号到主函数才可以创建窗口类
2023.03.03
1.多做题 多看面试题 和面试知识点, 一定一定要把c++学优秀,因为 优秀的c++程序员都被大厂招走了!!!我也要去~!!!!!
2.完了,就是这种感觉 ,我现在特别想做题,特别想去了解一些新的知识点
3.多使用帮助文档 遇到不会的函数的时候
2023.05.08
1.如果 读写两个文件 可以一个用文件流 FILE *hand 一个用QFile file(dstpath);打开
这样第一个文件流的形式 如果fread(buff_w, sizeof(char), BUFFER_MAX, hand);
这样文件流他是有指针的 所以读到哪 指针就停到哪 ,这样分次 或者循环一个buffer的大小,
拷贝到另一个 file.write (也就是destpath)文件里,