现在的位置: 首页 > 综合 > 正文

QTableWidget详解(样式、右键菜单、表头塌陷、多选等)

2013年03月10日 ⁄ 综合 ⁄ 共 6962字 ⁄ 字号 评论关闭

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

  以下为个人模拟Windows资源管理器的一个表单

 

 一、设置表单样式

  table_widget->setColumnCount(4);//设置列数

  table_widget->horizontalHeader()->setDefaultSectionSize(150); 
 table_widget->horizontalHeader()->setClickable(false);//设置表头不可点击(默认点击后进行排序)

 

  //设置表头内容
  QStringList header;
 header<<tr("name")<<tr("lastmodifytime")<<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, constQModelIndex &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(newNoFocusDelegate());

 

   OK,虚线边框去除

 

  问题二:当表格只有一行的时候,则表头会出现塌陷问题

  

 

   摸索了很长时间,才得以解决:

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

 

 二、操作表单(添加、删除行等)

  (1)动态插入行

  int row_count =table_widget->rowCount(); //获取表单行数
 table_widget->insertRow(row_count); //插入新行

  QTableWidgetItem *item = newQTableWidgetItem();
  QTableWidgetItem *item1 = newQTableWidgetItem();
  QTableWidgetItem *item2 = newQTableWidgetItem();
  QTableWidgetItem *item3 = newQTableWidgetItem();

  //设置对应的图标、文件名称、最后更新时间、对应的类型、文件大小
 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(intcolumn)
  {
     //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)创建菜单、菜单项

   voidTableWidget::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= newQAction(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

  voidTableWidget::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, intcolumn)
  void cellChanged(int row, int column)
  void cellClicked(int row, int column)
  void cellDoubleClicked(int row, intcolumn)
  void cellEntered(int row, int column)
  void cellPressed(int row, int column)
  voiditemActivated(QTableWidgetItem *item)
  void itemChanged(QTableWidgetItem *item)
  void itemClicked(QTableWidgetItem *item)
  void itemDoubleClicked(QTableWidgetItem*item)
  void itemEntered(QTableWidgetItem *item)
  void itemPressed(QTableWidgetItem *item)
  void itemSelectionChanged()

  voidcurrentItemChanged(QTableWidgetItem *current, QTableWidgetItem*previous)

  void currentCellChanged(intcurrentRow, int currentColumn, int previousRow, intpreviousColumn)
 

 

 到这里,还有一点遗留问题,关于界面的文件(文件夹)图标和类型怎么显示的?又怎么区别什么时候显示什么样的图标呢?如果图标和类型写死的话必不可行,因为不同后缀的文件至少也有100种以上吧!这里提示一下,可以调用系统API获取当前系统的指定文件(通过后缀区分)对应的类型以及图标。。。

 

  这些都是在接触Qt以来总结的一些小经验,希望对大家有用!

抱歉!评论已关闭.