目录
1. 表格初始化:table_init()
1.1. 为表格添加数据
Qt我习惯采用手动拖动增加控件,这里大部分采用的都是ui界面拖动的控件。
1.1.1. 设置行数和列数
//设置行数
ui->tableWidget->setRowCount(int row);
//设置列数
ui->tableWidget->setColumnCount(int colum);
1.1.2. 设置表头
这里是将所有的表头添加到列表里
QStringList *lab = new QStringList;
lab->push_back(QString("时间"));
lab->push_back(QString("频率"));
lab->push_back(QString("速度"));
ui->tableWidget->setHorizontalHeaderLabels(*lab);
1.1.3. 添加表格数据
本文的数据是提前准备好的,为筛选和排序做好数据准备工作。
这里是添加字符串数据:
//row为行号,colum为列号,从0开始
ui->tableWidget->setItem(int row , int colum , new TableWidgetItem("a new string"));
添加整形数据
QTableWidgetItem *item = new QTableWidgetItem;
item->setData(Qt::EditRole , int number);
ui->setItem(int row , int colum , item);
注意:采用非代码,手动在表格中输入数据时,数据默认为字符串数据。
在排序时,直接采用ui->tableWidget->sortByColumn()时,字符串和整形数据的排序是有区别的。数据的格式会影响排序的结果。
数字:2,5,11,27,8
升序:2,5,8,11,27
若为字符串升序:11,2,27,5,8
还有一种添加数据的方式,则是将TableWidgetItem用QCallotor类来管理:
#include <QtWidgets>
class ATableWidgetItem : public QTableWidgetItem
{
public:
virtual bool operator <(const QTableWidgetItem &other)const
{
QCollator collator;
collator.setNumericMode(true);
auto ret=collator.compare(this->text(),other.text());
if(ret<0)
return true;
else
return false;
}
};
设置setNumericMode为true时,采用数字排序。在实例化item时则用ATableWidgetItem来实例化,此时排序这对字符串数据,也能根据数字实现合理的排序。
QString table_col_2[5]={"1024","2048","9600","115200","4096"};
int row=0;
int column=0;
for(int i=0;i<rowC;++i)
{
QTableWidgetItem *item2=new ATableWidgetItem;
item2->setData(Qt::DisplayRole,table_col_2[i]);
ui->tableWidget->setItem(row,column,item2);
}
1.2.1. 其他的一些配置
//设置为只读
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
//单机选中整行
ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
//表格列宽度自适应
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
1.3.1. 针对表头的设置:右键表头弹出菜单Menu
注意:得到右键表头的列数参数index
//设置鼠标右键弹出菜单
ui->tableWidget->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->tableWidget->horizontalHeader(),&QWidget::customContextMenuRequested,[=](QPoint pos){
//拿到右键表头那一列的列数
int index=ui->tableWidget->columnAt(pos.rx());
qDebug()<<"选中的列:"<<index<<endl;
QMenu *menu=new QMenu;
QAction *pnew=new QAction("筛选");
menu->addAction(pnew);
QMenu *menu1=menu->addMenu("排序");
QAction *pnew_up=new QAction("升序");
QAction *pnew_down=new QAction("降序");
menu1->addAction(pnew_up);
menu1->addAction(pnew_down);
menu->move(cursor().pos());
menu->show();
)};
样式为这样:右键“时间”表头得到菜单
2. 表格排序
2.1. 升序
排序需要注意的点在于数据格式,一般包括:int、QString、float、还有一般日期的格式。这里我用QCollator类管理添加的数据后,经过测试后:int , QString ,一般的日期格式:2022/11/26类似这样,都能实现有效的排序。后续的排序就比较容易解决了。
注意:这里采用的是根据某一列的数据来进行排序的
//pnew_up为上面菜单"升序"添加的QAction
//index为上面右键表头得到的表头那一列的列号column
connect(pnew_up,&QAction::triggered,[=](){
ui->tableWidget->sortByColumn(index,Qt::SortOrder::AscendingOrder);
});
2.2. 降序
connect(pnew_down,&QAction::triggered,[=](){
ui->tableWidget->sortByColumn(index,Qt::SortOrder::DescendingOrder);
});
3. 表格筛选
3.1. 存储指定某列的数据
首先要做的事情就是将右键的那一列的数据存储在QStringList列表中,注意是不重复的数据
int rowC=ui->tableWidget->rowCount;
QString Edit_content=new QStringList;
for(int i=0;i<rowC;++i)
{
int flag=1;
QString text=ui->tableWidget->item(i,index)->text();
for(auto it=Edit_content->begin();it!=Edit_content->end();++it)
{
if(text==*it)
{
flag=0;
break;
}
}
if(flag==1)
{
Edit_content->push_back(text);
}
}
3.2. 筛选弹窗的ui和代码部分
3.2.1. UI
用到的控件有GroupBox、ComboBox、LineEdit、PushButton、ListWidge
3.2.2. ListWidget初始化
目标:为listWidget添加checkBox控件,新增ListWidgetItem,item元素为3.1中存储在QStringList *Edit_content中的不重复的列数据
*注意:将checkBox勾选状态为checked的添加到QStringList isCheck_Box列表中去管理,状态为unChecked的从列表中移除
QListWidgetItem *all=new QListWidgetItem(ui->listWidget);
all_Box=new QCheckBox;
all_Box->setText("全部");
ui->listWidget->addItem(all);
ui->listWidget->setItemWidget(all,all_Box);
for(auto it=Edit_content->begin();it!=Edit_content->end();++it)
{
QListWidgetItem *child=new QListWidgetItem(ui->listWidget);
QCheckBox *child_Box=new QCheckBox;
child_Box->setText(it);
ui->listWidget->addItem(child);
ui->listWidget->setItemWidget(child,child_Box);
if(isCheck_Box->contains(it))
{
child_Box->setCheckState(Qt::CheckState::Checked);
}
connect(all_Box,&QCheckBox::stateChanged,[=](){
if(all_Box->isChecked())
{
child_Box->setCheckState(Qt::CheckState::Checked);
}
else
{
child_Box->setCheckState(Qt::CheckState::Unchecked);
}
});
connect(child_Box,&QCheckBox::stateChanged,[=](){
if(child_Box->isChecked())
{
isCheck_Box->push_back(child_Box->text());
for(auto it=isCheck_Box->begin();it!=isCheck_Box->end();++it)
{
qDebug()<<*it;
}
qDebug()<<endl;
}
else
{
auto it = std::find(isCheck_Box->begin(),isCheck_Box->end(),child_Box->text());
isCheck_Box->erase(it);
for(auto it=isCheck_Box->begin();it!=isCheck_Box->end();++it)
{
qDebug()<<*it;
}
qDebug()<<endl;
all_Box->blockSignals(true);
all_Box->setCheckState(Qt::CheckState::Unchecked);
all_Box->blockSignals(false);
}
});
}
3.2.3. comboBox初始化
目标:添加筛选条件
①:大小写敏感
②:全文匹配
③:正则表达式搜索
QListWidget *comBox_listWidget=new QListWidget;
ui->comboBox->setModel(comBox_listWidget->model());
ui->comboBox->setView(comBox_listWidget);
checkBox1=new QCheckBox(comBox_listWidget);
checkBox1->setText("大小写敏感");
QListWidgetItem *item1=new QListWidgetItem();
comBox_listWidget->addItem(item1);
comBox_listWidget->setItemWidget(item1,checkBox1);
checkBox2=new QCheckBox(comBox_listWidget);
checkBox2->setText("全文匹配");
QListWidgetItem *item2=new QListWidgetItem();
comBox_listWidget->addItem(item2);
comBox_listWidget->setItemWidget(item2,checkBox2);
checkBox3=new QCheckBox(comBox_listWidget);
checkBox3->setText("使用正则表达式");
QListWidgetItem *item3=new QListWidgetItem();
comBox_listWidget->addItem(item3);
comBox_listWidget->setItemWidget(item3,checkBox3);
int length=checkBox3->text().length();
int font_val=ui->comboBox->font().pointSize();
ui->comboBox->view()->setFixedWidth(length*font_val*2);
3.2.4. LineEdit初始化
目标:当LineEdit::textEdited信号产生时,也就是在对行编辑框做出编辑时,以comboBox中勾选的筛选条件为依据,来更新ListWidget中的内容
大小写敏感
int QString::indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
indexOf()为模糊匹配函数,CaseInsensitive为大小写不敏感,CaseSensitive为敏感。没找到匹配的返回-1。全文匹配QString s.length()==ui->LineEdit->text()->length()判断字符串正则搜索
QRegExp rx(text,Qt::CaseInsensitive) ; rx.indexIn(QString s); rx.exactMatch(QString s);
indexIn()函数,判断s和text是否模糊匹配,不匹配返回-1;
exactMatch()函数,返回bool,判断是否全文匹配。
3.2.5. 实现筛选
目标:在点击确认按钮后,根据QStringList *isCheck_Box勾选列表中的内容,显示勾选过的表格内容,隐藏未勾选的内容。
connect(ui->pushButton_ok,&QPushButton::clicked,[=](){
ui->lineEdit->clear();
for(int i=0;i<rowC;++i)
{
ui->tableWidget->setRowHidden(i,true);
}
for(auto it=isCheck_Box->begin();it!=isCheck_Box->end();++it)
{
QList<QTableWidgetItem *> item;
for(int i=0;i<rowC;++i)
{
if(*it==ui->tableWidget->item(i,index)->text())
{
item.append(ui->tableWidget->item(i,index));
}
}
if(!item.isEmpty())
{
for(int i=0;i<item.count();++i)
{
ui->tableWidget->setRowHidden(item.at(i)->row(),false);
}
}
}
ui->groupBox_shaixuan->hide();
});
4. 代码
4.1.mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QCheckBox>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public:
void table_init();
void listWidget_init(const int &x,const int &y);
void lineEdit_init();
void comboBox_init();
void common_if(const QString &it);
void common_else();
void line_init_child();
private:
Ui::MainWindow *ui;
QStringList *Edit_content;
QStringList *isCheck_Box;
QCheckBox *checkBox1;
QCheckBox *checkBox2;
QCheckBox *checkBox3;
QCheckBox *all_Box;
};
#endif // MAINWINDOW_H
4.2. ATableWidgetItem.h
#ifndef ATABLEWIDGETITEM_H
#define ATABLEWIDGETITEM_H
#include <QtWidgets>
class ATableWidgetItem : public QTableWidgetItem
{
public:
virtual bool operator <(const QTableWidgetItem &other)const
{
QCollator collator;
collator.setNumericMode(true);
auto ret=collator.compare(this->text(),other.text());
if(ret<0)
return true;
else
return false;
}
};
#endif // ATABLEWIDGETITEM_H
4.3. mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "AtableWidgetItem.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
table_init();
lineEdit_init();
comboBox_init();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::table_init()
{
ui->groupBox_shaixuan->hide();
ui->tableWidget->setRowCount(5);
ui->tableWidget->setColumnCount(3);
QStringList *lab=new QStringList;
lab->push_back(QString("时间"));
lab->push_back(QString("频率"));
lab->push_back(QString("备注"));
ui->tableWidget->setHorizontalHeaderLabels(*lab);
int rowC=ui->tableWidget->rowCount();
QString table_col_1[5]={"2022/11/28","2022/11/08","2001/07/13","2003/10/16","2019/09/01"};
for(int i=0;i<rowC;++i)
{
QTableWidgetItem *item1=new ATableWidgetItem;
item1->setData(Qt::DisplayRole,table_col_1[i]);
ui->tableWidget->setItem(i,0,item1);
}
QString table_col_2[5]={"1024","2048","9600","115200","4096"};
for(int i=0;i<rowC;++i)
{
QTableWidgetItem *item2=new ATableWidgetItem;
item2->setData(Qt::DisplayRole,table_col_2[i]);
ui->tableWidget->setItem(i,1,item2);
}
QString table_col_3[5]={"abc","xZ","AD","Bb","ppd"};
for(int i=0;i<rowC;++i)
{
QTableWidgetItem *item3=new ATableWidgetItem;
item3->setData(Qt::DisplayRole,table_col_3[i]);
ui->tableWidget->setItem(i,2,item3);
}
//设置为只读
ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
//单机选中整行
ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
//表格列宽度自适应
ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
connect(ui->tableWidget,&QTableWidget::clicked,[=](){
ui->groupBox_shaixuan->hide();
});
connect(ui->tableWidget->horizontalHeader(),&QHeaderView::clicked,[=](){
ui->groupBox_shaixuan->hide();
});
//设置鼠标右键弹出菜单
ui->tableWidget->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->tableWidget->horizontalHeader(),&QWidget::customContextMenuRequested,[=](QPoint pos){
int index=ui->tableWidget->columnAt(pos.rx());
qDebug()<<"选中的列:"<<index<<endl;
ui->groupBox_shaixuan->hide();
Edit_content=new QStringList;
for(int i=0;i<rowC;++i)
{
int flag=1;
QString text=ui->tableWidget->item(i,index)->text();
for(auto it=Edit_content->begin();it!=Edit_content->end();++it)
{
if(text==*it)
{
flag=0;
break;
}
}
if(flag==1)
{
Edit_content->push_back(text);
}
}
QMenu *menu=new QMenu;
QAction *pnew=new QAction("筛选");
menu->addAction(pnew);
QMenu *menu1=menu->addMenu("排序");
QAction *pnew_up=new QAction("升序");
QAction *pnew_down=new QAction("降序");
menu1->addAction(pnew_up);
menu1->addAction(pnew_down);
menu->move(cursor().pos());
QPoint test_p1=this->mapFromGlobal(cursor().pos());
int x=test_p1.rx();
int y=test_p1.ry();
qDebug()<<x<<","<<y<<endl;
menu->show();
connect(pnew,&QAction::triggered,[=](){
isCheck_Box=new QStringList;
listWidget_init(x,y);
connect(ui->pushButton_ok,&QPushButton::clicked,[=](){
ui->lineEdit->clear();
for(int i=0;i<rowC;++i)
{
ui->tableWidget->setRowHidden(i,true);
}
for(auto it=isCheck_Box->begin();it!=isCheck_Box->end();++it)
{
QList<QTableWidgetItem *> item;
for(int i=0;i<rowC;++i)
{
if(*it==ui->tableWidget->item(i,index)->text())
{
item.append(ui->tableWidget->item(i,index));
}
}
if(!item.isEmpty())
{
for(int i=0;i<item.count();++i)
{
ui->tableWidget->setRowHidden(item.at(i)->row(),false);
}
}
}
ui->groupBox_shaixuan->hide();
});
connect(ui->pushButton_cancel,&QPushButton::clicked,[=](){
ui->groupBox_shaixuan->hide();
});
});
connect(pnew_up,&QAction::triggered,[=](){
ui->tableWidget->sortByColumn(index,Qt::SortOrder::AscendingOrder);
// menu->hide();
});
connect(pnew_down,&QAction::triggered,[=](){
ui->tableWidget->sortByColumn(index,Qt::SortOrder::DescendingOrder);
// menu->hide();
});
});
}
void MainWindow::listWidget_init(const int &x, const int &y)
{
ui->listWidget->clear();
ui->tableWidget->show();
ui->groupBox_shaixuan->move(x,y);
ui->groupBox_shaixuan->show();
common_else();
}
void MainWindow::lineEdit_init()
{
connect(ui->lineEdit,&QLineEdit::textEdited,[=](){
line_init_child();
});
}
void MainWindow::comboBox_init()
{
QListWidget *comBox_listWidget=new QListWidget;
ui->comboBox->setModel(comBox_listWidget->model());
ui->comboBox->setView(comBox_listWidget);
checkBox1=new QCheckBox(comBox_listWidget);
checkBox1->setText("大小写敏感");
QListWidgetItem *item1=new QListWidgetItem();
comBox_listWidget->addItem(item1);
comBox_listWidget->setItemWidget(item1,checkBox1);
checkBox2=new QCheckBox(comBox_listWidget);
checkBox2->setText("全文匹配");
QListWidgetItem *item2=new QListWidgetItem();
comBox_listWidget->addItem(item2);
comBox_listWidget->setItemWidget(item2,checkBox2);
checkBox3=new QCheckBox(comBox_listWidget);
checkBox3->setText("使用正则表达式");
QListWidgetItem *item3=new QListWidgetItem();
comBox_listWidget->addItem(item3);
comBox_listWidget->setItemWidget(item3,checkBox3);
int length=checkBox3->text().length();
int font_val=ui->comboBox->font().pointSize();
ui->comboBox->view()->setFixedWidth(length*font_val*2);
}
void MainWindow::common_if(const QString &it)
{
QListWidgetItem *child=new QListWidgetItem(ui->listWidget);
QCheckBox *child_Box=new QCheckBox;
child_Box->setText(it);
ui->listWidget->addItem(child);
ui->listWidget->setItemWidget(child,child_Box);
if(isCheck_Box->contains(it))
{
child_Box->setCheckState(Qt::CheckState::Checked);
}
connect(all_Box,&QCheckBox::stateChanged,[=](){
if(all_Box->isChecked())
{
child_Box->setCheckState(Qt::CheckState::Checked);
}
else
{
child_Box->setCheckState(Qt::CheckState::Unchecked);
}
});
connect(child_Box,&QCheckBox::stateChanged,[=](){
if(child_Box->isChecked())
{
isCheck_Box->push_back(child_Box->text());
for(auto it=isCheck_Box->begin();it!=isCheck_Box->end();++it)
{
qDebug()<<*it;
}
qDebug()<<endl;
}
else
{
auto it = std::find(isCheck_Box->begin(),isCheck_Box->end(),child_Box->text());
isCheck_Box->erase(it);
for(auto it=isCheck_Box->begin();it!=isCheck_Box->end();++it)
{
qDebug()<<*it;
}
qDebug()<<endl;
all_Box->blockSignals(true);
all_Box->setCheckState(Qt::CheckState::Unchecked);
all_Box->blockSignals(false);
}
});
}
void MainWindow::common_else()
{
QListWidgetItem *all=new QListWidgetItem(ui->listWidget);
all_Box=new QCheckBox;
all_Box->setText("全部");
ui->listWidget->addItem(all);
ui->listWidget->setItemWidget(all,all_Box);
for(auto it=Edit_content->begin();it!=Edit_content->end();++it)
{
common_if(*it);
}
}
void MainWindow::line_init_child()
{
ui->listWidget->clear();
QListWidgetItem *all=new QListWidgetItem;
all_Box=new QCheckBox;
all_Box->setText("全部");
ui->listWidget->addItem(all);
ui->listWidget->setItemWidget(all,all_Box);
int flag=1;
for(auto it=Edit_content->begin();it!=Edit_content->end();++it)
{
QString temp_text=*it;
//大小写敏感
if(checkBox1->isChecked() && !checkBox2->isChecked() && !checkBox3->isChecked())
{
if(temp_text.indexOf(ui->lineEdit->text(),0,Qt::CaseSensitive)!=-1)
{
flag=0;
common_if(*it);
}
}
//全文匹配
else if(!checkBox1->isChecked() && checkBox2->isChecked() && !checkBox3->isChecked())
{
if(temp_text.contains(ui->lineEdit->text(),Qt::CaseInsensitive)&&temp_text.length()==ui->lineEdit->text().length())
{
flag=0;
common_if(*it);
}
else if(ui->lineEdit->text()=="")
{
common_else();
break;
}
}
//正则
else if(!checkBox1->isChecked() && !checkBox2->isChecked() && checkBox3->isChecked())
{
QString text=ui->lineEdit->text();
QRegExp rx(text,Qt::CaseInsensitive);
if(rx.indexIn(*it)!=-1)
{
flag=0;
common_if(*it);
}
}
//大小写敏感+正则
else if(checkBox1->isChecked() && !checkBox2->isChecked() && checkBox3->isChecked())
{
QString text=ui->lineEdit->text();
QRegExp rx(text,Qt::CaseSensitive);
if(rx.indexIn(*it)!=-1)
{
flag=0;
common_if(*it);
}
}
//全文匹配+正则
else if(!checkBox1->isChecked() && checkBox2->isChecked() && checkBox3->isChecked())
{
QString text=ui->lineEdit->text();
QRegExp rx(text,Qt::CaseInsensitive);
if(rx.exactMatch(*it))
{
flag=0;
common_if(*it);
}
else if(ui->lineEdit->text()=="")
{
common_else();
break;
}
}
//大小写敏感+全文匹配+正则
else if(checkBox1->isChecked() && checkBox2->isChecked() && checkBox3->isChecked())
{
QString text=ui->lineEdit->text();
QRegExp rx(text,Qt::CaseSensitive);
if(rx.exactMatch(*it))
{
flag=0;
common_if(*it);
}
else if(ui->lineEdit->text()=="")
{
common_else();
break;
}
}
//大小写敏感+全文匹配
else if(checkBox1->isChecked() && checkBox2->isChecked() && checkBox3->isChecked())
{
if(temp_text.contains(ui->lineEdit->text(),Qt::CaseSensitive)&&temp_text.length()==ui->lineEdit->text().length())
{
flag=0;
common_if(*it);
}
else if(ui->lineEdit->text()=="")
{
common_else();
break;
}
}
else if(!checkBox1->isChecked() && !checkBox2->isChecked() && !checkBox3->isChecked())
{
if(temp_text.indexOf(ui->lineEdit->text(),0,Qt::CaseInsensitive)!=-1)
{
flag=0;
common_if(*it);
}
}
}
if(flag==1)
{
all->setHidden(true);
}
}
4.4. main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
4.5. UI设计
4.6. 效果视频
QTableWidget表格筛选排序
版权归原作者 m0_60752380 所有, 如有侵权,请联系我们删除。