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