本文章复制于别人的博客,是因为我怕原创者把原著删掉,所以就复制下来了,如有冒犯,请多见谅!
一、简介
QTableWidget是QT对话框设计中常用的显示数据表格的控件,QTableWidget单元格数据是QTableWidgetItem对象来实现的,整个表格都需要用逐个单元格对象QTableWidgetItem构建起来。
二、详解
1、代码
(1)table.h
- #ifndef TABLE_H
- #define TABLE_H
- #include <QtGui>
- class Table : public QTableWidget
- {
- Q_OBJECT
- public:
- Table(QWidget *parent = 0);
- ~Table();
- void setColumnValue(const int &columnSum, const QStringList &header); //set header value
- void setHeaderWidth(const int &index, const int &width); //set header and column widhth for each index
- void setHeaderHeight(const int &height); //set header height
- void addRowValue(const int &height, const QStringList &value, const QIcon &fileIcon);
- void setRowH(const int &index, const int &height);
- void setItemFixed(bool flag);
- bool getSelectedRow(QList<int> &rowList);
- protected:
- void contextMenuEvent(QContextMenuEvent *event);
- QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
- void keyPressEvent(QKeyEvent *event);
- private:
- void createActions();
- private slots:
- void slotItemEntered(QTableWidgetItem *item);
- void slotActionRename();
- void slotItemSelectionChanged();
- private:
- int tableWidth;
- int tableHeight;
- QList<int>rowHeghtList;
- QList<int>rowWidthList;
- QMenu *popMenu;
- QAction *actionName;
- QAction *actionSize;
- QAction *actionType;
- QAction *actionDate;
- QAction *actionOpen;
- QAction *actionDownload;
- QAction *actionFlush;
- QAction *actionDelete;
- QAction *actionRename;
- QAction *actionCreateFolder;
- QTableWidgetItem *rightClickedItem;
- QMap<QTableWidgetItem *, QString>fileMap;
- bool dupFlag;
- };
- // custom item delegate class
- class NoFocusDelegate : public QStyledItemDelegate
- {
- protected:
- void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- };
- #endif // TABLE_H
- #include "table.h"
- Table::Table(QWidget *parent)
- : QTableWidget(parent)
- , rightClickedItem(NULL)
- , dupFlag(false)
- {
- rowHeghtList.clear();
- rowWidthList.clear();
- fileMap.clear();
- this->setMouseTracking(true);
- //setWindowTitle(tr("table"));
- horizontalHeader()->setDefaultSectionSize(100);
- verticalHeader()->setDefaultSectionSize(30); //设置默认行高
- tableWidth = 100;
- tableHeight = 30;
- horizontalHeader()->setClickable(false); //设置表头不可点击(默认点击后进行排序
- QFont font = horizontalHeader()->font(); //设置表头字体加粗
- font.setBold(true);
- horizontalHeader()->setFont(font);
- horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
- horizontalHeader()->setMovable(false); //表头左右互换
- //verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
- setFrameShape(QFrame::NoFrame); //设置无边框
- //setShowGrid(false); //设置不显示格子线
- verticalHeader()->setVisible(false); //设置垂直头不可见
- setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
- setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
- setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
- setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
- //horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}"); //设置表头背景色
- //setStyleSheet("background: rgb(56,56,56);alternate-background-color:rgb(48,51,55);selection-background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(56,56,56),stop:1 rgb(76,76,76));"); //设置选中背景色
- horizontalHeader()->setStyleSheet("QHeaderView::section{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgba(134, 245, 99, 255),stop:0.5 rgba(134, 148, 99, 255),stop:1 rgba(115, 87, 128, 255));color:rgb(25, 70, 100);padding-left: 1px;border: 1px solid #FFFF00;}"); //设置表头背景色
- setAlternatingRowColors(true);
- //setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- //setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- //设置水平、垂直滚动条样式
- horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:12px;}"
- "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;}");
- verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width:12px;}"
- "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;}");
- // set the item delegate to your table widget
- setItemDelegate(new NoFocusDelegate()); //虚线边框去除
- //setFocusPolicy(Qt::NoFocus); //去除选中虚线框
- horizontalHeader()->setHighlightSections(false); //点击表时不对表头行光亮(获取焦点)
- createActions();
- setItemFixed(false);
- connect(this, SIGNAL(itemEntered(QTableWidgetItem*)), this , SLOT(slotItemEntered(QTableWidgetItem*)));
- connect(this, SIGNAL(itemSelectionChanged()), this , SLOT(slotItemSelectionChanged()));
- //this->resize(600, 600);
- }
- Table::~Table()
- {
- }
- void Table::setColumnValue(const int &columnSum, const QStringList &header)
- {
- setColumnCount(columnSum); //设置列数
- this->setHorizontalHeaderLabels(header); //设置列的标签
- }
- void Table::setHeaderWidth(const int &index, const int &width)
- {
- horizontalHeader()->resizeSection(index,width);
- if (rowWidthList.count() <= index + 1) {
- rowWidthList.append(width);
- }
- else {
- rowWidthList[index+1] = width;
- }
- tableWidth = 0;
- for(int index = 0; index < rowWidthList.count(); index++)
- tableWidth += rowWidthList.at(index);
- resize(tableWidth, tableHeight);
- }
- void Table::setHeaderHeight(const int &height)
- {
- horizontalHeader()->setFixedHeight(height); //设置表头的高度
- if (rowHeghtList.isEmpty()) {
- rowHeghtList.append(height);
- }
- else {
- rowHeghtList[0] = height;
- }
- tableHeight = 0;
- for(int index = 0; index < rowHeghtList.count(); index++)
- tableHeight += rowHeghtList.at(index);
- resize(tableWidth, tableHeight);
- }
- void Table::addRowValue(const int &height, const QStringList &value, const QIcon &fileIcon)
- {
- int row_count = rowCount(); //获取表单行数
- insertRow(row_count); //插入新行
- setRowHeight(row_count, height);
- for (int index = 0; index < columnCount(); index++) {
- QTableWidgetItem *item = new QTableWidgetItem;
- if (index == 0) {
- item->setIcon(fileIcon);
- item->setTextAlignment(Qt::AlignVCenter | Qt::AlignLeft);
- fileMap.insert(item, value.at(index));
- }
- else {
- item->setTextAlignment(Qt::AlignCenter);
- }
- item->setText(value.at(index));
- setItem(row_count, index, item);
- }
- rowHeghtList.append(height);
- tableHeight += height;
- resize(tableWidth, tableHeight);
- }
- 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);
- }
- void Table::setRowH(const int &index, const int &height)
- {
- setRowHeight(index, height);
- if (rowHeghtList.count() <= index + 1) {
- rowHeghtList.append(height);
- }
- else {
- rowHeghtList[index+1] = height;
- }
- tableHeight = 0;
- for(int index = 0; index < rowHeghtList.count(); index++)
- tableHeight += rowHeghtList.at(index);
- resize(tableWidth, tableHeight);
- }
- void Table::createActions()
- {
- popMenu = new QMenu();
- actionName = new QAction(this);
- actionSize = new QAction(this);
- actionType = new QAction(this);
- actionDate = new QAction(this);
- actionOpen = new QAction(this);
- actionDownload = new QAction(this);
- actionFlush = new QAction(this);
- actionDelete = new QAction(this);
- actionRename = new QAction(this);
- actionCreateFolder = new QAction(this);
- actionOpen->setText(tr("打开"));
- actionDownload->setText(tr("下载"));
- actionFlush->setText(tr("刷新"));
- actionDelete->setText(tr("删除"));
- actionRename->setText(tr("重命名"));
- actionCreateFolder->setText(tr("新建文件夹"));
- actionName->setText(tr("名称"));
- actionSize->setText(tr("大小"));
- actionType->setText(tr("项目类型"));
- actionDate->setText(tr("修改日期"));
- actionFlush->setShortcut(QKeySequence::Refresh);
- connect(actionRename, SIGNAL(triggered()), this, SLOT(slotActionRename()));
- }
- void Table::contextMenuEvent(QContextMenuEvent *event)
- {
- popMenu->clear();
- QPoint point = event->pos();
- rightClickedItem = this->itemAt(point);
- if(rightClickedItem != NULL) {
- popMenu->addAction(actionDownload);
- popMenu->addAction(actionFlush);
- popMenu->addSeparator();
- popMenu->addAction(actionDelete);
- popMenu->addAction(actionRename);
- popMenu->addSeparator();
- popMenu->addAction(actionCreateFolder);
- QMenu *sortStyle = popMenu->addMenu(tr("排序"));
- sortStyle->addAction(actionName);
- sortStyle->addAction(actionSize);
- sortStyle->addAction(actionType);
- sortStyle->addAction(actionDate);
- popMenu->exec(QCursor::pos());
- event->accept();
- }
- }
- QModelIndex Table::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
- {
- //重写移动光标事件,当存在编辑项的时候,让光标永远位于当前项(编辑项),否则返回父类
- if(rightClickedItem && rightClickedItem->row() >= 0) {
- return currentIndex();
- }
- else {
- return QTableWidget::moveCursor(cursorAction, modifiers);
- }
- }
- void Table::keyPressEvent(QKeyEvent *event)
- {
- if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
- QTableWidgetItem *item = currentItem();
- if (item) {
- closePersistentEditor(item);
- openPersistentEditor(item);
- slotItemSelectionChanged();
- dupFlag = false;
- }
- }
- }
- void Table::slotItemSelectionChanged()
- {
- //关闭编辑项
- if (rightClickedItem && dupFlag == false) {
- int editRow = rightClickedItem->row();
- QTableWidgetItem *item = this->item(editRow, 0);
- QMap<QTableWidgetItem *, QString>::iterator it;
- for (it = fileMap.begin(); it != fileMap.end(); ++it) {
- if (it.key() != item) {
- if (it.value() == item->text()) {
- dupFlag = true;
- }
- }
- }
- if (dupFlag == false) {
- this->closePersistentEditor(item);
- rightClickedItem = NULL;
- }
- else {
- QMessageBox::critical(this,tr("错误提示"),tr("文件重名"), tr("确定"));
- setCurrentItem(item);
- }
- }
- else {
- dupFlag = false;
- }
- }
- void Table::setItemFixed(bool flag)
- {
- if (flag == true)
- horizontalHeader()->setResizeMode(QHeaderView::Fixed);
- else
- horizontalHeader()->setResizeMode(QHeaderView::Interactive);
- }
- bool Table::getSelectedRow(QList<int> &rowList)
- {
- //多选并获取所选行
- QList<QTableWidgetItem *> items = this->selectedItems();
- int itemCount = items.count();
- if(itemCount <= 0) {
- return false;
- }
- for (int index = 0; index < itemCount; index++) {
- int itemRow = this->row(items.at(index));
- rowList.append(itemRow);
- }
- return true;
- }
- void Table::slotItemEntered(QTableWidgetItem *item)
- {
- if(!item)
- return;
- QString name = item->text();
- if (name.isEmpty())
- return;
- QToolTip::showText(QCursor::pos(), name);
- }
- void Table::slotActionRename()
- {
- //获得当前节点并获取编辑名称
- if (rightClickedItem) {
- int editRow = rightClickedItem->row();
- QTableWidgetItem *item = this->item(editRow, 0); //编辑的行号及第一列
- this->setCurrentCell(editRow, 0);
- this->openPersistentEditor(item); //打开编辑项
- this->editItem(item);
- }
- }
- #ifndef TABLEWIDGET_H
- #define TABLEWIDGET_H
- #include "table.h"
- class TableWidget : public QWidget
- {
- Q_OBJECT
- public:
- TableWidget(QWidget *parent = 0);
- ~TableWidget();
- private:
- bool ScanFile(const QString & path);
- private:
- Table *table;
- };
- #endif // TABLEWIDGET_H
- #include "tablewidget.h"
- TableWidget::TableWidget(QWidget *parent)
- : QWidget(parent)
- {
- QTextCodec*codec = QTextCodec::codecForName("utf8");
- QTextCodec::setCodecForLocale(codec);
- QTextCodec::setCodecForCStrings(codec);
- QTextCodec::setCodecForTr(codec);
- setWindowTitle(tr("文件浏览"));
- table = new Table(this);
- QStringList header;
- header<<tr("文件名")<<tr("最后更改日期")<<tr("类型")<<tr("大小");
- table->setColumnValue(4, header);
- table->setHeaderWidth(0, 200);
- table->setHeaderWidth(1, 150);
- table->setHeaderWidth(2, 100);
- table->setHeaderWidth(3, 100);
- table->setHeaderHeight(30);
- //table->setRowH(0, 200);
- ScanFile(QApplication::applicationDirPath());
- // table->setRowHeight(46);
- resize(800, 800);
- }
- TableWidget::~TableWidget()
- {
- }
- //Qt实现遍历文件夹和文件目录
- bool TableWidget::ScanFile(const QString &path)
- {
- QDir dir(path);
- if (!dir.exists())
- return false;
- // dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot);
- // QFileInfoList list = dir.entryInfoList();
- // //QStringList list = dir.entryList();
- // for(int index = 0; index < list.count(); index++) {
- // QFileInfo fileInfo = list.at(index);
- // if (fileInfo.isDir()) {
- // ScanFile(fileInfo.filePath());
- // }
- // else {
- // qDebug() << "----------" << fileInfo.absoluteFilePath();
- // }
- // }
- QDirIterator dirIterator(path, QDir::Dirs | QDir::Files | QDir::NoSymLinks| QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
- while(dirIterator.hasNext()) {
- dirIterator.next();
- QFileInfo fileInfo = dirIterator.fileInfo();
- QString filePath = fileInfo.absoluteFilePath();
- QFileIconProvider iconProvider;
- QIcon icon;
- if (fileInfo.isDir()) { //获取指定文件图标
- icon = iconProvider.icon(QFileIconProvider::Folder);
- }
- else {
- icon = iconProvider.icon(fileInfo);
- }
- QFileIconProvider icon_provider;
- QString typeFile = icon_provider.type(fileInfo);
- table->addRowValue(30, QStringList()<< filePath <<fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss")
- <<typeFile<<QString::number(fileInfo.size()/1024.0, 'f', 2)+"KB", icon);
- }
- return true;
- }
- #include "tablewidget.h"
- #include <QApplication>
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- TableWidget w;
- w.show();
- return a.exec();
- }
(7)总结
根据网上博客修改了:鼠标点击的选项会出现虚框、创建右键菜单、获取文件图标类型、右键编辑时Tab键的处理和重命名文件重名后表格更新的、递归扫描文件夹。
2、QTableWidget控件属性
一、禁止编辑表格在默认情况下,表格里的字符是可以更改的。
比如双击一个单元格,就可以修改原来的内容,如果想禁止用户的这种操作,让这个表格对用户只读,可以这样:
- ui.qtablewidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
- /*设置表格为整行选中*/
- ui.qtablewidget->setSelectionBehavior(QAbstractItemView::SelectRows);
单个选中意味着每次只可以选中一个单元格,多个就是相当于可以选择”一片“那种模式。
- /*设置允许多个选中*/
- ui.qtablewidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
对于水平或垂直方向的表头,如果不想显示可以用以下方式进行(隐藏/显示)设置:
- ui.qtablewidget->verticalHeader()->setVisible(true);
- ui.qtablewidget->horizontalHeader()->setVisible(false);
- ui.qtablewidget->item(0, 0)->setTextAlignment(Qt::AlignHCenter);
- ui.qtablewidget->item(1, 0)->setBackgroundColor(QColor(0,60,10));
- ui.qtablewidget->item(1, 0)->setTextColor(QColor(200,111,100));
- ui.qtablewidget->item(1, 0)->setFont(QFont("Helvetica"));
- ui.qtablewidget->setItem(1, 0, new QTableWidgetItem(str));
- QString str =ui.qtablewidget->item(0, 0)->data(Qt::DisplayRole).toString();
- QComboBox *comBox = new QComboBox();
- comBox->addItem("F");
- comBox->addItem("M");
- ui.qtablewidget->setCellWidget(0,3,comBox);
- //合并单元格的效果
- ui.qtablewidget->setSpan(2, 2, 3, 2);
- //第一个参数:要改变的单元格行数
- //第二个参数:要改变的单元格列数
- //第三个参数:需要合并的行数
- //第四个参数:需要合并的列数
- ui.qtablewidget->setItem(3, 2, new QTableWidgetItem(QIcon("images/music.png"), "Music"));
- ui.qtablewidget->setShowGrid(true);//显示表格线
- ui.qtablewidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//去掉水平滚动条
- //初始化界面
- QStringList HStrList;
- HStrList.push_back(QString("name"));
- HStrList.push_back(QString("id"));
- HStrList.push_back(QString("age"));
- HStrList.push_back(QString("sex"));
- HStrList.push_back(QString("department"));
- //设置行列数(只有列存在的前提下,才可以设置列标签)
- int HlableCnt = HStrList.count();
- ui.qtablewidget->setRowCount(10);
- ui.qtablewidget->setColumnCount(HlableCnt);
- //设置列标签
- ui.qtablewidget->setHorizontalHeaderLabels(HStrList);
- ui.qtablewidget->resizeColumnsToContents();
- ui.qtablewidget->resizeRowsToContents();
- ui.qtablewidget->setFont(font); //设置字体
- QString strText = ui.qtablewidget->item(0, 0)->text();
3、QTableWidget美化
QSS样式表(根据需求修改颜色):- QTableWidget
- {
- background: rgb(56,56,56);
- alternate-background-color:rgb(48,51,55);
- selection-background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(56,56,56),stop:1 rgb(66,66,66));
- }
- QHeaderView::section
- {
- background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(46,46,46),stop:1 rgb(56,56,56));
- color: rgb(210,210,210);
- padding-left: 4px;border: 1px solid #383838;
- }
- QScrollBar:vertical
- {
- border: 0px solid grey;
- background: transparent;
- width: 15px;
- margin: 22px 0 22px 0;
- }
- QScrollBar::handle:vertical
- {
- background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 rgb(46,46,46),stop:1 rgb(66,66,66));
- min-height: 20px;
- }
- QScrollBar::add-line:vertical
- {
- border: 0px solid grey;
- background: rgb(66,66,66);
- height: 20px;
- subcontrol-position: bottom;
- subcontrol-origin: margin;
- }
- QScrollBar::sub-line:vertical
- {
- border: 0px solid grey;
- background: rgb(56,56,56);
- height: 20px;
- subcontrol-position: top;
- subcontrol-origin: margin;
- }
- QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical
- {
- border: 0px solid grey;
- width: 3px;
- height: 3px;
- background: rgb(46,46,46);
- }
- QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical
- {
- background: none;
- }
四、总结
(1)源码中绝大部分的功能都没实现,Table也没进行完整的封装,可根据自己的需求修改代码。(2)本代码的总结参考了网友的博客,在此感谢。
(3)源码已经打包上传到csdn上,可登录下载(http://download.csdn.net/detail/taiyang1987912/8938815)。
(4)若有建议,请留言,在此先感谢!
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/taiyang1987912/article/details/47043937