在公司公示Qt開發一段時間,表格用到不少,所以,今天在這做個總結,防止以后忘記。
下面為個人模擬Windows資源管理器的一個表單。(寫的比較粗糙,諒解一下)
一、設置表單樣式
table_widget->setColumnCount(4); //設置列數
table_widget->horizontalHeader()->setDefaultSectionSize(150);
table_widget->horizontalHeader()->setClickable(false); //設置表頭不可點擊(默認點擊后進行排序)
//設置表頭內容
QStringList header;
header<<tr("name")<<tr("last modify time")<<tr("type")<<tr("size");
table_widget->setHorizontalHeaderLabels(header);
//設置表頭字體加粗
QFont font = this->horizontalHeader()->font();
font.setBold(true);
table_widget->horizontalHeader()->setFont(font);
table_widget->horizontalHeader()->setStretchLastSection(true); //設置充滿表寬度
table_widget->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
table_widget->verticalHeader()->setDefaultSectionSize(10); //設置行高
table_widget->setFrameShape(QFrame::NoFrame); //設置無邊框
table_widget->setShowGrid(false); //設置不顯示格子線
table_widget->verticalHeader()->setVisible(false); //設置垂直頭不可見
table_widget->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多選(Ctrl、Shift、 Ctrl+A都能夠)
table_widget->setSelectionBehavior(QAbstractItemView::SelectRows); //設置選擇行為時每次選擇一行
table_widget->setEditTriggers(QAbstractItemView::NoEditTriggers); //設置不可編輯
table_widget->horizontalHeader()->resizeSection(0,150); //設置表頭第一列的寬度為150
table_widget->horizontalHeader()->setFixedHeight(25); //設置表頭的高度
table_widget->setStyleSheet("selection-background-color:lightblue;"); //設置選中背景色
table_widget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}"); //設置表頭背景色
//設置水平、垂直滾動欄樣式
table_widget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
"QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
"QScrollBar::handle:hover{background:gray;}"
"QScrollBar::sub-line{background:transparent;}"
"QScrollBar::add-line{background:transparent;}");
table_widget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}"
"QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
"QScrollBar::handle:hover{background:gray;}"
"QScrollBar::sub-line{background:transparent;}"
"QScrollBar::add-line{background:transparent;}");
好了,樣式設置完畢,效果例如以下所看到的:
問題一:鼠標點擊的選項會出現虛框,在Qt官網找到一篇博客專門介紹的,直接上代碼!
(1)實現例如以下一個類
#include "no_focus_delegate.h"
void NoFocusDelegate::paint(QPainter* painter, const QStyleOptionViewItem & option, const QModelIndex &index) const
{
QStyleOptionViewItem itemOption(option);
if (itemOption.state & QStyle::State_HasFocus)
{
itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
}
QStyledItemDelegate::paint(painter, itemOption, index);
}
(2)表格構造中加入例如以下代碼
table_widget->setItemDelegate(new NoFocusDelegate());
OK,虛線邊框去除
問題二:當表格僅僅有一行的時候。則表頭會出現塌陷問題
//點擊表時不正確表頭行光亮(獲取焦點)
table_widget->horizontalHeader()->setHighlightSections(false);
二、多選並獲取所選行
this->setSelectionMode(QAbstractItemView::ExtendedSelection); //設置多選(能夠Ctral+A全選Ctral+Shift多選)獲取所選行號:
bool TableWidget::getSelectedRow(QSet&set_row)
{
QList items = this->selectedItems();
int item_count = items.count();
if(item_count <= 0)
{
return false;
}
for(int i=0; i
{
//獲取選中的行
int item_row = this->row(items.at(i));
set_row.insert(item_row);
}
return true;
}
三、操作表單(加入、刪除行等)
(1)動態插入行
int row_count = table_widget->rowCount(); //獲取表單行數
table_widget->insertRow(row_count); //插入新行
QTableWidgetItem *item = new QTableWidgetItem();
QTableWidgetItem *item1 = new QTableWidgetItem();
QTableWidgetItem *item2 = new QTableWidgetItem();
QTableWidgetItem *item3 = new QTableWidgetItem();
//設置相應的圖標、文件名、最后更新時間、相應的類型、文件大小
item->setIcon(icon); //icon為調用系統的圖標。以后綴來區分
item->setText(name);
item1->setText(last_modify_time);
item2->setText(type); //type為調用系統的類型。以后綴來區分
item3->setText(size);
table_widget->setItem(row_count, 0, item);
table_widget->setItem(row_count, 1, item1);
table_widget->setItem(row_count, 2, item2);
table_widget->setItem(row_count, 3, item3);
//設置樣式為灰色
QColor color("gray");
item1->setTextColor(color);
item2->setTextColor(color);
item3->setTextColor(color);
(2)在指定位置插入行
事實上跟(1)類似,(1)的前提是獲取到表格行數
table_widget->insertRow(row); //插入新行 row為插入的位置
四、單擊表頭觸發的事件
(1)連接表頭的信號和槽
connect(horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(onHeaderClicked(int)));
(2)實現槽函數
void TableWidget::onHeaderClicked(int column)
{
//column為所點擊的表頭的某列
}
五、打開某行進行編輯
既然模擬Window那么就模仿的像一點,Windows能夠改動名稱。那么Qt也必定能夠實現
//獲得當前節點並獲取編輯名稱
QTableWidgetItem *item = table_widget->item(edit_row, 0); //edit_row為想要編輯的行號
table_widget->setCurrentCell(edit_row, 0);
table_widget->openPersistentEditor(item); //打開編輯項
table_widget->editItem(item);
//關閉編輯項
table_widget->closePersistentEditor(item);
OK。重命名完畢,!
六、右鍵菜單
(1)創建菜單、菜單項
void TableWidget::createActions()
{
//創建菜單項
pop_menu = new QMenu();
action_name = new QAction(this);
action_size = new QAction(this);
action_type = new QAction(this);
action_date = new QAction(this);
action_open = new QAction(this);
action_download = new QAction(this);
action_flush = new QAction(this);
action_delete = new QAction(this);
action_rename = new QAction(this);
action_create_folder = new QAction(this);
action_open->setText(QString("打開"));
action_download->setText(QString("下載"));
action_flush->setText(QString("刷新"));
action_delete->setText(QString("刪除"));
action_rename->setText(QString("重命名"));
action_create_folder->setText(QString("新建目錄"));
action_name->setText(QString("名稱"));
action_size->setText(QString("大小"));
action_type->setText(QString("項目類型"));
action_date->setText(QString("改動日期"));
//設置快捷鍵
action_flush->setShortcut(QKeySequence::Refresh);
//設置目錄圖標
action_create_folder->setIcon(icon);
QObject::connect(action_create_folder, SIGNAL(triggered()), this, SLOT(createFolder()));
}
(2)又一次實現contextMenuEvent
void TableWidget::contextMenuEvent(QContextMenuEvent *event)
{
pop_menu->clear(); //清除原有菜單
QPoint point = event->pos(); //得到窗體坐標
QTableWidgetItem *item = this->itemAt(point);
if(item != NULL)
{
pop_menu->addAction(action_download);
pop_menu->addAction(action_flush);
pop_menu->addSeparator();
pop_menu->addAction(action_delete);
pop_menu->addAction(action_rename);
pop_menu->addSeparator();
pop_menu->addAction(action_create_folder);
sort_style = pop_menu->addMenu("排序");
sort_style->addAction(action_name);
sort_style->addAction(action_size);
sort_style->addAction(action_type);
sort_style->addAction(action_date);
//菜單出現的位置為當前鼠標的位置
pop_menu->exec(QCursor::pos());
event->accept();
}
}
OK,大功告成!
七、信號
void cellActivated(int row, int column)
void cellChanged(int row, int column)
void cellClicked(int row, int column)
void cellDoubleClicked(int row, int column)
void cellEntered(int row, int column)
void cellPressed(int row, int column)
void itemActivated(QTableWidgetItem *item)
void itemChanged(QTableWidgetItem *item)
void itemClicked(QTableWidgetItem *item)
void itemDoubleClicked(QTableWidgetItem *item)
void itemEntered(QTableWidgetItem *item)
void itemPressed(QTableWidgetItem *item)
void itemSelectionChanged()
void currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous)
void currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
關於界面的文件(夾)圖標和類型怎樣獲取?對於文件而言,不同擴展名的文件至少也有100種以上,假設圖標和類型固定寫死的話必不可行,所以。這里提供下面兩種方式獲取。
Qt之QFileIconProvider(獲取文件圖標、類型).
Qt之QFileIconProvider續(獲取文件圖標、類型).
很多其它關於QTableView的資料請參考:
Qt之模型/視圖(實時更新數據).
Qt之QTableView.
八、QTableWidget獲取選中的內容及所在行數
方法一:
// QTableWidget選中全部單元格及取消選中全部單元格
// ui->allowSelectKeyTableWidget->selectAll();
// ui->allowSelectKeyTableWidget->setFocus();
introwCount=ui->TableWidget->rowCount();
qDebug()<<"rowcount"<<rowCount;
intcolCount=ui->TableWidget->columnCount();
qDebug()<<"colcount"<<colCount;
QTableWidgetSelectionRangerange(0,0,rowCount-1,colCount-1);
ui->TableWidget->setRangeSelected(range,true);//false不選中
ui->TableWidget->setFocus();
QList<QTableWidgetItem*>items=ui->TableWidget->selectedItems();
intcount=items.count();
for(inti=0;i<count;i++)
{
introw=ui->TableWidget->row(items.at(i));//獲取選中的行
QTableWidgetItem*item=items.at(i);
QStringname=item->text();//獲取內容
}
方法二:獲取選中的行
QList<QTableWidgetSelectionRange>ranges=ui->TableWidget->selectedRanges();
intcount=ranges.count();
for(inti=0;i<count;i++)
{
inttopRow=ranges.at(i).topRow();
intbottomRow=ranges.at(i).bottomRow();
for(intj=topRow;j<=bottomRow;j++)
{
qDebug()<<"selectRow"<<j;
}
}
九、雙擊定位QtableWidget所在行號
connect(ui->SearchShow_TableWidget, SIGNAL(doubleClicked(QModelIndex)), this,SLOT(TableDoubleClicked_slots(QModelIndex)));//< 雙擊定位
void SearchsDlg::TableDoubleClicked_slots(QModelIndex index)
{
int row = index.row();//< 獲取到雙擊所在的行號
十、合並單元格
tableWidget->setSpan(0, 0, 3, 1) # 其參數為: 要改變單元格的 1行數 2列數 要合並的 3行數 4列數
