ASmollNote记这里吧,记完一定要保存一下哦!

文章涵盖了编程中的常见问题,如程序崩溃的原因和GDB调试方法,强调了内存管理和业务理解的重要性。此外,讨论了Qt框架的应用,包括样式表、线程创建及动态库加载。还提到了数据库连接与操作,以及鼠标事件处理和窗口风格设定。作者分享了个人的工作经验,如规划功能、与同事沟通和测试注意事项。
摘要由CSDN通过智能技术生成

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)文件里,


        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值