当前位置: 首页 > news >正文

太原建站培训室内装修设计图纸

太原建站培训,室内装修设计图纸,房地产开发公司简介范文大全,linux 网站目录权限设置0 环境 Windows 11Qt 5.15.2 MinGW x64 1 系列文章 简介#xff1a;本系列文章#xff0c;是以纯代码方式实现 Qt 控件的重构#xff0c;尽量不使用 Qss 方式。 《[Qt]QListView 重绘实例之一#xff1a;背景重绘》 《[Qt]QListView 重绘实例之二#xff1a;列表项覆…0 环境 Windows 11Qt 5.15.2 MinGW x64 1 系列文章 简介本系列文章是以纯代码方式实现 Qt 控件的重构尽量不使用 Qss 方式。 《[Qt]QListView 重绘实例之一背景重绘》 《[Qt]QListView 重绘实例之二列表项覆盖的问题处理》 《[Qt]QListView 重绘实例之三滚动条覆盖的问题处理》 《[Qt]QListView 重绘实例之四效果一讲解》 《[Qt]QListView 重绘实例之四效果二讲解》 2 问题开始 继上文《之一》绘制圆角矩形背景时遗留了两个主要问题 列表项覆盖破坏背景效果滚动条覆盖破坏背景效果 其中对于滚动条的问题留作下一文《之三》讲解。参考《[Qt]QListView 重绘实例之三滚动条的处理》。 本文先解决列表项覆盖的问题。 至少有两个思路解决列表项的覆盖问题 使用委托。如子类化 QItemDelegate然后进行列表项的重绘使用代理样式。如子类化 QProxyStyle然后进行列表项的重绘 本文选择第二种思路原因有二 其一承接上文《之一》已经使用了子类化 QProxyStyle 的方法继续实现对列表项的重绘功能即可没有必要再另外添加一个新委托子类实现其二样式 QStyle /代理样式 QProxyStyle本身即包含委托实现的功能。而且它们更多强大可以对某类或全局样式进行控件 具体的重绘过程分为两个部分 对于视口最上行/最下行需要处理上半部分/下半部分的圆角绘制对于视口的其它中间行则进行默认绘制或按期望样式绘制 →→→ 解决方案直达 ←←← 3 重绘列表项背景 代理样式中与列表项相关的主要有一个样式类和两个元素类型 样式类QStyleOptionViewItem元素类型 QStyle::CE_ItemViewItem - void drawControl() constQStyle::PE_PanelItemViewItem - void drawPrimitive() const Qt 文档关于 QStyle 类有如下说明 Styles in Item Views … The primitive element PE_PanelItemViewItem is responsible for painting the background of items, and is called from QCommonStyle’s implementation of CE_ItemViewItem. 译QCommonStyle 子类实现中的控制类型 CE_ItemViewItem 会调用原始类型 PE_PanelItemViewItem其中原始类型 PE_PanelItemViewItem 负责绘制列表项的背景。 … 即在 QStyle::PE_PanelItemViewItem 中绘制列表项的背景在 QStyle::CE_ItemViewItem 中绘制列表项的内容。 3.1 保存视口大小信息 Qt 明确说明 QListView 是垂直型的列表。 首先需要判断视口中的最上/最下行位置。而判断位置则需要知道整个列表的高度。具体实现是在绘制 QFrame 时保存数据。 /* .h */ class PListViewStyle : public QListView { public:// ... private:mutable QRect mRect; // Need mutable }/* .cpp */ void PListViewStyle::drawControl(QStyle::ControlElement element,const QStyleOption *option,QPainter *painter,const QWidget *widget) const {switch(element){case QStyle::CE_ShapedFrame:{const QStyleOptionFrame *opt qstyleoption_castconst QStyleOptionFrame *(option);if(nullptr opt) { return; }mRect opt-rect;//...return;}default:break;}QProxyStyle::drawControl(element, option, painter, widget); }注意变量 mRect 必须使用 mutable 修饰。 3.2 判断视口中的最上/最下行位置 判断视口中的最上行位置 if(0 opt-rect.y())如果没有设置内填充最上行位置的 y 坐标应该等于 0因此使用此条件进行判断。 判断视口中的最下行位置 bool PListViewStyle::isLastRow(const QRect rect, int rowHeight) const {/* 列表可显示行数 */int rowCount mRect.height() / rect.height();/* 由 y 坐标与行高计算行索引 */int index rect.y() / rect.height();if(rowCount index){rowHeight mRect.height() - index * rect.height();return true;}return false; }3.3 绘制列表项背景 /* 添加常量定义需要添加到 cpp 文件开头位置 */ const int Radius 15;void PListViewStyle::drawPrimitive(QStyle::PrimitiveElement element,const QStyleOption *option,QPainter *painter,const QWidget *widget) const {switch(element){/* PE_PanelItemViewItem 主要负责绘制列表项的背景选中背景/高亮背景*/case QStyle::PE_PanelItemViewItem:{const QStyleOptionViewItem *opt qstyleoption_castconst QStyleOptionViewItem *(option);if(nullptr opt) { break; }QColor c(Qt::lightGray);if(QStyle::State_MouseOver opt-state){c QColor(0, 0, 255, 255 * 0.2);}else if(QStyle::State_Selected opt-state){c QColor(0, 0, 255, 255 * 0.5);}int x, y, w, h;opt-rect.getRect(x, y, w, h);QPainterPath path;int rowHeight 0;/* 最上一行 */if(0 y){/* 创建最上一行带圆的角矩形路径 */path.moveTo(x, y h);path.arcTo(QRect(x, y, 2 * Radius, 2 * Radius), 180, -90);path.lineTo(x w, y);path.lineTo(x w, y h);path.closeSubpath();}/* 最下一行 */else if(isLastRow(opt-rect, rowHeight)){/* 创建最下一行带圆角的矩形路径 */path.moveTo(x, y);path.lineTo(x w, y);path.lineTo(x w, y rowHeight);path.arcTo(QRect(x, y rowHeight - 2 * Radius, 2 * Radius, 2 * Radius), 270, -90);path.closeSubpath();}else{path.addRect(QRect(x, y, w, h));}painter-save();painter-setRenderHint(QPainter::Antialiasing);painter-setPen(Qt::NoPen);painter-setBrush(QBrush(c));painter-drawPath(path);painter-restore();return;}default:break;}QProxyStyle::drawPrimitive(element, option, painter, widget); }为了显示绘图的效果这里特地将列表项的默认白色背景改成了浅灰色。 其中的重点是对视口最上行和最下行进行了圆角处理通过 QPainterPaht 实现。 效果图如下 从上图中可以看到绘制列表项的圆角效果确实出来了高亮效果也正确。说明至少这样的处理方案没有问题。 但是还是发现背景上有一个白色直角矩形仍然破坏了圆角矩形背景。 这也同样说明这个白色直角矩形并不是由于列表项产生的影响。 3.4 视口 viewport() 好了现在问题好像又回到 QListView 的里层了。 很明显列表项应该是表层的因为用户是可以直接看到的。 接下来结合上一文《之一》的内容来看一下以下这张图。 这里有一个层级关系 最底层QFrame。在《之一》中使用 paintEvent() 进行重绘时正是设置的这个直接设置成了 QFrame::NoFrame上一层viewpotr()。在《之一》中也验证过这点而且viewport() 区域是不包含滚动条的。如上图中列表项底下的白色矩形最上层列表项。上文已有说明。 现在基本上可以确定问题应该聚焦在 viewport() 上。 查看 Qt 帮助文档与视口相关的有两个接口 QWidget *QAbstractScrollArea::viewport() const; void QAbstractScrollArea::setViewport(QWidget *widget);可知视口即是一个 QWidget 控件。 那么再来验证一下重新设置视口控件然后设置其背景色为蓝色 PListView::PListView(QWidget *parent) : QListView(parent) {auto *widget new QWidget;widget-setStyleSheet(background: blue);setViewport(widget); }效果图如下 由此可知确认了之前的推论。 补充内容 解决方法只需要一条语句setViewport(new QWidget)而且做过一些深入的尝试但没有理解具体的原因。 既然视口是一个 QWidget那么对 QWidget 进行绘制是不是应该也可以当作背景使用实际上的情况是子类化 QWidget 后重写 paintEvent() 方法再设置为新的视口控件重绘函数根本不会被调用。经实测可以改变这个视口控件的方式只有通过设置 Qss 才有效。也没明白是为什么。然后设置 QWidget 对象为新的视口控件该对象的调色板或者说对象样式是会影响列表项的默认样式的。例如 QWidget 通过 Qss 设置背景颜色为蓝色则列表项的默认背景色也会变为蓝色。当然这也可能是 Qss 设置影响了子对象。 此外之所以只要设置一个默认的 QWidget 对象作为新视口即可猜测原因是默认 QWidget 本身是一个透明的或者是统一风格背景色的控制在 QListView 中即表现为透明的一层所以不会影响圆角背景的效果。 虽然实际原因不知但能解决问题。 4 解决方案 添加新的视口控件 PListView::PListView(QWidget *parent) : QListView(parent) {setViewport(new QWidget);setFrameStyle(QFrame::NoFrame); // Must//... }绘制列表项背景 void PListViewStyle::drawPrimitive(QStyle::PrimitiveElement element,const QStyleOption *option,QPainter *painter,const QWidget *widget) const {switch(element){/* PE_PanelItemViewItem 主要负责绘制列表项的背景以及选中背景/高亮背景 */case QStyle::PE_PanelItemViewItem:{const QStyleOptionViewItem *opt qstyleoption_castconst QStyleOptionViewItem *(option);if(nullptr opt) { break; }QColor c(Qt::white); /* 默认背景色 */if(QStyle::State_MouseOver opt-state){c QColor(0, 0, 255, 255 * 0.2);}else if(QStyle::State_Selected opt-state){c QColor(0, 0, 255, 255 * 0.5);}int x, y, w, h;opt-rect.getRect(x, y, w, h);QPainterPath path;int rowHeight 0;/* 最上一行 */if(0 y){/* 创建最上一行带圆角的矩形路径 */path.moveTo(x, y h);path.arcTo(QRect(x, y, 2 * Radius - 5, 2 * Radius - 5), 180, -90);path.lineTo(x w, y);path.lineTo(x w, y h);path.closeSubpath();}/* 最下一行 */else if(isLastRow(opt-rect, rowHeight)){/* 创建最下一行带圆角的矩形路径 */path.moveTo(x, y);path.lineTo(x w, y);path.lineTo(x w, y rowHeight);path.arcTo(QRect(x, y rowHeight - 2 * Radius, 2 * Radius, 2 * Radius), 270, -90);path.closeSubpath();}else{path.addRect(QRect(x, y, w, h));}painter-save();painter-setRenderHint(QPainter::Antialiasing);painter-setPen(Qt::NoPen);painter-setBrush(QBrush(c));painter-drawPath(path);painter-restore();return;}default:break;}QProxyStyle::drawPrimitive(element, option, painter, widget); }最后来看一下效果图达到了预期的效果目标。
http://www.dnsts.com.cn/news/151558.html

相关文章:

  • 机械外贸网站搜狗网站做滤芯怎么样
  • 游戏门户网站建设dede网站地图地睛
  • 建设网站花都郑州网站seo外包公司
  • 新八建设集团网站凡科代理建站登录
  • 网站建设要会什么软件融资网站建设方案
  • 个人建站程序建设部网站证件查询
  • 各大网站大全徐州网站建设方案咨询
  • 如何编辑自己的网站网络公司 给 客户网站备案
  • 做网站平台需要多少钱惠州seo推广优化
  • 长春专业网站建设哪家口碑好网站界面设计ps
  • 企业企业网站建设绵阳网站建设怎么做
  • 合肥怎么做网站湖南平台网站建设设计
  • 网站开发者收入来源自助建站基础工作主要包括()
  • 南通建设工程造价信息网站设计出色的网站
  • 灵山建设局网站网站做专题页面
  • 注册域名之后怎么建网站做网站建设公司哪家好
  • 美丽说网站代码与蘑菇街网站代码是用什么网站语言做的我是做颗粒在什么网站上
  • wordpress网站正在建设中贵州公司网站建设比选公示
  • 视频网站 外链手机网站生成app
  • 工程门户网站建设浏览器主页被篡改2345
  • 找人做网站上线后被投诉侵权亿码酷网站建设
  • 网站上的充值链接怎么做崇州市建设局网站
  • 邯郸网站建设服务报价有限公司简介
  • 泰安网站建设公司带深圳保障性住房和公租房区别
  • 网站建设佰金手指科捷一小程序开发官网
  • 专业网站是什么如何联系网站管理员
  • 成都网站建设cdcidi宜兴专业做网站公司
  • 网站制作哪个好薇商务网站规划与建设心得
  • 收费的网站怎么做的asp开源企业网站教程
  • 阳朔县建设规划局网站用vs2012做网站