Qt5 在表格中加入控件

来源:互联网 发布:张志君 java 编辑:程序博客网 时间:2024/06/05 18:32

任务:使用QTableWidget动态生成表格,在每行的某两列中加入QComboBox下拉框控件和QPushButton按钮控件

有添加,删除,编辑功能,每行的按钮可以浏览文件夹并选择文件

 1、新建一个对话框QDialog,设计界面中选择Item-Widgets里的Table Widget,添加该控件,命名为tableWidget_userlist

2、在Dialog的构造函数中初始化表格的一些参数 

   //初始化表格        ui->tableWidget_userlist->setWindowTitle("user list");  //表名    ui->tableWidget_userlist->setEditTriggers(QAbstractItemView::NoEditTriggers);   //表格禁止编辑    ui->tableWidget_userlist->setSelectionBehavior(QAbstractItemView::SelectRows);  //整行选中的方式   //设置行列数    ui->tableWidget_userlist->setColumnCount(7);    ui->tableWidget_userlist->setRowCount(0);   //设置每列宽    ui->tableWidget_userlist->setColumnWidth(0,80);    ui->tableWidget_userlist->setColumnWidth(1,80);    ui->tableWidget_userlist->setColumnWidth(2,50);    ui->tableWidget_userlist->setColumnWidth(3,80);    ui->tableWidget_userlist->setColumnWidth(4,50);    ui->tableWidget_userlist->setColumnWidth(5,100);    ui->tableWidget_userlist->setColumnWidth(6,80);    //设置表头    QStringList header;    header.append(QObject::tr("name"));    header.append(QObject::tr("sex"));    header.append(QObject::tr("age"));    header.append(QObject::tr("hometown"));    header.append(QObject::tr("group"));    header.append(QObject::tr("text list file"));    header.append("");    ui->tableWidget_userlist->setHorizontalHeaderLabels(header);


3、目前表格只有表头,还没有数据,添加新数据方法如下: 

添加新一行

    int row = ui->tableWidget_userlist->rowCount(); //获取表格行数    ui->tableWidget_userlist->setRowCount(row+1);  //表格加一行


表格第2列为一个下拉框,如下方法添加

    QComboBox *comBox = new QComboBox();    comBox->addItem(QObject::tr("female"));    comBox->addItem(QObject::tr("male"));    comBox->setEnabled(true);    ui->tableWidget_userlist->setCellWidget(row,1,comBox);


表格第7列为一个按钮,如下方法添加

    QPushButton *button = new QPushButton();    button->setText(tr("scan"));    button->setEnabled(true);    ui->tableWidget_userlist->setCellWidget(row,6,button);


由于要在按钮点击后进行处理,连接按钮点击的信号和处理的槽

    connect(button,SIGNAL(clicked()),this,SLOT(changTextListPath()));

 

处理函数changTextListPath()实现的是浏览文件,重置第6列内容为选择的文件

注意:每次点击按钮开始要用setFocus将焦点设置在表格上,否则currentRow传回的行号不一定是按钮所在的行,因为焦点不在表格上,而按钮又是悬浮在表格上的,没有和表格直接关联,所以点击不同行的按钮不会使currentRow变化。

实现如下

void user_setting::changTextListPath()   //更改用户列表文件{    ui->tableWidget_userlist->setFocus();    int row = -1;    //获取当前行    row = ui->tableWidget_userlist->currentRow();    if(row >= 0)    {        QString filters = QObject::tr("text files (*.txt)");    //过滤txt文件        //浏览文件,返回选择的文件路径        QString file = QFileDialog::getOpenFileName(this,QObject::tr("Select Files"),resource_Path,filters);        //获取文件名和路径        QString filepath = file.left(file.size() - file.split("/").back().size() - 1);        QString filename = file.split("/").back();        if(file.size() > 0)        { //将第6列设置为文件名            ui->tableWidget_userlist->setItem(row,5,new QTableWidgetItem(filename));        }    }}


  

4、删除数据

删除数据实现了多行同时选中删除,所以比较麻烦
1)首先用QTableWidget的selectedItems()方法获取所有选中的单元格
2)用std::set<int> del_row记录选中的单元格的行号,用set防止重复
3)为了保证删除行时不混乱,必须从行号由大到小依次删除行(否则后面的行号出现变动,之后删除的行就错误了),但是囧的是发现QT里set不让逆序排序。。(无法识别set<int,greater<int> >),所以只好将set中的数据赋值为vector,再逆序遍历了

实现如下

void user_setting::on_pushButton_deleteuser_clicked()   //删除用户{    QList<QTableWidgetItem*> list = ui->tableWidget_userlist->selectedItems();   //读取所有被选中的item    if(list.size() == 0)    //没有被选中的就返回    {        QMessageBox::warning(this,QObject::tr("warning"),QObject::tr("please select a user"));        return;    }    std::set<int> del_row;   //记录要删除的行号,用set防止重复    for(int i=0; i<list.size(); i++)    //删除选中的项    {        QTableWidgetItem* sel = list[i]; //指向选中的item的指针        if (sel)        {            int row = ui->tableWidget_userlist->row(sel);   //获取行号            del_row.insert(row);        }    }    std::vector<int> del_list;  //赋值给del_list,set本身为有序    for(std::set<int>::iterator it=del_row.begin(); it!=del_row.end(); it++)    {        del_list.push_back(*it);    }    for(int i=del_list.size()-1; i>=0; i--)    //逆序遍历    {        ui->tableWidget_userlist->removeRow(del_list[i]);   //从显示列表中删除行    }} 

5、编辑数据

编辑数据功能实际上做成一个开关,一开始表格默认不可编辑,点击编辑,表格变成可编辑模式,用一个bool变量记录表格是在编辑模式还是锁定模式。

注意:对于表格中的控件要单独处理;开始编辑时要设置焦点,保证每行的按钮能获得正确的行号(见3粗体)

void user_setting::on_pushButton_edituser_clicked()     //编辑用户{    if(isedit == false)    {        ui->tableWidget_userlist->setEditTriggers(QAbstractItemView::CurrentChanged);   //允许编辑        for(int i=0; i<ui->tableWidget_userlist->rowCount(); i++)        {            //允许操作下拉框            QComboBox *now = (QComboBox *)ui->tableWidget_userlist->cellWidget(i,1);            now->setEnabled(true);            //允许操作按钮            QPushButton *button = (QPushButton *)ui->tableWidget_userlist->cellWidget(i,6);            button->setEnabled(true);        }ui->tableWidget_userlist->setFocus();        ui->tableWidget_userlist->setSelectionBehavior(QAbstractItemView::SelectItems);  //单元格选中的方式        ui->pushButton_edituser->setText("lock");   //设置按钮文本为“锁定”        isedit = true;    }    else    {        ui->tableWidget_userlist->setEditTriggers(QAbstractItemView::NoEditTriggers);   //不允许编辑        for(int i=0; i<ui->tableWidget_userlist->rowCount(); i++)   //不允许编辑性别下拉框        {            //不允许操作下拉框            QComboBox *now = (QComboBox *)ui->tableWidget_userlist->cellWidget(i,1);            now->setEnabled(false);            //不允许操作按钮            QPushButton *button = (QPushButton *)ui->tableWidget_userlist->cellWidget(i,6);            button->setEnabled(false);        }        ui->tableWidget_userlist->setSelectionBehavior(QAbstractItemView::SelectRows);  //整行选中的方式        ui->pushButton_edituser->setText("edit");   //设置按钮文本为“编辑”        isedit = false;    }}


 



至此,任务中所述的功能基本实现,实际上,我将这个Dialog应用于显示与更改用户信息文件,需要重载Dialog的构造函数,读取文件传入参数,并添加提交数据按钮,将表格中更新的数据写入文件等,不过与这次的主题关系不大,就不详述了~   

	
				
		
原创粉丝点击