QTabelWidget表格的插入、删除、更新、动态滑动条以及配合QFile进行表格内容的长期存储

发布于:2023-01-10 ⋅ 阅读:(153) ⋅ 点赞:(0)

想实现表格 每一步都不能错过

【1】QTabelWidget界面初始化

在这里插入图片描述

【2】QTabelWidget效果图

在这里插入图片描述

【3】QTabelWidget初始化

/******************************************************************清洗日志表格初始化******************************************************/
void MainWindow::MenuRinseLogInit()
{
    ui->PB_updatetabl->hide();//刷新表格按钮  清洗结束才出现
    //对表格的初始化
    ui->tableWidget_rinselog->setRowCount(0);                   // 设置表格行数
    ui->tableWidget_rinselog->setColumnCount(4);                 // 设置表格列数
    //添加表头内容
    QStringList tablehead;
    tablehead.append(tr("清洗模式"));
    tablehead.append(tr("开始时间"));
    tablehead.append(tr("结束时间"));
    tablehead.append(tr("总清洗时间"));
    ui->tableWidget_rinselog->setHorizontalHeaderLabels(tablehead);

    ui->tableWidget_rinselog->setShowGrid(true);//设置显示网格
    //表头风格
    ui->tableWidget_rinselog->horizontalHeader()->setStyleSheet(
        "QHeaderView::section{background-color:rgb(189,255,253);"
        "font:15pt;color: black;};");//设置表头第一行风格
    //表格内容风格
    ui->tableWidget_rinselog->setStyleSheet("background-color:rgb(255,255,255);""color: blue;");
    QFont font =ui->tableWidget_rinselog->font();
    font.setBold(false);//不加粗
    font.setFamily("PingFang SC Medium");
    ui->tableWidget_rinselog->setFont(font);//设置字体

    ui->tableWidget_rinselog->verticalHeader()->setHidden(true); //隐藏行号列

    ui->tableWidget_rinselog->resizeColumnsToContents();//表格所有列自动适应文本大小
    ui->tableWidget_rinselog->resizeRowsToContents();//表格所有行自动适应文本大小
    ui->tableWidget_rinselog->setEditTriggers(QAbstractItemView::NoEditTriggers);  //	设置表格内容不可编辑
    ui->tableWidget_rinselog->horizontalHeader()->setResizeContentsPrecision(QHeaderView::Fixed);  //设置表头不可拖动
    ui->tableWidget_rinselog->setSelectionMode(QAbstractItemView::NoSelection);		//设置表格内容不可选
    ui->tableWidget_rinselog->horizontalHeader()->setStretchLastSection(true); //行头自适应表格
    ui->tableWidget_rinselog->horizontalHeader()->setFixedHeight(30);//设置表头高度
    ui->tableWidget_rinselog->verticalHeader()->setDefaultSectionSize(30);//设置行高度

    //ui->tableWidget_rinselog->setFrameShape(QFrame::StyledPanel);//设置边框跟单元格差不多
    //去除选中虚线框
    ui->tableWidget_rinselog->setFocusPolicy(Qt::NoFocus);
    //点击表时不对表头行光亮(获取焦点)
    ui->tableWidget_rinselog->horizontalHeader()->setHighlightSections(false);
    ui->tableWidget_rinselog->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);//平均列宽,固定
    ui->tableWidget_rinselog->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);//垂直滚动条显示
    ui->tableWidget_rinselog->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);//水平滚动显示
    //设置纵向滚动条样式
        ui->tableWidget_rinselog->verticalScrollBar()->setStyleSheet(
                "QScrollBar{background-color:rgb(255,255,255); width:30px;}"
                "QScrollBar::handle{background-color:rgb(189,255,253); border:2px solid transparent; border-radius:5px;}"
                "QScrollBar::handle:hover{background-color:rgb(189,255,253);}"
                "QScrollBar::sub-line{background:transparent;}"
                "QScrollBar::add-line{background:transparent;}");

//        //设置横向滚动条样式
//            ui->tableWidget_rinselog->horizontalScrollBar()->setStyleSheet(
//                    "QScrollBar{background-color:rgb(255,255,255); height:20px;}"
//                    "QScrollBar::handle{background-color:rgb(255,170,0); border:2px solid transparent; border-radius:5px;}"
//                    "QScrollBar::handle:hover{background-color:rgb(255,170,0);}"
//                    "QScrollBar::sub-line{background:transparent;}"
//                    "QScrollBar::add-line{background:transparent;}");

    ui->tableWidget_rinselog->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);//设置滑动效果

       //设置手动滑动事件
        m_scrollBarV = ui->tableWidget_rinselog->verticalScrollBar();
        QObjectList objectList = ui->tableWidget_rinselog->children();
        for(int i = 0; i < objectList.count(); i++)
        {
            if(objectList.at(i)->objectName() == "qt_scrollarea_viewport")
            {
                objectList.at(i)->installEventFilter(this);
            }
        }
    //设置表格一直显示最后内容=========================在每次插入都要写这个  不然不会定位到最后
    ui->tableWidget_rinselog->scrollToBottom();

    //使用进度条表示写了多少
    ui->progressBar__tab->setRange(0,100);
    ui->progressBar__tab->setValue(0);
    ui->progressBar__tab->hide();
}

【4】QTabelWidget内容写入文件和读出

/*************************************************************表格加载进文件和文件加载进表格***********************************************/
/*实际表格内容在机子重启后会消失,所以需要写进文件,下次开机从文件写入*/
QString MainWindow::LoadTabtoFileOrFileLoadtoTab(QString tabelflag)
{
        //设置标志位 开机 关机
        if(tabelflag == "写入文件" )//将今日清洗的数据全部存入文件  ====================[放在清洗结束关机前]
        {
            QString alldata;
            QString writeRowClumAlldata;
            //17行  4列
            uint32_t row = ui->tableWidget_rinselog->rowCount();//获取行
            uint8_t colum =ui->tableWidget_rinselog->columnCount();//获取列
            qDebug()<<"行 列  "<<row<<colum<<endl;
            if(row == 0 &&(colum == 4))//今日未清洗,表格没插入
            {
                    qDebug()<<"there is no rinse record today"<<endl;
                    return "";
            }
            //使用静态变量存储表格内容
            for(unsigned int i=row;i<=row;i++)//一行一行的写入文件
            {
                QTableWidgetItem *item1 = ui->tableWidget_rinselog->item(i-1,2);//获取单元格地址
                if(item1 == NULL){//跳过不写入
                  //跳过  
                }
                else{
                        for(unsigned int j=0;j<colum;j++)
                        {
                             qDebug()<<"行内容="<<ui->tableWidget_rinselog->item(i-1,j)->text()<<endl;
                             alldata.append(ui->tableWidget_rinselog->item(i-1,j)->text()+"@");//最后带@
                        }
                        //qDebug()<<"alldata="<<alldata<<endl;
                        //存储进文件包括:行,列,表格所有内容
                         writeRowClumAlldata = QString("%1@%2@%3").arg(row).arg(colum).arg(alldata);
                         //qDebug()<<"writeRowClumAlldata="<<writeRowClumAlldata<<endl;
                         //写入文件
                         datastorage.DataStorageManage(writeRowClumAlldata,RinseLog);//实际内容:行 列 数据  \n
                }
              }
        }
        else if(tabelflag == "写入表格")//加载进表格=================================[在开机初始化时]
        {
                 qDebug()<<"flag="<<tabelflag<<endl;
                 //每次点击下一页 页码++
                 //读取5行4列内容=================从文件读取数据  每次读取17行  自行选择
                 QString readRowClumAlldata = datastorage.ReadStorageRinseLogData(RinseLog,17,"下一页");//包括换行符
                 if(readRowClumAlldata=="" || readRowClumAlldata=="\n")//文件空
                 {
                     qDebug()<<"file  data is empty"<<endl;
                     return readRowClumAlldata;
                 }
                 QStringList list = readRowClumAlldata.split("\n");//分割
                 qDebug()<<"readRowClumAlldata="<<readRowClumAlldata<<endl;
                 qDebug()<<"list_size="<<list.size()<<"list="<<list<<endl;
                 list.removeLast();//删除最后一个无用字符
                 qDebug()<<"list_size="<<list.size()<<"list="<<list<<endl;
                 for (int i=0;i<list.size();i++)//=17执行十七遍
                 {
                         QStringList listdata= QString("%1").arg(list.at(i)).split("@");
                         listdata.removeLast();//删除最后一个无用字符
                         uint32_t row = listdata.at(0).toInt();
                         uint8_t colum = listdata.at(1).toInt();
                         if(row == 0 &&(colum == 4))//今日未清洗
                         {
                                 qDebug()<<"there is no rinse record today"<<endl;
                                 return "";
                         }
                         qDebug()<<"行 列  数据"<<row<<colum<<listdata<<endl;
                         //删除行列
                         listdata.removeFirst();//行
                         listdata.removeFirst();//列
                         ui->tableWidget_rinselog->insertRow(ui->tableWidget_rinselog->rowCount());//不管值等于多少,每次只插入一行
                         for (unsigned int j=0;j<colum;j++)
                         {
                                 if(j == 0)
                                 {
                                     //清洗模式
                                     ui->tableWidget_rinselog->setItem(ui->tableWidget_rinselog->rowCount()-1,j,new QTableWidgetItem(tr(listdata.at(j).toUtf8())));
                                     //设置对齐
                                     ui->tableWidget_rinselog->item(ui->tableWidget_rinselog->rowCount()-1,j)->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
                                 }
                                 else if(j==1)
                                 {
                                     //开始时间
                                     ui->tableWidget_rinselog->setItem(ui->tableWidget_rinselog->rowCount()-1,j,new QTableWidgetItem(tr(listdata.at(j).toUtf8())));
                                     //设置对齐
                                     ui->tableWidget_rinselog->item(ui->tableWidget_rinselog->rowCount()-1,j)->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
                                 }
                                 else if(j==2)
                                 {
                                     //结束时间
                                     ui->tableWidget_rinselog->setItem(ui->tableWidget_rinselog->rowCount()-1,j,new QTableWidgetItem(tr(listdata.at(j).toUtf8())));
                                     //设置对齐
                                     ui->tableWidget_rinselog->item(ui->tableWidget_rinselog->rowCount()-1,j)->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
                                 }
                                 else if(j==3)
                                 {
                                     //总时间
                                     ui->tableWidget_rinselog->setItem(ui->tableWidget_rinselog->rowCount()-1,j,new QTableWidgetItem(tr(listdata.at(j).toUtf8())));
                                     //设置对齐
                                     ui->tableWidget_rinselog->item(ui->tableWidget_rinselog->rowCount()-1,j)->setTextAlignment(Qt::AlignCenter|Qt::AlignVCenter);
                                 }
                              }
                             //执行一次,删除列表4个元素  元素个数=行*列
                             listdata.removeFirst();
                             listdata.removeFirst();
                             listdata.removeFirst();
                             listdata.removeFirst();
                             //qDebug()<<"listdata="<<listdata<<"listdata_size"<<listdata.size()<<endl;
                     }
                     ui->tableWidget_rinselog->scrollToBottom();//滑动条最底部
        }
        else//不满足条件调用此函数时  直接返回
        {
            return "";
        }
        return "1";

}

【5】QTabelWidget插入表格和写入文件

 //插入1行
   ui->tableWidget_rinselog->insertRow(ui->tableWidget_rinselog->rowCount());//尾插 依次往后
   //清洗模式  某行0列插入
   ui->tableWidget_rinselog->setItem(ui->tableWidget_rinselog->rowCount()-1,0,new QTableWidgetItem(tr("强制冲洗")));
   //设置对齐  垂直和居中
   ui->tableWidget_rinselog->item(ui->tableWidget_rinselog->rowCount()-1,0)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
   //开始时间
   QStringList split = ui->label_time->text().split(":");
   split.removeLast();
   endtime = split.at(0).toInt()*60+split.at(1).toInt();//总强制冲洗分钟
   QString add = QString("%1:%2").arg(split.at(0)).arg(split.at(1));; //静态变量只初始化一次 2022/1/1
   //开始时间只显示一次
   ui->tableWidget_rinselog->setItem(ui->tableWidget_rinselog->rowCount()-1,1,new QTableWidgetItem(tr("%1%2%3").arg(ui->label_date->text()).arg(" ").arg(add)));
   //设置对齐
   ui->tableWidget_rinselog->item(ui->tableWidget_rinselog->rowCount()-1,1)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
   ui->tableWidget_rinselog->hideRow(currRow);//隐藏行,读在表格时在显示
//结束时间=系统时间+清洗总时间
static uint32_t totalmin = endtime+starttime;
uint8_t hh =totalmin/60;
uint8_t min =totalmin%60;
QString h ;
QString m;
if(hh<10){
 h =QString("0%1").arg(hh);
}
else{
 h=QString("%1").arg(hh);
}
if(min<10){
 m =QString("0%1").arg(min);
}else
{
 m=QString("%1").arg(min);;
}
currow = currRow;//不管在那种清洗模式  切换回来后还是这个清洗模式的行
rinsehh = h;//结束时间 小时
rinsemm = m; // 结束时间 分钟
rinsetotaltime = starttime;//总时间
ui->tableWidget_rinselog->showRow(currow);//显示行
//结束时间
ui->tableWidget_rinselog->setItem(currow,2,new QTableWidgetItem(tr("%1 %2:%3").arg(ui->label_date->text()).arg(rinsehh).arg(rinsemm)));
ui->tableWidget_rinselog->repaint();
//设置对齐
ui->tableWidget_rinselog->item(currow,2)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
//总时间=ui->label_rinseleft的开始时间
ui->tableWidget_rinselog->setItem(currow,3,new QTableWidgetItem(tr("%1小时%2分钟").arg(rinsetotaltime/60).arg(rinsetotaltime%60)));
ui->tableWidget_rinselog->repaint();
//设置对齐
ui->tableWidget_rinselog->item(currow,3)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
datastorage.DataStorageManage(QString("强制冲洗 》= 2 %1 水洗:总时间=%2 固定时间=%3").arg(QDateTime::currentDateTime().toString("hh:mm:ss")).arg(ui->label_rinseleft->text().toUInt()).arg(ui->stage1_time_1->text()),PrintfLog);//实际内容:行 列 数据  \n
ui->tableWidget_rinselog->viewport()->update();//刷新内容
ui->tableWidget_rinselog->update();//刷新控件
ui->tableWidget_rinselog->show();
ui->widget_10->update();//刷新
ForcedRinseFlag = 0;

//不去后台看清洗日志直接写入文件,或者在清洗界面连续水洗
LoadTabtoFileOrFileLoadtoTab("写入文件");

【6】QTabelWidget写文件函数和都文件函数

	if(type == RinseLog)//存储清洗日志
    {
    	QFile file;
        file.setFileName(RinseLogStoragePath);
        if(!file.open(QIODevice::WriteOnly | QIODevice::Append)){//追加写入 每次一行
            qDebug()<<"RinseLogStorageFIle open fail";
            return;
        }
        //表格数据会将每天的数据显示在清洗日志,然后和今天的清洗内容一起写入吧表格,为防止重复,每次写入清空
        file.write(data.toUtf8());
        file.close();
    }
/*=======================清洗日志表格,只能一行一行获取===============*/
QString dataStorage::ReadStorageRinseLogData(StorageType type,uint32_t LineNum,QString page)
{

    //当一行数据行小于10,大小占74
    QString FilePath;
    QString filedata;
    static uint64_t filepos=0;//表格页码控制=============表格1页=17行
    filedata.clear();
    if(type == RinseLog)
    {
        FilePath =RinseLogStoragePath;
    }
    QFile file(FilePath);
    if(!file.open(QIODevice::ReadOnly)){
        qDebug()<<file.errorString()<<endl;
        return "";
    }
    qDebug() << "文件大小:"<< file.size()<<endl;
    filesize=file.size();//获取文件大小------------------随时变化
    QTextStream out(&file);//使用文本流来控制
    if(page =="下一页" && LineNum == 17)
    {
        file.seek(filepos);//=============================设置每次读取后光标移动
        for(uint32_t i=1;i<=LineNum;i++)
        {
            QByteArray filearray = file.readLine();//1@4@水洗@开始时间@结束时间@总时间@\n
            filedata.append(filearray);
        }
        filepos = out.pos();//============================记录最后的文本光标
        filepossize=filepos;
        qDebug()<<"下一页file->pos="<<filepos<<endl;
    }
    qDebug()<<"filedata1="<<filedata<<endl;
    file.close();
    return filedata;
}



【7】QTabelWidget表格上下页

connect(ui->PB_updatetabl, SIGNAL(clicked()), this, SLOT(PB_SystemAndRinseLog()));

/*表格:系统日志和清洗日志处理槽函数的处理*/
void MainWindow::PB_SystemAndRinseLog()
{
    QPushButton *button = qobject_cast<QPushButton *>(sender());
	if(button == ui->PB_updatetabl)//代码自动点击实现clik
    {
            //离线模式清洗自动停止开启的解决
            ui->tableWidget_rinselog->showRow(currow);//显示行
            //结束时间
            ui->tableWidget_rinselog->setItem(currow,2,new QTableWidgetItem(tr("%1 %2:%3").arg(ui->label_date->text()).arg(rinsehh).arg(rinsemm)));
            //设置对齐
            ui->tableWidget_rinselog->item(currow,2)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
            //总时间=ui->label_rinseleft的开始时间
            ui->tableWidget_rinselog->setItem(currow,3,new QTableWidgetItem(tr("%1小时%2分钟").arg(rinsetotaltime/60).arg(rinsetotaltime%60)));
            //设置对齐
            ui->tableWidget_rinselog->item(currow,3)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);

            datastorage.DataStorageManage(QString("ui->PB_updatetabl %1 水洗:总时间=%2 固定时间=%3").arg(QDateTime::currentDateTime().toString("hh:mm:ss")).arg(ui->label_rinseleft->text().toUInt()).arg(ui->stage1_time_1->text()),PrintfLog);//实际内容:行 列 数据  \n
            ui->PB_updatetabl->hide();
            LoadTabtoFileOrFileLoadtoTab("写入文件");
    }
    else if(button == ui->PB_uppage)//上一页
    {
        ui->progressBar__tab->hide();
       pageflag=1;
       ui->tableWidget_rinselog->verticalScrollBar()->setValue(ui->tableWidget_rinselog->verticalScrollBar()->value()-520);
       //qDebug()<<"上一页滑动条的值="<< ui->tableWidget_rinselog->verticalScrollBar()->value()<<endl;
    }
    else if(button == ui->PB_downpage)//下一页
    {
        static bool endflag=false;
        if(pageflag ==1 && ui->tableWidget_rinselog->rowCount() >17)
        {
             ui->progressBar__tab->hide();
            ui->tableWidget_rinselog->verticalScrollBar()->setValue(ui->tableWidget_rinselog->verticalScrollBar()->value()+520);
        }
        if(endflag == false)//============作用:只在读取文件时进入
        {
            ui->progressBar__tab->show();
            QString readRowClumAlldata =  LoadTabtoFileOrFileLoadtoTab("写入表格");
            if(readRowClumAlldata=="")
            {
                    qDebug()<<"readRowClumAlldata"<<readRowClumAlldata<<endl;
                    ui->tableWidget_rinselog->scrollToBottom();//滑动条最底部
            }
            uint64_t filesize =  datastorage.filesize;
            uint64_t filepos =  datastorage.filepossize;
            if(filesize ==filepos )
            {
                endflag =true;
            }
             int value = 100-(filepos%filesize)%100;
             //qDebug()<<"filesize"<<filesize<<"filepos"<<filepos<<"value"<<value<<endl;
             data_lib->SendttyAT0(tr("【=====filesize======】%1【=====filepos=====】%2【====value====】").arg(filesize).arg(filepos).arg(value));
             ui->progressBar__tab->setValue(value);
             if(value == 100)
             {
                     ui->progressBar__tab->setStyleSheet("color:red");
                     ui->progressBar__tab->update();
             }
         }
    }
}

【8】QTabelWidget表格滑动事件Event

bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{

 /******************************表格拖动事件*************************************/
       static int press_y   = 0;
       static int move_y    = -1;
       static int release_y = 0;
       static QDateTime pressDateTime;
       static QPropertyAnimation *animation = new QPropertyAnimation;

       if("qt_scrollarea_viewport" != watched->objectName())
       {
           return false;
       }
       int scrollV_max = m_scrollBarV->maximum ();
       int scrollV_min = m_scrollBarV->minimum ();

       //根据鼠标的动作——按下、放开、拖动,执行相应的操作
       if(event->type() == QEvent::MouseButtonPress)
       {
           //记录按下的时间、坐标

           pressDateTime = QDateTime::currentDateTime();
           move_y  = QCursor::pos().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 = QCursor::pos().y();
            qDebug()<<"MouseButtonRelease QCursor::pos().y()="<<QCursor::pos().y();
           QObject *parent_obj = watched->parent();
           if(parent_obj != 0 || parent_obj->inherits("QAbstractItemView"))
           {
               QTimer::singleShot(150, (QAbstractItemView *)parent_obj
                                  , SLOT(clearSelection()));
           }

           int endValue = 0;
           int pageStep;
           if(release_y - press_y != 0 && qAbs(release_y - press_y) > 45)
           {
               qDebug()<<"obj->objectName()="<<watched->objectName();
               int mseconds = pressDateTime.msecsTo(QDateTime::currentDateTime());
                qDebug()<<"mseconds="<<mseconds;

               int limit = 440;
               pageStep = 240;//scrollBarV->pageStep();
                qDebug()<<"pageStep="<<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 = QCursor::pos().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);
           qDebug()<<"endValue="<<endValue;
           qDebug()<<"move_distance="<<move_distance;
           move_y = QCursor::pos().y();
       }
           return QMainWindow::eventFilter(watched,event);

}
/******************************表格拖动事件*************************************/

over 祝你好运

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到