目录
2、写.h文件(名称可以自定义,但是必须是继承QStyledItemDelegate)
2、如果你是代码生成,New完按照上面的配置即可。然后添加到子视图
3、为啥我的QListview旁边出现了滑动条??如何隐藏滑动条,如何禁用滑动条?
5、我想像网易云那样,上面的组件和QListView,整体可以下滑。
255.效果展示
事实上,这个是用QListView实现的,用QTableView更好。
00.废话
一般情况下QListView中的元素可以用
QStandardItemModel *pModel = new QStandardItemModel();
QStandardItem *pItem = new QStandardItem;
这两个方法搞OK。
但是如果要使用比较特殊一点的Custom 显示效果,就需要设置ListView的
QStyledItemDelegate //就是这个鬼玩意,新建一个C艹 Class具体的内容下面有。
其中 QStyledItemDelegate类主要用在model-view的编辑上,调用
paint 方法 方法啥样,看下面
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
进行渲染。因此可以通过重写paint函数就可以实现自定义数据。
01.Delegate怎么写
1.不可或缺的事情
定义 Model 例如:
typedef struct {
QString name;
QString type ;
QString package;
QString positionString;
QString lc_code ;
QString serial ;
QString pic_url ;
QString created_at ;
QString updated_at ;
} MuItemData;
Q_DECLARE_METATYPE(MuItemData) //必不可少(少了完犊子)
可以放在Delegate.h的前面,当然也可以单独放置
2.写.h文件(名称可以自定义,但是必须是继承QStyledItemDelegate)
class MyItemDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
MyItemDelegate(QListView *parent = nullptr);
virtual ~MyItemDelegate();
//paint函数就是绘制用耳朵
void paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
//sizeHint 可以改变item的大小
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
};
以下方法也都可以用哦。具体使用参考QT官网:戳我看文档
virtual QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const override
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override
3.写.cpp文件
paint在这里,sizeHint在下面
void ResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.isValid()) {
QStyleOptionViewItem viewOption(option);
if (viewOption.state & QStyle::State_HasFocus) {
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
}
painter->save();
QVariant var = index.data(Qt::UserRole+1);
MuItemData itemData = var.value<MuItemData>();
//这里是绘制item 矩形区域
QRectF rect;
rect.setX(option.rect.x()); //根据option的大小绘制
rect.setY(option.rect.y());
rect.setWidth(option.rect.width()-1);
rect.setHeight(option.rect.height()-1);
QPainterPath path;
path.moveTo(rect.topRight());
path.lineTo(rect.topLeft());
path.quadTo(rect.topLeft(), rect.topLeft());
path.lineTo(rect.bottomLeft());
path.quadTo(rect.bottomLeft(), rect.bottomLeft());
path.lineTo(rect.bottomRight());
path.quadTo(rect.bottomRight(), rect.bottomRight());
path.lineTo(rect.topRight());
path.quadTo(rect.topRight(), rect.topRight());
// 鼠标悬停、选中、单双行改变背景色
if (option.state.testFlag(QStyle::State_MouseOver)) {
painter->setPen(QPen(QColor::fromRgb(229,229,229,255)));
painter->setBrush(QColor::fromRgb(229,229,229,255));
painter->drawRoundedRect(rect,border_radius,border_radius);
}else if (option.state.testFlag(QStyle::State_Selected)) {
painter->setPen(QPen(QColor("#e4f0ff")));
painter->setBrush(QColor("#e4f0ff"));
painter->drawRoundedRect(rect,border_radius,border_radius);
}else if (index.row()%2 ==0){
painter->setPen(QPen(QColor::fromRgb(242,242,242,255)));
painter->setBrush(QColor::fromRgb(242,242,242,255));
painter->drawRoundedRect(rect,border_radius,border_radius);
}else{
painter->setPen(QPen(QColor::fromRgb(250,250,250,255)));
painter->setBrush(QColor::fromRgb(250,250,250,255));
painter->drawRoundedRect(rect,border_radius,border_radius);
}
//各项数据的放置区域区域、明显可以看出是一项跟着一项
QRectF id = QRect(rect.left() + 5, rect.top() + 5, 40, 40);
QRectF LCCode = QRect(id.right() + 10, id.top(), rect.width() /7, 20);
QRectF Name = QRect(LCCode.right() + 10, id.top(), rect.width() /7, 20);
QRectF package = QRect(Name.right() + 50, id.top(), rect.width() /7-40, 20);
QRectF type = QRect(package.right() + 10, id.top(), rect.width() /7, 20);
QRectF serial = QRect(type.right() + 10, id.top(), rect.width() /7, 20);
QRectF positionString = QRect(serial.right() + 20, id.top(), rect.width() /7, 20);
painter->setPen(QPen(QColor::fromRgb(204,204,204,255)));
painter->setFont(QFont("丁卯点阵体 9px", 10));
painter->drawText(id, QString::number(index.row() + 1));
painter->setPen(QPen(Qt::black));
painter->setFont(QFont("丁卯点阵体 9px", 10));
painter->drawText(Name, itemData.name);
painter->setPen(QPen(Qt::black));
painter->setFont(QFont("丁卯点阵体 9px", 10));
painter->drawText(LCCode, itemData.lc_code);
painter->setPen(QPen(Qt::black));
painter->setFont(QFont("丁卯点阵体 9px", 10));
painter->drawText(package, itemData.package);
painter->setPen(QPen(Qt::black));
painter->setFont(QFont("丁卯点阵体 9px", 10));
painter->drawText(type, itemData.type);
painter->setPen(QPen(Qt::black));
painter->setFont(QFont("丁卯点阵体 9px", 10));
painter->drawText(serial, itemData.serial);
painter->setPen(QPen(Qt::black));
painter->setFont(QFont("丁卯点阵体 9px", 10));
painter->drawText(positionString, itemData.positionString);
painter->restore();
}
}
sizeHint在这里
QSize ResultDelegate::sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const {
Q_UNUSED(index)
return QSize(option.rect.width(), 30);
}
02.这个鬼玩意怎么使用
1.如果你是UI生成
1、首先在UI界面拖一个出来:
2、拖到你想要去的地方
3、撸代码
QStandardItemModel *pModel = new QStandardItemModel();
for (int i=0; i<55; ++i) {
QStandardItem *pItem = new QStandardItem;
MuItemData itemData; //在这里是用你定义的模型
itemData.name = "10nF ±10% 50V";
itemData.package = "0603";
itemData.lc_code = "C386151";
itemData.positionString = "cab_A_16";
itemData.serial = "UMK107B103KAHT";
itemData.type = "贴片电容(MLCC)";
itemData.pic_url ="https://alimg.szlcsc.com/upload/public/product/breviary/20230109/37C066B076EAB09E57A5A7BEB01242BA.jpg";
pItem->setData(QVariant::fromValue(itemData), Qt::UserRole+1);
pModel->appendRow(pItem);
}
ResultDelegate *pItemDelegate = new ResultDelegate(this);
ui->listView->setItemDelegate(pItemDelegate);
4、即可使用、特殊需求往下看、但是跳过下面一句话。
2.如果你是代码生成,New完按照上面的配置即可。然后添加到子视图
3、特殊需求的实现
1.改绘制的颜色
在paint函数中最后的没有IF的那个改颜色就是。
2.为啥我悬停在item上没有变色,是不是BUG?
不是,需要加入代码
ui->listView->viewport()->setAttribute(Qt::WA_Hover);
3.为啥我的QListview旁边出现了滑动条??如何隐藏滑动条,如何禁用滑动条?
因为你的数据量比较大,条数*item高度 > view的miniheight,所以出现了滑动条;
如果只是不想看到滑动条:
ui->listView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
上述代码使用后只是看不见,但是!!里面一样可以通过鼠标中间滚轮滑动!!!
如果想禁用滑动条:
ui->listView->verticalScrollBar()->setDisabled(true);
俩可以同时使用;
注意:禁用和不想看到不代表他会显示完整,一样会显示不完整。
4、我不想出现进度条,我就想完整显示!自动适应高度!
ui->listView->setMinimumHeight(你item的高度 * (pModel->rowCount()+1));
使用此代码即可,但是,注意!可能会超出边际!
5、我想像网易云那样,上面的组件和QListView,整体可以下滑。
(你在说啥?看例子)
思路:
底层scrollArea>自动嵌套scrollAreaWidgetContents>里面塞各种组件+ListView
(scrollAreaWidgetContents里 切记使用布局,否则无法使用)
关键代码:
ui->scrollAreaWidgetContents->setMinimumHeight(65 * pModel->rowCount() + 20);
此代码作用就是把scrollAreaWidgetContents放大容得下第四点中的自适应高度的ListView。
记得和搭配第四点的一起食用,否则无效;
后记:
Qt的资料太少、还需要多摸索。
环境:QT 5.15.2
推荐使用CLion