目录
一、 创建行表头
二、往表格里插入单元项(带图片和不带图片)
三、 禁止表格可编辑
四、 按行或列或单个选择单元项
五 、设置列宽(包括列表头的和行表头的)
1 这个普通的行和列都可以设置固定宽高
2 还可以将行和列的大小设为与内容相匹配
3 不想要表头的还可以隐藏掉:
4 设置表头字体颜色
5 设置固定列宽 编辑
六、设置为可以选中多个目标
七、单击或双击item会触发的信号以及怎么运用
八、QTableWidget添加右键菜单的方法
在此基础上,怎么创建出多级菜单呢?
九、QTableWidget怎么按照某列的大小来排序(有两种方法)
前言:
QTableWidget 表格单元格的行标和列标都是从 0 开始;QTableWidget 表格中,每个单元格都是 QTableWidgetItem 类的实例对象
一、 创建行表头
QStringList cHeader;
cHeader << "编号" << "名字" << "日期" ;
m_tableWidget->setHorizontalHeaderLabels(cHeader);
创建之后,运行发现显示不出来表头!查找原因发现要设置了行数和列数才行:
方法1 构造的时候就创建了行数
m_tableWidget = new QTableWidget(10,10,this);
方法2
m_tableWidget->setRowCount(10);
m_tableWidget->setColumnCount(3);
二、往表格里插入单元项(带图片和不带图片)
//..1
QTableWidgetItem *item=new QTableWidgetItem();
item->setText(“示例”);
item->setBackgroundColor(QColor("#8EE5EE"));//背景颜色
item->setTextColor(QColor("#8EE5EE"));//字体颜色
item->setFont(QFont("Helvetica"));//字体样式
m_tableWidget->setItem(row,col,item);
//..2插入带图片的项目
m_tableWidget->setItem(row,col,new QTableWidgetItem(QIcon("images/found.png"), "查找"));
另:如果需要对所有的单元格都使用这种字体,则可以使用 tableWidget->setFont(QFont("Helvetica"));
三、 禁止表格可编辑
在默认情况下,表格里的字符是可以更改的。比如双击一个单元格,就可以修改原来的内容。
m_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
QAbstractItemView::NoEditTriggers |
不允许编辑 |
QAbstractItemView::CurrentChanged |
只要当前项发生更改,编辑就会开始 |
QAbstractItemView::DoubleClicked |
当项目(指表格里的单元项)被双击时,编辑开始 |
QAbstractItemView::SelectedClicked |
当单击已选择的项目时,编辑开始 |
QAbstractItemView::EditKeyPressed |
当在项目上按下Platform编辑键时,开始编辑。 |
QAbstractItemView::AnyKeyPressed |
当在项目上按下任何键时,编辑开始。 |
QAbstractItemView::AllEditTriggers |
开始编辑以上所有操作 |
四、 按行或列或单个选择单元项
m_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
QAbstractItemView::SelectItems |
选择单个项目. |
QAbstractItemView::SelectRows |
行 |
QAbstractItemView::SelectColumns |
列 |
五 、设置列宽(包括列表头的和行表头的)
这个对列表头的设置有用,记得加头文件
#include <QHeaderView>不然会报错
m_tableWidget->verticalHeader()->setMinimumWidth(42);
m_tableWidget->horizontalHeader()->setMinimumHeight(30);
1 这个普通的行和列都可以设置固定宽高
m_tableWidget->setColumnWidth(1,200);
m_tableWidget->setRowHeight(1,120);
表头的一些相关设置还可以看看这个:因为上面的能达到我的暂时要求,其他就没去时有啥效果了.
加了下面这句之后,不管你的界面是放大还是缩小,那一列的宽高都是固定在你设置的值,而且不可手动把他变大变小
m_tableWidget->horizontalHeader()->setResizeMode(0,QHeaderView::Fixed);
2 还可以将行和列的大小设为与内容相匹配
m_tableWidget->resizeColumnsToContents();
m_tableWidget->resizeRowsToContents();
3 不想要表头的还可以隐藏掉:
m_tableWidget->verticalHeader()->setVisible(false); //隐藏列表头
m_tableWidget->horizontalHeader()->setVisible(false); //隐藏行表头
4 设置表头字体颜色
QTableWidgetItem *columnHeaderItem0 = m_tableWidget->horizontalHeaderItem(0); //获得水平方向表头的Item对象
columnHeaderItem0->setFont(QFont("Helvetica")); //设置字体
columnHeaderItem0->setBackgroundColor(QColor("#BBFFFF")); //设置单元格背景颜色
columnHeaderItem0->setTextColor(QColor("#BBFFFF")); //设置文字颜色
Qt中设置QTableWidget的表头高度
5 设置固定列宽
六、设置为可以选中多个目标
m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
QAbstractItemView::SingleSelection |
单选 |
QAbstractItemView::ContiguousSelection |
平时就当做单选即可; 它还有个功能就是按下shift键的时候同时选择单元项,再选择另一个单元项时,两个中间的单元项都会被选择。也就是多选 |
QAbstractItemView::ExtendedSelection |
这个感觉和上面那个达到的效果一样,按shift键也可以多选; 还有个功能就是当用户以通常的方式选择一项时,该选择被清除并且新的项被选中。但是,如果用户在单击某个项目时按下Ctrl键,则会切换所单击的项目,而所有其他项目保持不变。(我没看懂qaq) |
QAbstractItemView::MultiSelection |
这个就是你连续拉,可以多选(而且你再重新选中其他项目之前的状态会保持不变,上面三个是你再次选中其他单元项的时候,之前选中的就会恢复没被选中的状态); 然后你选中了某个项目再单击一次那个项目它的状态就会被切换成没选中;上面三个都没有这个效果也就是你再单击它也是选中的状态,除非你选了其他的单选项 |
QAbstractItemView::NoSelection |
Items cannot be selected. |
七、单击或双击item会触发的信号以及怎么运用
connect(m_tableWidget,SIGNAL(itemClicked(QTableWidgetItem*)),this,SLOT(slotGetTableItem(QTableWidgetItem*)));
//槽函数里面我们可以通过item获取很多单元格里的信息,比如item所在的行和列,文字等
void MainWindow::slotGetTableItem(QTableWidgetItem *item)
{
qDebug() << item->column() << item->text() << "ceshi";
}
另外还有这些信号,用法和上面一样
void |
itemActivated ( QTableWidgetItem * item )
|
void |
itemChanged ( QTableWidgetItem * item )
|
void |
itemDoubleClicked ( QTableWidgetItem * item )
|
void |
itemEntered ( QTableWidgetItem * item )
|
void |
itemPressed ( QTableWidgetItem * item )
|
//..1
QMenu *m_popupMenu;
//..2
m_popupMenu=new QMenu(this);
m_popupMenu->addAction(tr("选中"),this,SLOT(slotCheckedSelected()));//这个槽函数里面可以做你选择之后想做的事
m_popupMenu->addAction(tr("取消选中"),this,SLOT(slotUnCheckedSelected()));
m_popupMenu->addSeparator();
//..3
m_tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_tableWidget,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(slotShowPopupMenu(QPoint)));
//槽函数
void MainWindow::slotShowPopupMenu(const QPoint &p)
{
QPoint pp;
pp.setX(QCursor::pos().x()+2);
pp.setY(QCursor::pos().y());
m_popupMenu->exec(pp);
}
效果:
在此基础上,怎么创建出多级菜单呢?
当鼠标滑到多级菜单添加的项目是会自动弹出下级菜单的,方法如下:
新创建出一个菜单:
QMenu *m_testMenu;
m_testMenu = m_popupMenu->addMenu("ceshi");//重点在这里
m_testMenu->addAction(tr("111"),this,SLOT(slotTest1()));
m_testMenu->addAction(tr("2222"),this,SLOT(slotTest2()));
m_testMenu->addSeparator();
当然这是在QTableWidget里面我们刚才已经绑定了这个m_tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);而且槽函数里面做了相关操作,右键的时候会弹出菜单栏
如果不是在表格里面的话,我们可能需要重写contextMenuEvent()事件用于处理鼠标右键事件,在右击鼠标时,在鼠标点击的位置弹出菜单。
void Widget::contextMenuEvent(QContextMenuEvent *event)
{
m_popupMenu->exec(QCursor::pos());
event->accept();
}
示例:
QMenu *m_ProgramBtnGroupMenu;
QAction *m_CopyEffectAction;
m_ProgramBtnGroupMenu->addAction(tr("复制"), this, SLOT(slotProgramGroupCopy()));
m_CopyEffectAction = m_ProgramBtnGroupMenu->addAction(tr("粘贴"), this, SLOT(slotProgramGroupPost()));
//先设置为不可见
m_CopyEffectAction->setEnabled(false);
//然后再你做了某个操作之后,就设为可见
m_CopyEffectAction->setEnabled(true);
示例:
QAction *m_ascSortAction;
QAction *m_descSortAction;
用setIcon的方法添加图标,直接构造添加的,我的显示不是很顺畅不知道啥原因
这几个action都可以绑定同一个槽函数,具体如下:
void MainWindow::slotSortAction()
{
QAction *action = (QAction*)sender();
QString sActText = action->text();
if(sActText == "升序")
{
m_bDescSortSong = false;
m_ascSortAction->setIconVisibleInMenu(true);//设置图标可见
m_descSortAction->setIconVisibleInMenu(false);//设置图标不可见
}
else if(sActText == "降序")
{
m_bDescSortSong = true;
m_ascSortAction->setIconVisibleInMenu(false);
m_descSortAction->setIconVisibleInMenu(true);
}
}
1:应用:在这里,你可以定义一个全局变量,比如说有个combox来记录它选择要排列哪一列,还有是升序还是降序,通过调用sortByColumn就可以达到表格按照某列的值排序的效果了
int iCol=0;
//..1
if(m_bSortBySongDownloadTime)//我这里只涉及到两列,所以这样判断即可,多列的话可以用多个if来判断或者switch
iCol=2;
//..2
if(m_bDescSortSong)
m_tableWidget->sortByColumn(iCol,Qt::DescendingOrder);//降
else
m_tableWidget->sortByColumn(iCol,Qt::AscendingOrder);//升
但是由于QTableWidgetItem比较大小的时候用的是字符串比较,我们一般比较大小的时候都是根据整型值。所以这里我们要重写一下QTableWidgetItem
.h
#ifndef MYTABLEWIDGETITEM_H
#define MYTABLEWIDGETITEM_H
#include <QIcon>
#include <QObject>
#include <QTableWidgetItem>
class MyTableWidgetItem : public QTableWidgetItem
{
public:
MyTableWidgetItem();
~MyTableWidgetItem();
MyTableWidgetItem(const QString& sText);
MyTableWidgetItem(int role, const QVariant & value);
MyTableWidgetItem(const QIcon& icon, const QString& sText);
bool operator < (const QTableWidgetItem& other) const;
};
#endif // MYTABLEWIDGETITEM_H
.cpp
#include "mytablewidgetitem.h"
MyTableWidgetItem::MyTableWidgetItem():QTableWidgetItem()
{
}
MyTableWidgetItem::~MyTableWidgetItem()
{
}
MyTableWidgetItem::MyTableWidgetItem(const QString &sText)
{
setText(sText);
}
MyTableWidgetItem::MyTableWidgetItem(const QIcon &icon, const QString &sText)
{
setText(sText);
setIcon(icon);
}
bool MyTableWidgetItem::operator <(const QTableWidgetItem &other) const
{
//通常只需要这句话即可
return text().toInt() < other.text().toInt();
//但是由于我有一列显示的数据是QString的时间,这里就不能像上面那样直接返回了,我把时间对应的时间戳放在data数据里,比较时间戳就可以了
bool ok;
text().toInt(&ok);
if(ok)
{
return text().toInt() < other.text().toInt();
}
else
{
return this->data(Qt::UserRole).toInt() < other.data(Qt::UserRole).toInt();
}
}
给大家看看我加入数据的时候是怎么加的:
setData还可以存多个数据,可以看这里:利用setData(),data()存储数据的示例
2 如果你的列数据没那么麻烦的话,可以直接用QTableWidget自带的表头排列方式,如下:
m_tableWidget->horizontalHeader()->setClickable(true);
m_tableWidget->horizontalHeader()->setStretchLastSection(false);
connect(m_tableWidget->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT (slotSortByColumn(int)));
if (iColumnindex==1 || iColumnindex==3)
{
m_tableWidget->horizontalHeader()->setSortIndicatorShown(false);
return;
}
m_iCurrentSortColumnIndex=iColumnindex;
m_tableWidget->horizontalHeader()->setSortIndicatorShown(true);//设置是否要排列
Qt::SortOrder cSortorder;
cSortorder=m_tableWidget->horizontalHeader()->sortIndicatorOrder();
m_tableWidget->sortByColumn(iColumnindex);
cSortorder=m_tableWidget->horizontalHeader()->sortIndicatorOrder();
问题:QTableWidget的clear函数会释放Item,同样效果的还有clearContents()、removeRow()。所有再次使用到item->text()会引起异常(野指针)