qt日志信息模块(模块化程序)功能块复制直接使用不冲突

一、前言

日志功能,可以在任何想要记录操作的地方增加函数,之后会在日志信息列表中查询到。

二、环境

windows

qt5.7

三、正文

话不多说,直接一步一步复制粘贴即可。

1.main函数增加函数

//增加日志信息
void writejournal(QString note)
{
    QDateTime time;
    QString sqlnote;
    QString date=time.currentDateTime().toString("yyyy-MM-dd");
    QSqlQuery query(db);
    QString sql=QString("select * from Sys_journal where date is '%1'").arg(date);
    if(query.exec(sql)&&query.next()){
        sqlnote=query.value(1).toString();
    }
    if(!sqlnote.isNull()){//有当天记录
        sqlnote+="\r\n"+time.currentDateTime().toString("hh:mm:ss ")+note;
        query.exec(QString("UPDATE Sys_journal set note='%1' where date ='%2';").arg(sqlnote).arg(date));
    }
    else{//无当天记录
        sqlnote+=time.currentDateTime().toString("hh:mm:ss ")+note;
        query.exec(QString("INSERT INTO Sys_journal(date,note) VALUES ('%1','%2');").arg(date).arg(sqlnote));
    }
}

并在全局头文件中包含

extern void writejournal(QString note);

2.数据库建立日志表格

 3.在使用的地方增加日志信息添加函数

writejournal(QString("导出%1使用日志信息").arg(searchdata[0].at(i)));

至此日志信息保存功能完毕,接下来就是日志管理和查询部分了

4.ui文件增加表格,查询按键,筛选日志条件信息控件

 5.查询日志头文件

#ifndef USED_H
#define USED_H
#include "wurenjkgl_header.h"
namespace Ui {
class used;
}
class used : public QWidget
{
    Q_OBJECT
public:
    explicit used(QWidget *parent = 0);
    ~used();
protected:
    //表格滑动刷新
    bool eventFilter(QObject *obj, QEvent *event);
private slots:
    //历史数据查询模块
    void on_btn_datasearch_clicked();//数据查询
    void tableWidget_journal_init(QTableWidget *tab,QVector<int> line,QStringList name,bool push);
    void tableWidget_journal_refuse(QTableWidget *TableWidget);//更新历史数据信息
private:
    Ui::used *ui;
    QScrollBar *m_scrollBarV;//表格滚动实现
};
#endif // USED_H

6.查询日志源码

#include "used.h"
#include "ui_used.h"
#include "login.h"
used::used(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::used)
{
    ui->setupUi(this);
    this->setWindowModality(Qt::ApplicationModal);//设置一直保持在顶端,不可切换其他界面,除非被新界面带此属性覆盖
    this->setWindowFlags(Qt::FramelessWindowHint);//设置界面无边框

    connect(ui->btn_exit,&QPushButton::clicked,[=](){this->close();});//退出健康管理界面
    connect(ui->btn_exiticon,&QPushButton::clicked,[=](){this->close();});//退出健康管理界面

    //日志初始化
    QVector<int> historytable_line;
    historytable_line.append({150,300,1000,200});//配置表格宽度6列
    QStringList historytable_title;
    historytable_title.append({"序号","日期","操作日志信息","功能"});//配置表格表头名称6列
    m_scrollBarV = ui->tableWidget_used->verticalScrollBar();//绑定表格滑动效//在表格第一次初始化前必须初始化一次,否则程序崩溃
    tableWidget_journal_init(ui->tableWidget_used,historytable_line,historytable_title,true);//初始化表格表头
    tableWidget_journal_refuse(ui->tableWidget_used);//更新历史信息
    connect(ui->tableWidget_used,&QTableWidget::cellPressed,[=](){//点击表格某行生效,当需要滑动时必定点击到表格某行。
        m_scrollBarV = ui->tableWidget_used->verticalScrollBar();//绑定表格滑动效
    });


}

used::~used()
{
    delete ui;
}
//数据查询
void used::on_btn_datasearch_clicked()
{
    tableWidget_journal_refuse(ui->tableWidget_used);//更新历史信息
}
//通用表格初始化函数,建立表格列,刷新表头和列宽
void used::tableWidget_journal_init(QTableWidget *tab,QVector<int> line,QStringList name,bool push)
{
    tab->clearContents();//清空内容
    tab->verticalHeader()->setVisible(false);//去掉行序号
    tab->horizontalHeader()->setFixedHeight(80); //设置表头的高度
    tab->horizontalHeader()->setStretchLastSection(true);//设置表格是否充满,即行末不留空
    //tab->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); //禁止鼠标拖放列宽度
    tab->horizontalHeader()->setFocusPolicy(Qt::NoFocus); //设置表头不可选
    tab->horizontalHeader()->setHighlightSections(false); //设置表头不可选//QTableWidget表头塌陷问题解决
    tab->setEditTriggers(QAbstractItemView::NoEditTriggers);//设置表格内容不可修改
    tab->setSelectionBehavior(QAbstractItemView::SelectRows);//设置选中就是一行选中
    tab->setSelectionMode(QAbstractItemView::SingleSelection);//设置只能选中一行
    tab->setFocusPolicy(Qt::NoFocus);//设置去掉选中虚线框
    //tab->setAlternatingRowColors(true);//设置表格颜色交替
    //表格滚动部分实现函数:初始化函数+以下俩函数+ (QObject *obj, QEvent *event)
    if(push)tab->viewport()->installEventFilter(this);//对此对象安装事件过滤器
    if(push)tab->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);//设置滚动模式按照像素滑动,做表格滑动时使用
    tab->setColumnCount(line.size());//设置列数量
    for(int i=0;i<line.size();i++)
        tab->setColumnWidth(i,line.at(i));
    tab->setHorizontalHeaderLabels(name);//设置table列表各项标题
    tab->setRowCount(0);
}
//更新历史数据信息,默认包含日期筛选,人员筛选,编码筛选,如有不同功能更改相应部分
void used::tableWidget_journal_refuse(QTableWidget *TableWidget)
{
    //更新页面控件操作员列表,每次都更新,以防人员管理改变
    QString lastname=ui->comboBox_user->currentText();
    ui->comboBox_user->clear();//清空操作员列表
    ui->comboBox_user->addItems(Data_user.usernamelist);//放入最新操作员列表
    ui->comboBox_user->setCurrentText(lastname);
    //筛选搜索数据库数据
    QStringList searchterm;//筛选条件,默认包含日期筛选,人员筛选,编码筛选,如有不同功能更改相应部分
    if(ui->checkBox_starttime->isChecked())//判断起始日期是否包含
        searchterm.append(QString("(date>'%1')").arg(ui->dateTimeEdit_start->dateTime().toString("yyyy-MM-dd")));//date是数据库表头
    if(ui->checkBox_endtime->isChecked())//判断截止日期是否包含
        searchterm.append(QString("(date<'%1')").arg(ui->dateTimeEdit_end->dateTime().toString("yyyy-MM-dd")));//date是数据库表头
    if(ui->checkBox_user->isChecked())//判断操作员是否包含
        searchterm.append(QString("note like '%%1%'").arg(ui->comboBox_user->currentText()));//note是数据库表头
    if(ui->checkBox_car->isChecked())//判断车型是否包含
        searchterm.append(QString("note like '%%1%'").arg(ui->comboBox_user_2->currentText()));//note是数据库表头
    QSqlQuery qry(db);
    QString sql=QString("select * from Sys_journal");
    if(searchterm.size()>0){//判断是否有筛选条件
        sql.append(" where ");
        for(int i=0;i<searchterm.size();i++){
            sql.append(searchterm.at(i));//添加筛选内容
            if(i<(searchterm.size()-1))
                sql.append(" and ");//添加连接符,最后一个不添加
        }
    }
//    ui->btn_datasearch->setToolTip(sql);
    qDebug()<<sql;
    QStringList searchdata[2];//搜索数据,本程序数据库包含2列,如更换不同程序数据列不同更改相应部分
    if(qry.exec(sql)){
      for(int i=0;qry.next()&&i<10000;i++){
          searchdata[0].append(qry.value(0).toString());//赋值日期
          searchdata[1].append(qry.value(1).toString());//赋值日志信息
      }
    }
    //更新表格显示
    TableWidget->clearContents();//清空内容
    TableWidget->setRowCount(searchdata[0].size());//设置表格行数
    //删除上次表格的控件,这里必须先删除widget里面的控件,后删除widget,否则程序运行崩溃
    QList<QPushButton*> btnList = TableWidget->findChildren<QPushButton*>();
    for(int i=0;i<btnList.size();i++)delete btnList[i];//这里仍然要删除按键,没有因为按键在widget里先删除widget而被删除,还得先删除按键,否则崩溃
    QList<QWidget*> widgetList = TableWidget->findChildren<QWidget*>();
    for(int i=0;i<widgetList.size();i++){
        if(widgetList.at(i)->objectName().contains("widget_journaltable_"))//判断是表格创建控件,才刷新
            delete widgetList[i];//删除表格中新建的widget,根据object命名,避免错误删除其他widget
    }
    for(int i=0;i<searchdata[0].size();i++){  //刷新信号列表
        TableWidget->setItem(i,0,new QTableWidgetItem(QString("%1").arg(i+1,2,10,QChar('0'))));//更新序号
        TableWidget->item(i,0)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//数据居中
        TableWidget->setItem(i,1,new QTableWidgetItem(searchdata[0].at(i)));//更新日志时间
        TableWidget->item(i,1)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//数据居中
        TableWidget->setItem(i,2,new QTableWidgetItem(searchdata[1].at(i)));//更新日志信息
        TableWidget->item(i,2)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//数据居中
        //创建水平布局
        QHBoxLayout *vLayout = new QHBoxLayout(this);//创建布局,布局不需要单独删除,会随着widget删除
        vLayout->setContentsMargins(10, 2, 10, 2);// 设置外间距left,top,right,bottom
        vLayout->setSpacing(10);//设置内间距
        //创建widget放入单元格中,在widget里放入其他控件
        QWidget *widget = new QWidget(this);
        widget->setObjectName(tr("widget_journaltable_%1").arg(i+1));
        widget->setStyleSheet("background-color:rgb(0,0,0,0)");
        //创建按键1,根据需求更改创建的控件和数量
        QPushButton *aaa=new QPushButton(this);//创建按键控件,按键控件需要单独删除,不会随着widget删除
        aaa->setObjectName(tr("btn_table_look%1").arg(i+1));
        aaa->setText("日志导出");//设置文本
        aaa->setStyleSheet("font: 20pt ""黑体"";background-color:rgb(0,0,0,0);color: rgb(202, 234, 206);border-radius:10px;");//设置风格
        aaa->setMinimumSize(140,45);//设置按键控件最小尺寸
        aaa->setIcon(QIcon(":/icon/baogao.png"));//设置图标
        aaa->setIconSize(QSize(40,40));//设置图标尺寸
        //创建按键2,根据需求更改创建的控件和数量
        QPushButton *bbb=new QPushButton(this);//创建按键控件,按键控件需要单独删除,不会随着widget删除
        bbb->setObjectName(tr("btn_table_delete%1").arg(i+1));
        bbb->setText("数据删除");//设置文本
        bbb->setStyleSheet("font: 20pt ""黑体"";background-color:rgb(0,0,0,0);color: rgb(202, 234, 206);border-radius:10px;");//设置风格
        bbb->setMinimumSize(140,45);//设置按键控件最小尺寸
        bbb->setIcon(QIcon(":/icon/删除.png"));//设置图标
        bbb->setIconSize(QSize(40,40));//设置图标尺寸
        //将widget放入表格单元格中
        vLayout->addWidget(aaa);//将按键放入布局中
        vLayout->addWidget(bbb);//将按键放入布局中
        widget->setLayout(vLayout);//将布局放入widget中
        TableWidget->setCellWidget(i,3,widget);//插入widget到表格指定行列
        widget->show();//显示widget
        TableWidget->setRowHeight(i,60);//设置行高
        //绑定自定义控件按键点击槽函数,根据需求更改创建的控件和数量
        connect(aaa,&QPushButton::clicked,[=](){//绑定按键点击回调槽函数
            QString dir = QFileDialog::getExistingDirectory(this, tr("选择信息导出文件目录"),"/home",QFileDialog::ShowDirsOnly|QFileDialog::DontResolveSymlinks);
            if(dir.isEmpty())
                QMessageBox::information(this,"提示","路径为空!设置保存报告路径失败!");
            else{
                bool exist;
                QDir *folder = new QDir();
                QString historydir="/journal";
                exist = folder->exists(dir+historydir);//文件夹是否存在
                if(!exist)folder->mkdir(dir+historydir);//不存在创建文件夹
                //写入txt文件
                QFile file(dir+"/journal/"+searchdata[0].at(i)+"日志信息.txt");
                file.open(QIODevice::WriteOnly|QIODevice::Text);
                QTextStream stream(&file);
                stream<<searchdata[1].at(i);
                file.close();
                QMessageBox::information(this,"提示","保存日志信息成功!");
                writejournal(QString("导出%1使用日志信息").arg(searchdata[0].at(i)));
            }
        });
        connect(bbb,&QPushButton::clicked,[=](){//绑定按键点击回调槽函数
            int res=massage_dialog(2,"提示",QString("是否确认删除序号%1数据?\r\n日期:%2")
                                   .arg(QString("%1").arg(i+1,2,10,QChar('0')))
                                   .arg(searchdata[0].at(i)),4);
            if(res==0){//点击确认返回0,点击取消或关闭返回1
                QSqlQuery qry(db);
                qry.exec(QString("delete from Sys_journal where date = '%1'").arg(searchdata[0].at(i)));
                qry.prepare("vacuum");//删除成功之后释放内存碎片
                qry.exec();
                tableWidget_journal_refuse(ui->tableWidget_used);//更新历史信息
                massage_dialog(1,"提示","删除数据成功!",1);
            }
        });
    }
    TableWidget->resizeRowsToContents();//根据单元格内容自动换行
}
//滑动表格实现函数
bool used::eventFilter(QObject *obj, QEvent *event)
{
    static signed int press_y   = 0;
    static signed int move_y    = -1;
    static signed int release_y = 0;
    static QDateTime pressDateTime;
    static QPropertyAnimation *animation = new QPropertyAnimation();
//    qDebug()<<obj->objectName()<<event->type();
    if("qt_scrollarea_viewport" != obj->objectName())
        return false;
    int scrollV_max = m_scrollBarV->maximum();//获取当前滚动控件的最大进度条值
    int scrollV_min = m_scrollBarV->minimum();//获取当前滚动控件的最小进度条值,基本是0
#ifdef WINDOWS
    int global_y=QCursor::pos().y();//相对于正屏幕的y坐标,window下此方法即可获取
#else
    QMouseEvent *event1 = (QMouseEvent *)event;
    int global_y=event1->globalPos().y();//相对于正屏幕的y坐标,linux下用此方法获取
#endif
    //根据鼠标的动作——按下、放开、拖动,执行相应的操作
    if(event->type() == QEvent::MouseButtonPress){//记录按下的时间、坐标
        pressDateTime = QDateTime::currentDateTime();
        move_y  = global_y;
        press_y = move_y;
        animation->stop();
    }
    else if(event->type() == QEvent::MouseButtonRelease){//鼠标放开,根据鼠标拖动的垂直距离和持续时间,设置窗口滚动快慢程度和距离
        if(animation->targetObject() != m_scrollBarV){
            animation->setTargetObject(m_scrollBarV);
            animation->setPropertyName("value");
        }
        move_y = -1;
        release_y = global_y;
        QObject *parent_obj = obj->parent();
        if(parent_obj != 0 || parent_obj->inherits("QAbstractItemView"))
            QTimer::singleShot(150, (QAbstractItemView *)parent_obj, SLOT(clearSelection()));
        int endValue;
        int pageStep;
        if(release_y - press_y != 0 && qAbs(release_y - press_y) > 45){
            int mseconds = pressDateTime.msecsTo(QDateTime::currentDateTime());
            int limit = 440;
            pageStep = 240;//scrollBarV->pageStep();
            if(mseconds > limit)//滑动的时间大于某个值的时候,不再滚动(通过增加分母)
                mseconds = mseconds + (mseconds - limit) * 20;
            if(release_y - press_y > 0){
                endValue = m_scrollBarV->value()- pageStep * (200.0 / mseconds);//.0避免避免强制转换为整形
                if(scrollV_min > endValue)endValue = scrollV_min;
            }
            else if(release_y - press_y < 0){
                    endValue = m_scrollBarV->value() + pageStep * (200.0 / mseconds);
                    if(endValue > scrollV_max)
                        endValue = scrollV_max;
            }
            if(mseconds > limit)mseconds = 0;//滑动的时间大于某个值的时候,滚动距离变小,减小滑动的时间
            animation->setDuration(mseconds+550);
            animation->setEndValue(endValue);
            animation->setEasingCurve(QEasingCurve::OutQuad);
            animation->start();
            return true;
        }
    }
    else if(event->type() == QEvent::MouseMove && move_y >= 0){//窗口跟着鼠标移动
        int move_distance = global_y - move_y;
        int endValue = m_scrollBarV->value() - move_distance;
        if(scrollV_min > endValue)endValue = scrollV_min;
        if(endValue > scrollV_max)endValue = scrollV_max;
        m_scrollBarV->setValue(endValue);
        move_y = global_y;
    }
    return false;
}

有一个login的头文件,是用到了全局用户信息,可参照前面人员管理通用模板文章。

或者自定如下结构体,或者自己二次更改程序。

//用户管理结构体
typedef struct
{
    QString now_username;//当前用户
    QString now_password;//当前密码
    bool now_root;//当前权限
    QString now_noted;//当前备注
    QStringList usernamelist;//用户列表
    QStringList userpswdlist;//用户密码
    QVector<bool> userroot;//用户权限
    QStringList usernote;//用户备注
}UserList;

最后,效果演示:

 

四、结语

本文不放里程,全看正文即可。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大桶矿泉水

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值