1.需求描述
代理实现按钮图标状态的绘制
实现方法
(1)重写paint函数,根据type类型绘制案件、文件夹、监控点、视频任务;
为了实现不同的item的样式,需要继承QStyledItemDelegate类型实现TreeTaskDelegate。重写paint函数,根据不同的类型type去绘制不同的按钮和状态;
void TreeTaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (painter == nullptr || !index.isValid()) { return; } if (option.state & QStyle::State_Editing) { return; } if (index.flags()) { } QFont gfont; gfont.setFamily("Microsoft YaHei UI"); gfont.setPixelSize(16); painter->setFont(gfont); QStyleOptionViewItem viewOption(option); initStyleOption(&viewOption, index); if (option.state.testFlag(QStyle::State_HasFocus)) viewOption.state = viewOption.state ^ QStyle::State_HasFocus; QStyledItemDelegate::paint(painter, viewOption, index); QVariantMap var = index.data(Qt::UserRole).toMap(); if (var.contains("type")) { QString strType = var.value("type").toString(); if (strType == "0")//case { paintCase(painter, viewOption, index); } else if (strType == "1")//folder { paintFolder(painter, viewOption, index); } else if (strType=="3")//camera { paintCamera(painter, viewOption, index); } else if(strType=="2")//video { paintVideo(painter, viewOption, index); } } }
(2)以绘制案件为例,绘制按钮,状态和名称;
void TreeTaskDelegate::paintCase(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (option.state .testFlag(QStyle::State_Editing))//正在编辑状态,不绘制 { return; } QVariantMap caseinfo = index.data(Qt::UserRole).toMap(); //绘制案件的图标 QRect rectItem = option.rect; QIcon icon(":/analysisCenter/Resources/analysisCenter/caseicon.svg"); // 替换为你的图标路径 QRect iconRect(rectItem.x() + 20, rectItem.y() + 8, 24, 24); // 设置图标大小和位置 icon.paint(painter, iconRect); if (caseinfo.contains("editing"))//编辑状态,不绘制 { return; } QRect nameRect; QStyleOptionButton buttonOption; buttonOption.features = QStyleOptionButton::Flat; buttonOption.state |= QStyle::State_Enabled; if (option.state.testFlag(QStyle::State_MouseOver)) //鼠标hover { QRect rectTop = QRect(rectItem.x() + 75, rectItem.y() + 8, 24, 24); QRect rectEdit = QRect(rectItem.x() + 95, rectItem.y() + 8, 24, 24); QRect rectCreateDir = QRect(rectItem.x() + 125, rectItem.y() + 8, 24, 24); QRect rectInput = QRect(rectItem.x() + 155, rectItem.y() + 8, 24, 24); QRect rectDelete = QRect(rectItem.x() + 185, rectItem.y() + 8, 24, 24); nameRect = QRect(rectItem.x() + 44, rectItem.y() + 8, 20, 24); if (caseinfo.contains("top")&&caseinfo.value("top").toString()=="1") { buttonOption.state |= QStyle::State_On; // 设置为选中状态,取消置顶图标 } else { buttonOption.state |= QStyle::State_Off; // 设置为选中状态,置顶图标 } buttonOption.rect = rectTop; m_pbTop.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbTop);//绘制创建文件夹 buttonOption.state = QStyle::State_Enabled; buttonOption.rect = rectEdit; m_pbEditName.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbEditName);//绘制创建文件夹 buttonOption.rect = rectCreateDir; m_pbCreateFold.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbCreateFold);//绘制创建文件夹 buttonOption.rect = rectInput; m_pbInput.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbInput);//绘制导入按钮 buttonOption.rect = rectDelete; m_pbDelete.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbDelete);//绘删除按钮 } else { nameRect = QRect(rectItem.x() + 44, rectItem.y() + 8, 120, 24); } if (caseinfo.contains("TasksStatistic")) { TasksStatistic statstic = caseinfo.value("TasksStatistic").value<TasksStatistic>(); QString strColor = ""; if ((statstic.unfinished + statstic.finished + statstic.failed) != 0) { QString strState = ""; if (statstic.unfinished == 0) { strColor = "#2080F7"; strState="已完成"; } else { strColor = "#09D245"; strState = "解析中"; } if (strColor!="") { painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(QPen(QColor(strColor), 1, Qt::SolidLine, Qt::RoundCap)); painter->setBrush(QBrush(QColor(strColor), Qt::SolidPattern)); //绘圆 painter->drawEllipse(rectItem.x() + 210 + 3, rectItem.y() + 17, 6, 6); painter->restore(); } QRect rectState = QRect(rectItem.x() + 210, rectItem.y() + 10, 54, 20); buttonOption.rect = rectState; m_pbState.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbState);//绘制区域按钮 QFont font; font.setPixelSize(12); painter->save(); painter->setFont(font); QRect rectText(rectItem.x() + 210+10, rectItem.y() + 10, 54, 20); painter->drawText(rectText, Qt::AlignLeft | Qt::AlignVCenter, strState); painter->restore(); } } paintName(painter, nameRect, caseinfo.value("name").toString()); //painter->drawText(nameRect, Qt::AlignLeft|Qt::AlignVCenter, caseinfo.value("name").toString()); }
(3)按钮m_pbTop等是代理中定义的QPushButton对象;要设置按钮的图标样式
m_pbTop.setStyleSheet(QLatin1String("QPushButton:checked\n" "{\n" "background-image: url(:/analysisCenter/Resources/analysisCenter/canceltop-nor.svg) no-repeat center center;\n" "background-repeat:no-repeat;\n" "background-color: Transparent;\n" "}\n" "QPushButton:checked:hover\n" "{\n" "background-image: url(:/analysisCenter/Resources/analysisCenter/canceltop-nor.svg) no-repeat center center;\n" "background-repeat:no-repeat;\n" "background-color: Transparent;\n" "}\n" "QPushButton\n" "{\n" "background-image: url(:/analysisCenter/Resources/analysisCenter/top-nor.svg) no-repeat center center;\n" "background-repeat:no-repeat;\n" "background-color: Transparent;\n" "}\n" "QPushButton:hover\n" "{\n" "background-image: url(:/analysisCenter/Resources/analysisCenter/top-nor.svg) no-repeat center center;\n" "background-repeat:no-repeat;\n" "border-style: flat;\n" "background-color: rgba(0,0,0,0.20);\n" "}\n" ""));
这样就可以实现按钮的绘制和布局;但是按钮绘制好以后,点击还是无响应的,需要自行实现按钮的点击信号和响应函数;
看下一篇如何实现按钮的鼠标移动点击响应;
(1)重写paint函数,根据type类型绘制案件、文件夹、监控点、视频任务;
为了实现不同的item的样式,需要继承QStyledItemDelegate类型实现TreeTaskDelegate。重写paint函数,根据不同的类型type去绘制不同的按钮和状态;
voidTreeTaskDelegate::paint(QPainter *painter, constQStyleOptionViewItem &option, constQModelIndex &index) const
{
if (painter == nullptr || !index.isValid())
{
return;
}
if (option.state&QStyle::State_Editing)
{
return;
}
if (index.flags())
{
}
QFontgfont;
gfont.setFamily("Microsoft YaHei UI");
gfont.setPixelSize(16);
painter->setFont(gfont);
QStyleOptionViewItemviewOption(option);
initStyleOption(&viewOption, index);
if (option.state.testFlag(QStyle::State_HasFocus))
viewOption.state=viewOption.state^QStyle::State_HasFocus;
QStyledItemDelegate::paint(painter, viewOption, index);
QVariantMapvar = index.data(Qt::UserRole).toMap();
if (var.contains("type"))
{
QStringstrType = var.value("type").toString();
if (strType=="0")//case
{
paintCase(painter, viewOption, index);
}
elseif (strType=="1")//folder
{
paintFolder(painter, viewOption, index);
}
elseif (strType=="3")//camera
{
paintCamera(painter, viewOption, index);
}
elseif(strType=="2")//video
{
paintVideo(painter, viewOption, index);
}
}
}
(2)以绘制案件为例,绘制按钮,状态和名称;
voidTreeTaskDelegate::paintCase(QPainter *painter, constQStyleOptionViewItem &option, constQModelIndex &index) const
{
if (option.state .testFlag(QStyle::State_Editing))//正在编辑状态,不绘制
{
return;
}
QVariantMapcaseinfo = index.data(Qt::UserRole).toMap();
//绘制案件的图标
QRectrectItem = option.rect;
QIconicon(":/analysisCenter/Resources/analysisCenter/caseicon.svg"); // 替换为你的图标路径
QRecticonRect(rectItem.x() + 20, rectItem.y() + 8, 24, 24); // 设置图标大小和位置
icon.paint(painter, iconRect);
if (caseinfo.contains("editing"))//编辑状态,不绘制
{
return;
}
QRectnameRect;
QStyleOptionButtonbuttonOption;
buttonOption.features=QStyleOptionButton::Flat;
buttonOption.state|=QStyle::State_Enabled;
if (option.state.testFlag(QStyle::State_MouseOver)) //鼠标hover
{
QRectrectTop = QRect(rectItem.x() + 75, rectItem.y() + 8, 24, 24);
QRectrectEdit = QRect(rectItem.x() + 95, rectItem.y() + 8, 24, 24);
QRectrectCreateDir = QRect(rectItem.x() + 125, rectItem.y() + 8, 24, 24);
QRectrectInput = QRect(rectItem.x() + 155, rectItem.y() + 8, 24, 24);
QRectrectDelete = QRect(rectItem.x() + 185, rectItem.y() + 8, 24, 24);
nameRect=QRect(rectItem.x() + 44, rectItem.y() + 8, 20, 24);
if (caseinfo.contains("top")&&caseinfo.value("top").toString()=="1")
{
buttonOption.state|=QStyle::State_On; // 设置为选中状态,取消置顶图标
}
else
{
buttonOption.state|=QStyle::State_Off; // 设置为选中状态,置顶图标
}
buttonOption.rect=rectTop;
m_pbTop.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbTop);//绘制创建文件夹
buttonOption.state=QStyle::State_Enabled;
buttonOption.rect=rectEdit;
m_pbEditName.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbEditName);//绘制创建文件夹
buttonOption.rect=rectCreateDir;
m_pbCreateFold.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbCreateFold);//绘制创建文件夹
buttonOption.rect=rectInput;
m_pbInput.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbInput);//绘制导入按钮
buttonOption.rect=rectDelete;
m_pbDelete.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbDelete);//绘删除按钮
}
else
{
nameRect=QRect(rectItem.x() + 44, rectItem.y() + 8, 120, 24);
}
if (caseinfo.contains("TasksStatistic"))
{
TasksStatisticstatstic = caseinfo.value("TasksStatistic").value<TasksStatistic>();
QStringstrColor = "";
if ((statstic.unfinished + statstic.finished + statstic.failed) != 0)
{
QStringstrState = "";
if (statstic.unfinished == 0)
{
strColor="#2080F7";
strState="已完成";
}
else
{
strColor="#09D245";
strState="解析中";
}
if (strColor!="")
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setPen(QPen(QColor(strColor), 1, Qt::SolidLine, Qt::RoundCap));
painter->setBrush(QBrush(QColor(strColor), Qt::SolidPattern));
//绘圆
painter->drawEllipse(rectItem.x() + 210 + 3, rectItem.y() + 17, 6, 6);
painter->restore();
}
QRectrectState = QRect(rectItem.x() + 210, rectItem.y() + 10, 54, 20);
buttonOption.rect=rectState;
m_pbState.style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, &m_pbState);//绘制区域按钮
QFontfont;
font.setPixelSize(12);
painter->save();
painter->setFont(font);
QRectrectText(rectItem.x() + 210+10, rectItem.y() + 10, 54, 20);
painter->drawText(rectText, Qt::AlignLeft|Qt::AlignVCenter, strState);
painter->restore();
}
}
paintName(painter, nameRect, caseinfo.value("name").toString());
//painter->drawText(nameRect, Qt::AlignLeft|Qt::AlignVCenter, caseinfo.value("name").toString());
}
按钮m_pbTop是QPushButton对象;要设置按钮的图标样式
//案件的按钮
m_pbTop.setStyleSheet(QLatin1String("QPushButton:checked\n"
"{\n"
"background-image: url(:/analysisCenter/Resources/analysisCenter/canceltop-nor.svg) no-repeat center center;\n"
"background-repeat:no-repeat;\n"
"background-color: Transparent;\n"
"}\n"
"QPushButton:checked:hover\n"
"{\n"
"background-image: url(:/analysisCenter/Resources/analysisCenter/canceltop-nor.svg) no-repeat center center;\n"
"background-repeat:no-repeat;\n"
"background-color: Transparent;\n"
"}\n"
"QPushButton\n"
"{\n"
"background-image: url(:/analysisCenter/Resources/analysisCenter/top-nor.svg) no-repeat center center;\n"
"background-repeat:no-repeat;\n"
"background-color: Transparent;\n"
"}\n"
"QPushButton:hover\n"
"{\n"
"background-image: url(:/analysisCenter/Resources/analysisCenter/top-nor.svg) no-repeat center center;\n"
"background-repeat:no-repeat;\n"
"border-style: flat;\n"
"background-color: rgba(0,0,0,0.20);\n"
"}\n"
""));
这样就可以实现按钮的绘制和布局;但是按钮绘制好以后,点击还是无响应的,需要自行实现按钮的点击信号和响应函数; 标签:24,QRect,QTreeView,QStyle,buttonOption,rectItem,QStyledItemDelegate,painter,图标 From: https://www.cnblogs.com/bclshuai/p/18414275