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

建立网站的费用策划广州番禺区好玩的景点

建立网站的费用策划,广州番禺区好玩的景点,中航建设集团有限公司网站,网站建设需要哪些工作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 控件无外乎两个主要目的 实现更漂亮的样式实现更强大的/更合适的功能 要实现以上两个主要目的基本上都需要对 Qt 原生控件进行一定的重绘以适应需求。 本节中主要讲解 QListView 的背景绘制。 之所以单独写一文是因为自己动手实现时才发现虽然最后的实现代码并不多但要弄懂这些还是要花费很多精力的。 → 解决方案直达 ← 3 paintEvent 重绘与问题 通常重构一个新控件基本上都是直接重写 void paintEvent(QPaintEvent *event) 方法。 void PListView::paintEvent(QPaintEvent *event) {Q_UNUSED(event)QPainter painter(this); // Errorpainter.setRenderHint(QPainter::Antialiasing);painter.setPen(QPen(Qt::red));painter.setBrush(QBrush(Qt::white));painter.drawRoundedRect(rect(), 5, 5); }3.1 问题 1 —— 绘图对象 通常进行重绘时新建 QPainter 对象都是以父控件为对象意即在父控件中进行绘制。 但是如果这样直接对 QListView 进行重绘是会出错的 QWidget::paintEngine: Should no longer be called QPainter::begin: Paint device returned engine 0, type: 1 QPainter::setRenderHint: Painter must be active to set rendering hints QPainter::setPen: Painter not active QPainter::setBrush: Painter not active猜测原因大致应该是QListView 是由多个子控件组成实际负责显示内容的只是其中的一个子控件所以绘制对象需要具体指定到负责显示的对象。 QListView 继承树如下 而一个默认 QListView 对象包含的子控件如下 (QWidget(0x1eb4600, name qt_scrollarea_viewport), QStyledItemDelegate(0x1eb1840), QItemSelectionModel(0x1eb1ba0), QWidget(0x1eb1010, name qt_scrollarea_hcontainer), QWidget(0x1eb1150, name qt_scrollarea_vcontainer))其中实际显示内容的对象就是 “qt_scrollarea_viewport”也就是 QListView 的视口viewport。这样做的主要原因是要实现对 QListView 内容的滚动显示显示部分内容。 所以对于 QListView 重绘必须要针对视口 viewport()。 void PListView::paintEvent(QPaintEvent *event) {Q_UNUSED(event)QPainter painter(viewport());painter.setRenderHint(QPainter::Antialiasing);painter.setPen(QPen(Qt::red));painter.setBrush(QBrush(Qt::white));painter.drawRoundedRect(rect(), 5, 5); }效果如下图示 3.2 问题 2 —— 外边线框 从上图看这次倒是绘制出背景框。但首先注意到的问题是 QListView 默认外连线框非常显眼。因此首要目的是要去掉这个外连线框。 上文实现代码中的重绘过程仅做了两件事 绘制了一个圆角矩形阻止了 QListView 的其它默认绘制 因此 基本可以肯定外连线框并不是由 paintEvent() 绘制过程中引起的。看来原因得到 QListView 里层查找。 原因查找的具体过程略过不述QListView 的外边线框其实就是其父类 QFrame 的边框可以理解为一个底层其它内容都绘制在这个底层之上毕竟 QListView 是 UI 控件。 只需要对 QListView 进行如下设置改变一下 QFrame 样式即可去掉外边线框 PListVeiw::PListView(QWidget *parent) : QListView(parent) {setFrameStyle(QFrame::NoFrame); }效果如下 强制隐藏/关闭垂直滚动条效果如下 3.3 问题 3 —— 绘制区域 从上图可知绘制的背景效果基本出来了。但是也被垂直滚动条挡住了一部分。 再回来看一看绘图代码其中有一行如下 painter.drawRoundedRect(rect(), 5, 5);此时指定的绘图区域为 rect()即针对控件的整个显示区域。而我们指定的绘图对象是 QListView 的视口原则上为了保证一致性在什么上绘图就应该在该对象的区域内进行绘制。所以修改以上那行的代码 painter.drawRoundedRect(viewport()-rect(), 5, 5);效果如下 这种效果也还可以。一些样式也确实是将滚动条置于控件之外的。 本文不针对此样式进行讲解主要考虑滚动条内含在列表内的样式。 滚动条的问题先按下不提具体详见本系列后文说明。参考《[Qt]QListView 重绘实例之三滚动条覆盖的问题处理》。 3.4 问题 4 —— 滚动时残留 先前为了重点显示 QListView 的背景绘制效果所以没有绘制 QListView 的内容。 现在加上内容的绘制代码 void PListView::paintEvent(QPaintEvent *event) {QPainter painter(viewport());painter.setRenderHint(QPainter::Antialiasing);painter.setPen(QPen(Qt::red));painter.setBrush(QBrush(Qt::white));painter.drawRoundedRect(rect(), 5, 5); // 理解为视口占据整个控件区域QListView::paintEvent(event); }说明绘制顺序是有要求的。应该先绘制背景然后绘制列表内容即前景。 效果图如下 但是如果我们使用鼠标滚轮滚动或拖动滚动条滚动 QListView 的内容却出现了如下效果 这显然不是想要的效果。 具体原因未深究暂时未知猜测应该是底层代码的原因。因为上文中的重绘代码其实很简单并未做多余的动作。 但这种残留效果显然不可接受。 因此至少到目前这种方式绘制 QListView 的背景是不可行的。 考虑到添加委托会对列表项进行绘制可能会影响到这个残留问题。尝试过添加委托但这个残留问题依然存在。 4 解决方案 从上文得知采用 paintEvent() 对 QListView 背景进行绘制的方案不可行。 另考虑到后来的 Qt 版本对于 Qss 的性能问题本系列也不考虑 Qss 方案。 于是已知可行的方案只剩使用 QProxyStyle 代理样式定制了。 之前也没有实际使用过代理样式通过学习/练习/测试得出了合适的效果。 关于 QProxyStyle 的具体内容查找资料的过程中有发现有不少介绍的好博文请酌情参考文末参考资料有链接本文不另述。 4.1 定义背景绘制样式 /* .h */ class PListViewStyle : public QProxyStyle { public:PListViewStyle();void drawControl(QStyle::ControlElement element,const QStyleOption *option,QPainter *painter,const QWidget *widget nullptr) const override; };/* .cpp */ PListViewStyle::PListViewStyle() { } 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; }painter-save();painter-setRenderHint(QPainter::Antialiasing);painter-setPen(QPen(Qt::red));painter-setBrush(QBrush(Qt::white));painter-drawRoundedRect(opt-rect, 5, 5);painter-restore();return;}default:break;}QProxyStyle::drawControl(element, option, painter, widget); }4.2 使用代理样式 PListVeiw::PListView(QWidget *parent) : QListView(parent) {// setFrameStyle(QFrame::NoFrame); // Must delete or comment itsetStyle(new PListViewStyle); }注意 需要删除重写函数 void paintEvent(QPaintEvent *event)否则可能覆盖效果。需要删除对 QFrame 的样式设置不能再设置为 QFrame::NoFrame。因为代理样式实际是对 QFrame 进行绘制的如果设置了 QFrame::NoFrame则绘制的样式根本就不会显示。 效果如下 至少看上去基本达到了预期的效果。 但是 但是 但是总有但是哈哈。 将背景的圆角矩形圆角半径加大一下再来看看效果图 从上图可以看出有几个问题 列表项在背景的上层即背景绘制先于列表项。而列表项也是有背景的以及高亮/选中背景可以理解为列表项就是一个个小矩形默认没有圆角。由上可以看出视口的最上/最下一行都有矩形直角覆盖了背景圆角矩形因此破坏了背景的效果同理滚动条也在背景上层滚动条也是一个直角矩形矩形直角覆盖了背景因此也破坏了背景的效果 其中 对于列表项产生的覆盖问题可以通过使用委托控制列表项背景默认背景/高亮背景/选中背景的绘制使绘制视口最上/最下一行时绘制合适的圆角效果。对于滚动条的问题就复杂得多具体详见本系列后文内容。参考《[Qt]QListView 重绘实例之三滚动条覆盖的问题处理》。 5 参考资料 《C GUI Qt 4编程第二版》第 19 章19.2 子类化 QStyleQStyle类用法总结一绘制自定义QSlider
http://www.w-s-a.com/news/732354/

相关文章:

  • 郑州建设网站哪家好东莞网络公司排行榜
  • 成都网站开发费用做行程的网站
  • 做地铁建设的公司网站手机网站首页布局设计
  • 福建亨立建设集团有限公司网站搜狗网页游戏大厅
  • 设计网站musil访问量大的网站选择多少流量的服务器何时
  • 公司网站包括哪些内容新网站怎样做外链
  • 淘宝宝贝链接怎么做相关网站广州好蜘蛛网站建设
  • 长春网站制作网页博山区住房和城乡建设局网站
  • 云南大学网站建设解析到网站怎样做
  • 网站维护的要求包括锦溪网站建设
  • 金站网.营销型网站学校安全教育网站建设
  • 临沂市建设局网站公示军事新闻头条2023
  • 购物网网站建设lamp 做网站
  • 做网站网站庄家html5网站开发技术
  • 无锡门户网站制作电话广告设计公司的未来
  • 白云区专业网站建设网页设计模拟试题答案
  • 毕业设计网站代做多少钱制作旅游网站设计概述
  • 网站开发维护运维无人在线电视剧免费观看
  • 电子商务网站建设开题报告展馆网站建设
  • 门户网站建设的背景和意义手机网站前
  • 国内免费视频素材无水印素材网站国家最新消息
  • 襄阳seo站内优化学做网站论坛教程
  • 文明网站建设情况报告wordpress伪静态配置
  • 牙科网站模板个人微信网站建设
  • 厦门公司注册网站dw做简单小说网站
  • 网站建好以后每年都续费么wordpress 仿聚划算
  • 单位网站建设收费标准网上开店铺需要多少钱
  • 灯饰网站需要这么做申请域名的流程
  • 软件下载网站怎么赚钱wordpress减少数据库查询
  • 什么兼职网站可以做视频剪辑常见的推广平台有哪些