zoukankan      html  css  js  c++  java
  • QTableWidget详解(样式、右键菜单、表头塌陷、多选等)

    在Qt的开发过程中,时常会用到表单(QTableWidget)这个控件,网上的资料不少,但是都是最基本的,有一些比较经常遇到的问题也说得不太清楚。所以,今天就在这里总结一下!
    以下为个人模拟Windows资源管理器的一个表单

     1 一、设置表单样式
     2 table_widget->setColumnCount(4); //设置列数
     3 table_widget->horizontalHeader()->setDefaultSectionSize(150); 
     4 table_widget->horizontalHeader()->setClickable(false); //设置表头不可点击(默认点击后进行排序)
     5 
     6 //设置表头内容
     7 QStringList header;
     8 header<<tr("name")<<tr("last modify time")<<tr("type")<<tr("size");
     9 table_widget->setHorizontalHeaderLabels(header);
    10 
    11 //设置表头字体加粗
    12 QFont font = this->horizontalHeader()->font();
    13 font.setBold(true);
    14 table_widget->horizontalHeader()->setFont(font);
    15 
    16 table_widget->horizontalHeader()->setStretchLastSection(true); //设置充满表宽度
    17 table_widget->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
    18 table_widget->verticalHeader()->setDefaultSectionSize(10); //设置行高
    19 table_widget->setFrameShape(QFrame::NoFrame); //设置无边框
    20 table_widget->setShowGrid(false); //设置不显示格子线
    21 table_widget->verticalHeader()->setVisible(false); //设置垂直头不可见
    22 table_widget->setSelectionMode(QAbstractItemView::ExtendedSelection); //可多选(Ctrl、Shift、 Ctrl+A都可以)
    23 table_widget->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为时每次选择一行
    24 table_widget->setEditTriggers(QAbstractItemView::NoEditTriggers); //设置不可编辑
    25 table_widget->horizontalHeader()->resizeSection(0,150); //设置表头第一列的宽度为150
    26 table_widget->horizontalHeader()->setFixedHeight(25); //设置表头的高度
    27 table_widget->setStyleSheet("selection-background-color:lightblue;"); //设置选中背景色
    28 table_widget->horizontalHeader()->setStyleSheet("QHeaderView::section{background:skyblue;}"); //设置表头背景色
    29 
    30 //设置水平、垂直滚动条样式
    31 table_widget->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}"
    32 "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
    33 "QScrollBar::handle:hover{background:gray;}"
    34 "QScrollBar::sub-line{background:transparent;}"
    35 "QScrollBar::add-line{background:transparent;}");
    36 table_widget->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent;  10px;}"
    37 "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}"
    38 "QScrollBar::handle:hover{background:gray;}"
    39 "QScrollBar::sub-line{background:transparent;}"
    40 "QScrollBar::add-line{background:transparent;}");



    好了,样式设置完成,效果如下所示:
    QTableWidget详解(样式、右键菜单、表头塌陷、多选等)


    问题一:鼠标点击的选项会出现虚框,在Qt官网找到一篇博客专门介绍的,直接上代码!
    (1)实现如下一个类

     1 #include "no_focus_delegate.h"
     2 void NoFocusDelegate::paint(QPainter* painter, const QStyleOptionViewItem & option, const QModelIndex &index) const
     3 {
     4 QStyleOptionViewItem itemOption(option);
     5 if (itemOption.state & QStyle::State_HasFocus)
     6 {
     7 itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
     8 }
     9 QStyledItemDelegate::paint(painter, itemOption, index);
    10 }


    (2)表格构造中添加如下代码
    table_widget->setItemDelegate(new NoFocusDelegate());

    QTableWidget详解(样式、右键菜单、表头塌陷、多选等)
    OK,虚线边框去除

    问题二:当表格只有一行的时候,则表头会出现塌陷问题
    QTableWidget详解(样式、右键菜单、表头塌陷、多选等)
    摸索了很长时间,才得以解决:

    1 //点击表时不对表头行光亮(获取焦点) 
    2 table_widget->horizontalHeader()->setHighlightSections(false);

    二、多选并获取所选行

     1 this->setSelectionMode(QAbstractItemView::ExtendedSelection); //设置多选(可以Ctral+A全选Ctral+Shift多选)获取所选行号:
     2 bool TableWidget::getSelectedRow(QSet&set_row)
     3 {
     4 QList items = this->selectedItems();
     5 int item_count = items.count();
     6 if(item_count <= 0)
     7 {
     8 return false;
     9 }
    10 for(int i=0; i
    11 {
    12 //获取选中的行
    13 int item_row = this->row(items.at(i));
    14 set_row.insert(item_row);
    15 }
    16 return true;
    17 }

    三、操作表单(添加、删除行等)
    (1)动态插入行

     1 int row_count = table_widget->rowCount(); //获取表单行数
     2 table_widget->insertRow(row_count); //插入新行
     3 QTableWidgetItem *item = new QTableWidgetItem();
     4 QTableWidgetItem *item1 = new QTableWidgetItem();
     5 QTableWidgetItem *item2 = new QTableWidgetItem();
     6 QTableWidgetItem *item3 = new QTableWidgetItem();
     7 //设置对应的图标、文件名称、最后更新时间、对应的类型、文件大小
     8 item->setIcon(icon); //icon为调用系统的图标,以后缀来区分 
     9 item->setText(name);
    10 item1->setText(last_modify_time);
    11 item2->setText(type); //type为调用系统的类型,以后缀来区分
    12 item3->setText(size);
    13 table_widget->setItem(row_count, 0, item);
    14 table_widget->setItem(row_count, 1, item1); 
    15 table_widget->setItem(row_count, 2, item2);
    16 table_widget->setItem(row_count, 3, item3);
    17 //设置样式为灰色
    18 QColor color("gray");
    19 item1->setTextColor(color);
    20 item2->setTextColor(color);
    21 item3->setTextColor(color);


    (2)在指定位置插入行
    其实跟(1)相似,(1)的前提是获取到表格行数
    table_widget->insertRow(row); //插入新行 row为插入的位置

    四、单击表头触发的事件
    (1)连接表头的信号和槽

    1 connect(horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(onHeaderClicked(int)));



    (2)实现槽函数

    1 void TableWidget::onHeaderClicked(int column)
    2 {
    3 //column为所点击的表头的某列
    4 }



    五、打开某行进行编辑
    既然模拟Window那么就模仿的像一点,Windows可以修改名称,那么Qt也必然可以实现
    QTableWidget详解(样式、右键菜单、表头塌陷、多选等)

    1 //获得当前节点并获取编辑名称
    2 QTableWidgetItem *item = table_widget->item(edit_row, 0); //edit_row为想要编辑的行号
    3 table_widget->setCurrentCell(edit_row, 0);
    4 table_widget->openPersistentEditor(item); //打开编辑项
    5 table_widget->editItem(item);
    6 
    7 //关闭编辑项
    8 table_widget->closePersistentEditor(item);

    QTableWidget详解(样式、右键菜单、表头塌陷、多选等)
    OK,重命名完成,!

    六、右键菜单
    (1)创建菜单、菜单项

     1 void TableWidget::createActions()
     2 {
     3 //创建菜单项
     4 pop_menu = new QMenu();
     5 action_name = new QAction(this);
     6 action_size = new QAction(this);
     7 action_type = new QAction(this);
     8 action_date = new QAction(this);
     9 action_open = new QAction(this); 
    10 action_download = new QAction(this);
    11 action_flush = new QAction(this);
    12 action_delete = new QAction(this);
    13 action_rename = new QAction(this);
    14 action_create_folder = new QAction(this);
    15 
    16 action_open->setText(QString("打开"));
    17 action_download->setText(QString("下载"));
    18 action_flush->setText(QString("刷新"));
    19 action_delete->setText(QString("删除"));
    20 action_rename->setText(QString("重命名"));
    21 action_create_folder->setText(QString("新建文件夹"));
    22 action_name->setText(QString("名称"));
    23 action_size->setText(QString("大小"));
    24 action_type->setText(QString("项目类型"));
    25 action_date->setText(QString("修改日期"));
    26 
    27 //设置快捷键
    28 action_flush->setShortcut(QKeySequence::Refresh);
    29 
    30 //设置文件夹图标
    31 action_create_folder->setIcon(icon);
    32 QObject::connect(action_create_folder, SIGNAL(triggered()), this, SLOT(createFolder()));
    33 } 


    (2)重新实现contextMenuEvent

     1 void TableWidget::contextMenuEvent(QContextMenuEvent *event)
     2 {
     3 pop_menu->clear(); //清除原有菜单
     4 QPoint point = event->pos(); //得到窗口坐标
     5 QTableWidgetItem *item = this->itemAt(point);
     6 if(item != NULL)
     7 {
     8 pop_menu->addAction(action_download);
     9 pop_menu->addAction(action_flush);
    10 pop_menu->addSeparator();
    11 pop_menu->addAction(action_delete);
    12 pop_menu->addAction(action_rename);
    13 pop_menu->addSeparator();
    14 pop_menu->addAction(action_create_folder);
    15 sort_style = pop_menu->addMenu("排序");
    16 sort_style->addAction(action_name);
    17 sort_style->addAction(action_size);
    18 sort_style->addAction(action_type);
    19 sort_style->addAction(action_date);
    20 
    21 //菜单出现的位置为当前鼠标的位置
    22 pop_menu->exec(QCursor::pos());
    23 event->accept();
    24 } 
    25 }



    OK,大功告成!
    QTableWidget详解(样式、右键菜单、表头塌陷、多选等)

    七、信号

     1 void cellActivated(int row, int column)
     2 void cellChanged(int row, int column)
     3 void cellClicked(int row, int column)
     4 void cellDoubleClicked(int row, int column)
     5 void cellEntered(int row, int column)
     6 void cellPressed(int row, int column)
     7 void itemActivated(QTableWidgetItem *item)
     8 void itemChanged(QTableWidgetItem *item)
     9 void itemClicked(QTableWidgetItem *item)
    10 void itemDoubleClicked(QTableWidgetItem *item)
    11 void itemEntered(QTableWidgetItem *item)
    12 void itemPressed(QTableWidgetItem *item)
    13 void itemSelectionChanged()
    14 void currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous)
    15 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/s/blog_a6fb6cc90101dd5u.html

  • 相关阅读:
    300. Longest Increasing Subsequence_算法有误
    LIS (DP)_代码
    pthread_detach pthread_create实例
    pthread_detach
    DP(动态规划)
    括号匹配(二)
    gdb调试遇到的问题
    matplotlib 显示中文
    一个奇怪的编码 big5-hkscs
    python 重载 __hash__ __eq__
  • 原文地址:https://www.cnblogs.com/felix-wang/p/6210198.html
Copyright © 2011-2022 走看看