0


Qt TableWidget实现筛选和排序

目录


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();
    )};

样式为这样:右键“时间”表头得到菜单

6866a5cc34cc4044a1dc7c8e469f8e1d.png


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

c83ada47ec5f455989a7ebbc0967975a.png8a23ee6c901e475bb668732865a3d81f.png

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表格筛选排序

标签: qt

本文转载自: https://blog.csdn.net/m0_60752380/article/details/128017404
版权归原作者 m0_60752380 所有, 如有侵权,请联系我们删除。

“Qt TableWidget实现筛选和排序”的评论:

还没有评论