QTableWidget的用法总结 - findumars - 博客园
Qt QTableWidget 样式表_漫步繁华街的博客-CSDN博客_qtablewidget 样式
QT模型视图MVC系列教程(5)---自定义委托Delegate编辑时显示_setitemdelegateforrow_暴躁的野生猿的博客-CSDN博客
前言:QT内置了它的两个子类QItemDelegate and QStyledItemDelegate,其中QItemDelegate不支持样式表,QStyledItemDelegate会使用当前样式绘制内容,支持样式表,推荐继承QStyledItemDelegate 来实现自定义委托。
一、实现整行上下拖动
1.写一个继承于 QTableWidget的ProSelectTableWidget类
2.重写拖拽事件dropEvent(QDropEvent *event
3.将TableWidget控件提升为ProSelectTableWidget
ProSelectTableWidget.cpp/.h 资源如下
QTableWidget实现整行拖动-C++文档类资源-CSDN下载
ProSelectTableWidget::ProSelectTableWidget(QWidget *parent)
: QTableWidget{parent}
{
//拖拽设置
this->setDragDropMode(QAbstractItemView::InternalMove); // 内部移动
this->setDropIndicatorShown(true); // drop位置 提示
this->setSelectionBehavior(QAbstractItemView::SelectRows);//选中整行
}
//重写拖拽事件
void ProSelectTableWidget::dropEvent(QDropEvent *event)
{
qDebug()<<"dropEvent";
// 原行号与目标行号的确定
int row_src,row_dst;
row_src = this->currentRow(); // 原行号 可加if
QTableWidgetItem *item = this->itemAt(event->position().toPoint()); // 获取落点的item
if(item !=nullptr){ // 判断是否为空
row_dst = item->row(); // 不为空 获取其行号
// 保证鼠标落下的位置 就是拖拽的一行最后所移动到的位置(考虑插入新行 移除原行的上下变化)
row_src = (row_src > row_dst? row_src + 1:row_src); // 如果src在dst的下方(行号大),后续插入dst会影响src的行号
row_dst = (row_src < row_dst? row_dst + 1:row_dst); // 如果src在dst的上方(行号小),后续移除src会影响dst的行号
this->insertRow(row_dst); // 插入一行
}
else{ // 落点没有item 说明拖动到了最下面
row_dst = this->rowCount();// 获取行总数
this->insertRow(row_dst); // 在最后新增一行
}
// 执行移动 并移除原行
for(int i = 0;i < this->columnCount();i++){ // 遍历列
this->setItem(row_dst,i,this->takeItem(row_src,i));// 每一列item的移动
}
this->removeRow(row_src); // 删除原行
}
二、使用委托类限制整行/列输入内容
函数:
2.1 createEditor
返回在 QTableView 中使用的控件,就在这边用正则限制输入的数据。
2.2 setEditorData
从指定的数据模型设置要由编辑器显示和编辑的数据
2.3 setModelData
从 editor 小部件获取数据,并将数据存储在项目索引处的数据模型中。
2.4 updateEditorGeometry
根据给定的样式选项,更新 index 指定项的编辑器。
2.5void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
思路:
1.使用委托(直接写函数在头文件),写继承于QItemDelegate的GenderComboBoxDelegate类
2.重新实现 QAbstractItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
"GenderComboBoxDelegate.h"//限制只能选男或女
#ifndef GENDER_COMBO_BOX_DELEGATE_HPP_
#define GENDER_COMBO_BOX_DELEGATE_HPP_
#include <QItemDelegate>
#include <QComboBox>
class GenderComboBoxDelegate: public QItemDelegate {
Q_OBJECT
public:
using QItemDelegate::QItemDelegate;
QWidget *GenderComboBoxDelegate::createEditor
(QWidget *parent,
const QStyleOptionViewItem & /*option*/,
const QModelIndex & /*index*/) const
{
//在tablewidget设置控件
QComboBox *editor = new QComboBox{parent};
editor->addItem(tr("男"));
editor->addItem(tr("女"));
return editor;
}
#endif
ReadOnlyDelegate.h//限制不可编辑
#ifndef READONLYDELEGATE_H
#define READONLYDELEGATE_H
#include <QItemDelegate>
class ReadOnlyDelegate : public QItemDelegate
{
Q_OBJECT
public:
explicit ReadOnlyDelegate(QObject *parent = nullptr);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
Q_UNUSED(parent)
Q_UNUSED(option)
Q_UNUSED(index)
return NULL;
}
signals:
};
#endif // READONLYDELEGATE_H
调用:
GenderComboBoxDelegate *limitnum = new GenderComboBoxDelegate{this};
//限制第二列编辑
m_ui->userinfoTableWidget->setItemDelegateForColumn(1, limitnum);
参考:QT:在QTableView中使用各种自定义委托_Keycer的博客-CSDN博客
三、解决在QTableWidget控件中无法响应鼠标事件——安装事件过滤器
由于鼠标事件被父窗口拦截,QTableWidget无法捕获鼠标事件,使用Qt的事件过滤器,捕获QTableWidget的视窗(viewPort
)所发生的事件。
//在构造函数中为QTableWidget安装事件过滤器
m_ui->userinfoTableWidget->viewport()->installEventFilter(this);
bool eventFilter(QObject *obj, QEvent *event)
{
if (obj == m_ui->userinfoTableWidget->viewport())
{
QMouseEvent *e = static_cast<QMouseEvent *>(event);
if (e == nullptr) {
return QWidget::eventFilter(obj, event);
}
//判断事件类型为鼠标点击
if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) {
deselect(e);
}
}
return QWidget::eventFilter(obj, event);
}
void deselect(QMouseEvent *e)
{
...
}
参考:QTableWidget无法响应鼠标点击(QMousePressEvent)的问题_flist的博客-CSDN博客_mousepressevent不响应