1. 程式人生 > >Qt在表格中加入控制元件

Qt在表格中加入控制元件

任務:使用 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列內容為選擇的檔案,實現如下

void user_setting::changTextListPath()   //更改使用者列表檔案
{
    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變數記錄表格是在編輯模式還是鎖定模式。需要注意的是對於表格中的控制元件要單獨處理 

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->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的建構函式,讀取檔案傳入引數,並新增提交資料按鈕,將表格中更新的資料寫入檔案等,不過與這次的主題關係不大,就不詳述了~