Qt浅谈之三十一数据表格(QTableWidget)

来源:互联网 发布:我的世界手机版js吧 编辑:程序博客网 时间:2024/06/05 11:52

一、简介

        QTableWidget是QT对话框设计中常用的显示数据表格的控件,QTableWidget单元格数据是QTableWidgetItem对象来实现的,整个表格都需要用逐个单元格对象QTableWidgetItem构建起来。


二、详解

1、代码

(1)table.h

#ifndef TABLE_H#define TABLE_H#include <QtGui>class Table : public QTableWidget{    Q_OBJECTpublic:    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 classclass NoFocusDelegate : public QStyledItemDelegate{protected:    void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;};#endif // TABLE_H
(2)table.cpp
#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);    }}
(3)tablewidget.h
#ifndef TABLEWIDGET_H#define TABLEWIDGET_H#include "table.h"class TableWidget : public QWidget{    Q_OBJECTpublic:    TableWidget(QWidget *parent = 0);    ~TableWidget();private:    bool ScanFile(const QString & path);private:    Table *table;};#endif // TABLEWIDGET_H
(4)tablewidget.cpp
#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;}
(5)main.cpp
#include "tablewidget.h"#include <QApplication>int main(int argc, char *argv[]){    QApplication a(argc, argv);    TableWidget w;    w.show();    return a.exec();}
(6)运行结果

(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));
八、把QTableWidgetItem对象内容转换为QString
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)若有建议,请留言,在此先感谢!

3 0
原创粉丝点击