QTableWidget详解
Qt
转载自http://blog.sina.com.cn/s/blog_a6fb6cc90101dd5u.html
在Qt的开发过程中,时常会用到表单(QTableWidget)这个控件,网上的资料不少,但是都是最基本的,有一些比较经常遇到的问题也说得不太清楚。所以,今天就在这里总结一下!
以下为个人模拟Windows资源管理器的一个表单。
一、设置表单样式1234table_widget->setColumnCount(4); //设置列数table_widget->horizontalHeader()->setDefaultSectionSize(150); table_widget->horizontalHeader()->setClickable(false); //设置表头不可点击(默认点击后进行排序)
1234//设置表头内容QStringList header;header<
1234//设置表头字体加粗QFont font = this->horizontalHeader()->font();font.setBold(true);table_widget->horizontalHeader()->setFont(font);
12345678910111213table_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); //设置表头第一列的宽度为150table_widget->horizontalHeader()->setFixedHeight(25); //设置表头的高度table_widget->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色table_widget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}"); //设置表头背景色
123456789101112//设置水平、垂直滚动条样式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)实现如下一个类
1234567891011#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,虚线边框去除。
问题二:当表格只有一行的时候,则表头会出现塌陷问题
摸索了很长时间,才得以解决:
12//点击表时不对表头行光亮(获取焦点) table_widget->horizontalHeader()->setHighlightSections(false);
二、多选并获取所选行123456789101112131415161718this->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)动态插入行
12345678910111213141516171819202122232425int 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)实现槽函数
1234void TableWidget::onHeaderClicked(int column){ //column为所点击的表头的某列}
五、打开某行进行编辑 既然模拟Window那么就模仿的像一点,Windows可以修改名称,那么Qt也必然可以实现
12345678//获得当前节点并获取编辑名称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);
六、右键菜单 (1)创建菜单、菜单项
1234567891011121314151617181920212223242526272829303132333435void 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
123456789101112131415161718192021222324252627void 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,大功告成!
七、信号1234567891011121314151617void 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.
以上都是在接触Qt以来总结的一些小经验,希望对大家有用!不积跬步无以至千里,不积小流无以成江河。。。
注:
技术在于交流、沟通,转载请注明出处并保持作品的完整性。
作者:[╰☆奋斗ing❤孩子`](http://blog.sina.com.cn/liang19890820) 原文:http://blog.sina.com.cn/s/blog_a6fb6cc90101dd5u.html。
之后的东西是我自己的一些小补充。
一、动态插入新行后的滚动条问题问题:动态插入一行数据后,我希望表格可以显示到我新插入的这一行来,所以写了代码如下:
123456789101112131415161718192021222324void MainWindow::addInfoTableWidget(dbdate db){ //增加新行 int RowCont; RowCont=ui->infoTableWidget->rowCount(); ui->infoTableWidget->insertRow(RowCont); //插入元素 ui->infoTableWidget->setItem(RowCont,0,new QTableWidgetItem(QString::number(db.number))); ui->infoTableWidget->setItem(RowCont,1,new QTableWidgetItem(QString::number(db.weight))); ui->infoTableWidget->setItem(RowCont,2,new QTableWidgetItem(QString::number(db.length))); ui->infoTableWidget->setItem(RowCont,3,new QTableWidgetItem(QString::number(db.width))); ui->infoTableWidget->setItem(RowCont,4,new QTableWidgetItem(QString::number(db.height))); ui->infoTableWidget->setItem(RowCont,5,new QTableWidgetItem(QString::number(db.volume))); ui->infoTableWidget->setItem(RowCont,6,new QTableWidgetItem(db.barCodeInfo)); ui->infoTableWidget->setItem(RowCont,7,new QTableWidgetItem(db.time)); //根据内容调整表格 ui->infoTableWidget->resizeColumnsToContents(); //设置滚动条滚动到最大值 int t = ui->infoTableWidget->verticalScrollBar()->maximum(); ui->infoTableWidget->verticalScrollBar()->setValue(t);}
结果如下图:
总是有一段剩余。
原因:之前的代码实际上并没有运行完成,所以在获得t的时候仍然是获得的没有新行时的值。
方案:增加一个小的延时函数。
1234567891011121314151617181920212223242526272829void MainWindow::addInfoTableWidget(dbdate db){ //增加新行 int RowCont; RowCont=ui->infoTableWidget->rowCount(); ui->infoTableWidget->insertRow(RowCont); //插入元素 ui->infoTableWidget->setItem(RowCont,0,new QTableWidgetItem(QString::number(db.number))); ui->infoTableWidget->setItem(RowCont,1,new QTableWidgetItem(QString::number(db.weight))); ui->infoTableWidget->setItem(RowCont,2,new QTableWidgetItem(QString::number(db.length))); ui->infoTableWidget->setItem(RowCont,3,new QTableWidgetItem(QString::number(db.width))); ui->infoTableWidget->setItem(RowCont,4,new QTableWidgetItem(QString::number(db.height))); ui->infoTableWidget->setItem(RowCont,5,new QTableWidgetItem(QString::number(db.volume))); ui->infoTableWidget->setItem(RowCont,6,new QTableWidgetItem(db.barCodeInfo)); ui->infoTableWidget->setItem(RowCont,7,new QTableWidgetItem(db.time)); //根据内容调整表格 ui->infoTableWidget->resizeColumnsToContents(); //增加5ms延时 QTime _Timer = QTime::currentTime().addMSecs(5); while( QTime::currentTime() < _Timer ) QCoreApplication::processEvents(QEventLoop::AllEvents, 100); //设置滚动条滚动到最大值 int t = ui->infoTableWidget->verticalScrollBar()->maximum(); ui->infoTableWidget->verticalScrollBar()->setValue(t);}
原文地址: