垫江网站建设,网页界面设计教程视频,天津泰达建设集团有限公司网站,建设一个充电站需要多少钱QWidget窗口抗锯齿圆角的一个实现方案#xff08;支持子控件#xff09;2
本方案使用了QGraphicsEffect#xff0c;由于QGraphicsEffect对一些控件会有渲染问题#xff0c;比如列表、表格等#xff0c;所以暂时仅作为研究#xff0c;优先其他方案
在之前的文章中#…QWidget窗口抗锯齿圆角的一个实现方案支持子控件2
本方案使用了QGraphicsEffect由于QGraphicsEffect对一些控件会有渲染问题比如列表、表格等所以暂时仅作为研究优先其他方案
在之前的文章中支持子控件的抗锯齿圆角方案对于独立弹窗的抗锯齿圆角使用一层遮罩来实现对窗口内容的裁切。
在很早之前还考虑过另外一种方案既然QGraphicsEffect能够对控件进行一些特效处理那自定义QGraphicsEffect也应该可以做到对内容裁剪。但当时仅在QComboBox下拉列表上进行了测试没有达到预期实际可能是Qt内部的bug甚至导致了我对QGraphicsEffect原理的误解。
直接说方案。
方案
重写一个QGraphicsEffect照着其他Qt提供的类重写QGraphicsEffect::draw接口。 简单来说就是通过混合模式对sourcePixmap进行圆角位置的像素清除支持抗锯齿
void draw(QPainter *painter)
{// 一些Qt的逻辑QPoint offset;Qt::CoordinateSystem system sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;QPixmap pixmap sourcePixmap(system, offset, QGraphicsEffect::NoPad);if (pixmap.isNull())return;painter-save();QPainter pixmapPainter(pixmap);pixmapPainter.setRenderHints(QPainter::Antialiasing); // 打开抗锯齿pixmapPainter.setPen(Qt::NoPen);pixmapPainter.setBrush(Qt::red); //颜色不重要非透明即可pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationOut); // 混合模式达到清楚圆角部分像素目的QPainterPath path;// _target是目标QWidget可以通过构造函数自己保存// 区域增大一点避免边界有残留path.addRect(QRect(QPoint(0, 0), _target-size()).adjusted(-1, -1, 1, 1));path.addRoundedRect(QRect(QPoint(0, 0), _target-size()), 20, 20);// 一些Qt的绘制逻辑if (system Qt::DeviceCoordinates) {QTransform worldTransform painter-worldTransform();worldTransform * QTransform::fromTranslate(-offset.x(), -offset.y());pixmapPainter.setWorldTransform(worldTransform);} else {pixmapPainter.translate(-offset);}pixmapPainter.drawPath(path);pixmapPainter.end();painter-setWorldTransform(QTransform());painter-drawPixmap(offset, pixmap);painter-restore();
};上述代码里包含Qt的一些代码逻辑没有具体研究过差异。
设置给目标控件即可 下拉框动画过程中会存在一些黑色像素可以关闭动画。主要还是建议在相对静态的控件中使用。
结论
个人理解Qt的QGraphicsEffect里有相当多的问题较早的版本可能对窗口的子控件无效后期增加了对子控件的统一渲染支持直到Qt6.4应该是这个版本解决了大部分问题但对于像列表、表格等存在脏区域优化的控件仍然存在渲染问题。