QStyle实现自绘界面项目实战(二)

QT界面美化之QStyle  转贴: http://www.cppblog.com/umbcom/QT中的QStyle类提供了对QT应用程序界面的封装,QT本身也是利用它应对不同平台下的界面外观的。例如 在windowxp下 你所写的程序的默认外观是通过QT自身调用QWindowsXPStyle来实现的.既然它提供了这么方便的类用来绘制独立于应用程序功能框架的程序外观,那想对自己程序的界面进行美化人,你确实很有必要去 阅读详情

1.前言     

QT自绘技术系列文章链接如下: 

  1.  《QStyle类用法总结(一)》。对Qt自定义风格简单描述,对QStyle及其相关类作了概念性的描述。
  2. 《QStyle类用法总结(二)》。对QStyle及其相关类作了详细描述。
  3. 《QStyle类用法总结(三)》。对QStyle中的各widget元素的层次继承树做了详细描述。
  4. 《QProxyStyle用法简述》。通过一个简单的例子,演示了QProxyStyle类用法。
  5. 《QStyle实现自绘界面项目实战(一)》通过项目实战来理解前几篇提到的内容,理解QStyle及其子类在自绘时的工作机制。
  6. 《QStyle实现自绘界面项目实战(二)》通过项目实战来理解前几篇提到的内容,理解QStyle及其子类在自绘时的工作机制。

在阅读本文章之前,请先阅读上述列出的相关文章,否则没有自绘基础,很难读懂本文章。

2. 工程说明

        Qt自带的例子affine中的ArthurStyle类继承自QCommonStyle,实现了绘制自定义窗体部件的功能,是学习自定义控件的好例子。

工程存放的路径在:Examples\Qt-XX.XX.XX\widgets\painting\affine

其中XX.XX.XX为Qt的版本号,如:5.14.1。关于该工程和自绘、QStyle无关的有关技术知识点分析参见《Qt Examples之affine工程难点、亮点汇总》博文,本篇博文只讲该工程和自绘、QStyle有关的技术点。

3.工程分析

        本工程自绘在arthurstyle.cpp文件通过ArthurStyle类实现的。ArthurStyle类的成员函数用到PE_、CC_、SE_、PM_、CT_、SC_、CE_、开头的标识符,这些标识符分别表示什么意思,及绘制这些标识符表示的部件元素的函数drawPrimitive、drawComplexControl、drawControl用法含义,请参考:《QStyle类用法总结(二)》、《QStyle类用法总结(三)》及Qt Assist,如果不理解这些标识符含义,很难理解自绘是怎么实现的。

3.1.drawPrimitive函数

drawPrimitive函数用于绘制图形元素,即某个widget的某一部分,如:spin box中的上下箭头元素。以PE_开头的标识符表示的图形元素都是该函数绘制的。

3.1.1.case语句之PE_IndicatorRadioButton

Qt Assist对PE_IndicatorRadioButton解释如下:

 可以理解为:该标识符表示单选按钮左边用于勾选的小圆圈及小圆圈外包围矩形。该标识所在case语句如下:

case PE_IndicatorRadioButton:
        if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
            painter->save();
            QPixmap radio;
            if (hover)
                drawHoverRect(painter, widget->rect());

            if (button->state & State_Sunken)
                radio = cached(":res/images/radiobutton-on.png");
            else if (button->state & State_On)
                radio = cached(":res/images/radiobutton_on.png");
            else
                radio = cached(":res/images/radiobutton_off.png");
            painter->drawPixmap(button->rect.topLeft(), radio);

            painter->restore();
        }
        break;

第2行:程序能进入到PE_IndicatorRadioButton所在的case语句,则窗体部件必定是QRadioButton类型按钮。接下来将option通过qstyleoption_cast强制转换为QStyleOptionButton,因为此时的窗体部件肯定是一个按钮类型,这种转化肯定能成功。
第3行:如果单选按钮处于可用状态且鼠标在单选按钮上,则调用drawHoverRect函数。drawHoverRect函数绘制出鼠标在单选按钮上时呈现的圆角矩形,以便用户能从视觉感知鼠标是真的悬浮在单选框上,即如下红色框效果:

图1

 注意:传递给drawHoverRect函数的第2个参数应该是widget->rect()即整个单选按钮占据的矩形,而不是button->rect或option->rect,后者仅仅表示单选按钮左边用于勾选的小圆圈及小圆圈外包围矩形,即下面红色方框表示的矩形而不是整个单选按钮占据的矩形:

图2

如果给drawHoverRect函数的第2个参数的矩形不对,则不会出现图1的鼠标悬浮视觉冲击效果。

第9~10行:鼠标在单选按钮上按下时,用radiobutton-on.png图片构成的QPixmap对象通过drawPixmap函数绘制到图2所示的矩形上,以呈现单选按钮被按下的视觉冲击感。

第11~12行:单选按钮被勾选时,用radiobutton_on.png图片构成的QPixmap对象通过drawPixmap函数绘制到图2所示的矩形上,以呈现单选按钮被勾选的视觉冲击感。

第13~14行:单选按钮既没被勾选又没被按下时,用radiobutton_off图片构成的QPixmap对象通过drawPixmap函数绘制到图2所示的矩形上,以呈现单选按钮既没被勾选又没被按下的视觉冲击感。

3.1.2.case语句之PE_PanelButtonCommand

Qt Assist对PE_PanelButtonCommand解释如下:

                                                                  图3 

 再结合 《QStyle类用法总结(三)》博文2.2.1节对push button的描述,其实PE_PanelButtonCommand可以简单理解为就时一个QPushButton类型按钮,该标识所在case语句如下:

 if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);

            painter->save();
            const QPushButton *pushButton = qobject_cast<const QPushButton *>(widget);
            Q_ASSERT(pushButton);
            QWidget *parent = pushButton->parentWidget();
            if (parent && qobject_cast<QGroupBox *>(parent)) {
                QLinearGradient lg(0, 0, 0, parent->height());
                lg.setColorAt(0, QColor(224,224,224));
                lg.setColorAt(1, QColor(255,255,255));
                painter->setPen(Qt::NoPen);
                painter->setBrush(lg);
                painter->setBrushOrigin(-widget->mapToParent(QPoint(0,0)));
                painter->drawRect(button->rect);
                painter->setBrushOrigin(0,0);
            }

            bool down = (button->state & State_Sunken) || (button->state & State_On);

            QPixmap left, right, mid;
            if (down) {
                left = cached(":res/images/button_pressed_cap_left.png");
                right = cached(":res/images/button_pressed_cap_right.png");
                mid = cached(":res/images/button_pressed_stretch.png");
            } else {
                left = cached(":res/images/button_normal_cap_left.png");
                right = cached(":res/images/button_normal_cap_right.png");
                mid = cached(":res/images/button_normal_stretch.png");
            }
            painter->drawPixmap(button->rect.topLeft(), left);
            painter->drawTiledPixmap(QRect(button->rect.x() + left.width(),
                                           button->rect.y(),
                                           button->rect.width() - left.width() - right.width(),
                                           left.height()),
                                     mid);
            painter->drawPixmap(button->rect.x() + button->rect.width() - right.width(),
                                button->rect.y(),
                                right);
            if (hover)
                painter->fillRect(widget->rect().adjusted(3,5,-3,-5), QColor(31,127,31,63));
            painter->restore();
        }
        break;

第1行:程序能进入到PE_PanelButtonCommand所在的case语句,则窗体部件必定是QPushButton类型按钮。接下来将option通过qstyleoption_cast强制转换为QStyleOptionButton,因为此时的窗体部件肯定是一个按钮类型,这种转化肯定能成功。

第2行:如果按钮处于可用状态且鼠标在按钮上,则hover为true,否则为false。

第5~16行:通过按钮找到按钮的父控件,即按钮外面的QGroupBox,再创建一个渐变画刷来填充按钮外包围矩形button->rect。注意:button->rect坐标是相对其父QGroupBox来说的,即

button->rect是以QGroupBox的坐标系为基准的,故需要通过下句代码:

 painter->setBrushOrigin(-widget->mapToParent(QPoint(0,0)));

将画刷默认坐标原点(默认值是以按钮坐标系为基准,且在按钮的左上顶点(0,0)处)转为以QGroupBox的坐标系下的画刷坐标原点。

第19~39行:先判断按钮是否按下或勾选,根据按下或没按下,设置不同的按钮贴图。然后调用drawPixmap在按钮左边和右边把贴图贴到按钮左部分和右部分,调用drawTiledPixmap函数给按钮中间部分贴图。

第40~41行:根据第2行判断的鼠标是否在按钮上方悬浮,如果是悬浮,则调用fillRect函数,传入 QColor(31,127,31,63)画刷绘制矩形,因为颜色和没悬浮时的颜色不同,这样就可以让用户产生视觉冲击感。

3.1.3.case语句之PE_FrameGroupBox

Qt Assist对PE_FrameGroupBox解释如下:

 图4

再结合 《QStyle类用法总结(三)》博文2.2.9节对Group Box的描述,其实 PE_FrameGroupBox就是Group Box面板最外面的边框。该标识所在case语句如下:

if (const QStyleOptionFrame *group
                = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
            const QRect &r = group->rect;

            painter->save();
            int radius = 14;
            int radius2 = radius*2;
            QPainterPath clipPath;
            clipPath.moveTo(radius, 0);
            clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90);
            clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90);
            clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90);
            clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90);
            painter->setClipPath(clipPath);
            QPixmap titleStretch = cached(":res/images/title_stretch.png");
            QPixmap topLeft = cached(":res/images/groupframe_topleft.png");
            QPixmap topRight = cached(":res/images/groupframe_topright.png");
            QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png");
            QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png");
            QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png");
            QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png");
            QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png");
            QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png");
            QLinearGradient lg(0, 0, 0, r.height());
            lg.setColorAt(0, QColor(224,224,224));
            lg.setColorAt(1, QColor(255,255,255));
            painter->setPen(Qt::NoPen);
            painter->setBrush(lg);
            painter->drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0));
            painter->setClipping(false);

            int topFrameOffset = titleStretch.height()/2 - 2;
            painter->drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft);
            painter->drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0)
                                + QPoint(0, topFrameOffset), topRight);
            painter->drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft);
            painter->drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1,
                                bottomRight.height()-1), bottomRight);

            QRect left = r;
            left.setY(r.y() + topLeft.height() + topFrameOffset);
            left.setWidth(leftStretch.width());
            left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset);
            painter->drawTiledPixmap(left, leftStretch);

            QRect top = r;
            top.setX(r.x() + topLeft.width());
            top.setY(r.y() + topFrameOffset);
            top.setWidth(r.width() - topLeft.width() - topRight.width());
            top.setHeight(topLeft.height());
            painter->drawTiledPixmap(top, topStretch);

            QRect right = r;
            right.setX(r.right() - rightStretch.width()+1);
            right.setY(r.y() + topRight.height() + topFrameOffset);
            right.setWidth(rightStretch.width());
            right.setHeight(r.height() - topRight.height()
                            - bottomRight.height() - topFrameOffset);
            painter->drawTiledPixmap(right, rightStretch);

            QRect bottom = r;
            bottom.setX(r.x() + bottomLeft.width());
            bottom.setY(r.bottom() - bottomStretch.height()+1);
            bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width());
            bottom.setHeight(bottomLeft.height());
            painter->drawTiledPixmap(bottom, bottomStretch);
            painter->restore();

第1行:程序能进入到PE_FrameGroupBox所在的case语句,则窗体部件必定是PE_FrameGroupBox类型的组框边框图元。接下来将option通过qstyleoption_cast强制转换为QStyleOptionFrame,因为组框有边框,这种转化肯定能成功。

第6~14行:构建了一个类似圆角矩形的QPainterPath画图路径类对象clipPath,并将裁剪区域设置为clipPath,这样GroupBox外边框看起来就是一个圆角矩形。

第24~29行: 将GroupBox占据的包围矩形用一个渐变画刷lg绘制填充。

第32~38行: 将GroupBox占据的包围矩形四个端点所在的角用pixmap图片填充、贴图。即填充图5中的数字1部分所示区域。

第40~66行: 将GroupBox占据的包围矩形非四个端点形成的角的区域,且不是矩形主体用pixmap图片填充、贴图。即填充图5中的数字2部分所示区域。

 图5

3.2.drawComplexControl函数 

drawComplexControl函数用于绘制复杂控件,以CC开头表示的元素都是该函数绘制的。

3.2.1.case语句之CC_Slider

Qt Assist对CC_Slider解释如下:

                     图6 

再结合 《QStyle类用法总结(三)》博文2.2.5节对Slider的描述,其实 CC_Slider就是Group 整个QSlider控件。该标识所在case语句如下: 

case CC_Slider:
        if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
            QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
            QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);

            painter->save();

            bool hover = (slider->state & State_Enabled) && (slider->state & State_MouseOver);
            if (hover) {
                QRect moderated = widget->rect().adjusted(0, 4, 0, -4);
                drawHoverRect(painter, moderated);
            }

            if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
                QPixmap grv = cached(":res/images/slider_bar.png");
                painter->drawPixmap(QRect(groove.x() + 5, groove.y(),
                                          groove.width() - 10, grv.height()),
                                    grv);
            }
            if ((option->subControls & SC_SliderHandle) && handle.isValid()) {
                QPixmap hndl = cached(":res/images/slider_thumb_on.png");
                painter->drawPixmap(handle.topLeft(), hndl);
            }

            painter->restore();
        }
        break;

第2行:程序能进入到CC_Slider所在的case语句,则窗体部件必定是CC_Slider类型的复合控件。接下来将option通过qstyleoption_cast强制转换为QStyleOptionSlider,这种转化肯定能成功。

第3~4行: 通过调用subControlRect函数,获取QSlider控件中的SC_SliderGroove、SC_SliderHandle表示的子控件即沟槽、手柄占据的外包围矩形。关于SC_SliderGroove、SC_SliderHandle表示的子控件具体是什么、含义请查看 《QStyle类用法总结(三)》博文2.2.5节对Slider的描述及Qt Assist。

第8~12行:检测鼠标是否悬浮在QSlider控件上方。如果是则调用drawHoverRect函数绘制一个圆角浅绿色的矩形,这样就会有视觉冲击感。

第14~19行:如果子控件是SC_SliderGroove即QSlider复合控件的沟槽子控件,则将slider_bar.png贴在SC_SliderGroove外包围矩形适当缩小后的矩形上。

第20~23行:如果子控件是SC_SliderHandle即QSlider复合控件的手柄子控件,则将slider_thumb_on.png贴在SC_SliderHandle外包围矩形上。

3.2.2 case语句之CC_GroupBox

Qt Assist对CC_GroupBox解释如下:

 再结合 《QStyle类用法总结(三)》博文2.2.9节对GroupBox的描述,其实 CC_GroupBox就是Group 整个QSlider控件。该标识所在case语句如下: 

  if (const QStyleOptionGroupBox *groupBox
                = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
            QStyleOptionGroupBox groupBoxCopy(*groupBox);
            groupBoxCopy.subControls &= ~SC_GroupBoxLabel;
            QCommonStyle::drawComplexControl(control, &groupBoxCopy, painter, widget);

            if (groupBox->subControls & SC_GroupBoxLabel) {
                const QRect &r = groupBox->rect;
                QPixmap titleLeft = cached(":res/images/title_cap_left.png");
                QPixmap titleRight = cached(":res/images/title_cap_right.png");
                QPixmap titleStretch = cached(":res/images/title_stretch.png");
                int txt_width = groupBox->fontMetrics.horizontalAdvance(groupBox->text) + 20;
                painter->drawPixmap(r.center().x() - txt_width/2, 0, titleLeft);
                QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget);
                painter->drawTiledPixmap(tileRect, titleStretch);
                painter->drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight);
                int opacity = 31;
                painter->setPen(QColor(0, 0, 0, opacity));
                painter->drawText(tileRect.translated(0, 1),
                                  Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
                painter->drawText(tileRect.translated(2, 1),
                                  Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
                painter->setPen(QColor(0, 0, 0, opacity * 2));
                painter->drawText(tileRect.translated(1, 1),
                                  Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
                painter->setPen(Qt::white);
                painter->drawText(tileRect, Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
            }
        }
        break;

第3~5行:除了Group box的标题(SC_GroupBoxLabel)外,Group box的其它子控件都采用默认值绘制,即调用该父类QCommonStyle的drawComplexControl函数绘制。

第12~16行:根据Group box标题文本占据的水平方向上的长度和Group box外包围矩形尺寸信息,在Group box占据的矩形中间、左边、右边贴图。

第17~27行:设置不同画笔颜色透明度且多次微调绘制标题文本的矩形位置绘制标题文本,最终用白色画笔绘制了标题文本。

3.3.drawControl函数

这个函数很简单。基本意思是:如果绘制的是单选按钮、pushbutton按钮文本,且按钮文本为空,则调用默认值绘制,也即调用父类QCommonStyle的drawControl函数。如果单选按钮文本不为空,则以垂直方向居中对齐绘制文本;如果是pushbutton按钮文本,则以垂直且水平都居中对齐绘制文本。

QT:使用QStyle实现QMenu的滚动效果 这一段q->style()->styleHint(QStyle::SH_Menu_Scrollable, 0, q) 是支持滚动样式的,需要配置。QMenu自带滚动,但是要知道怎么使用 还是需要查看QT源码,现在简单记录下我的使用方法。实际就是这么简单,可惜我最开始没看源码,盲人摸象 耽误了很多时间,还是源码最靠谱!QStyle 还有更多样式,可以查查相关文章。 阅读详情

相关推荐

Qt——自定义界面之QStyle

1. Qt控件结构简介

QtCompany的博客 1693

QT风格(QStyle):绘制控件风格设置--QStyleOption

QStyleOption是风格的设置类,定义了最基本的绘制控件所需的信息。 绘制不同控件时,控件所使用的设置类继承QStyleOption,且OptionType值不同。 如绘制按钮的风格设置类QStyleOptionButton继承QStyleOption时,Type = SO_Button表明是要绘制按钮,且添加了一些按钮才有的属性。 根据QStyleOptionButton来绘制自定义按钮的一例: class PushButton : public QWidget { Q_O..

友善啊,朋友的博客 9208

【Qt开发教程】样式选项管理QStyleOption类详解及实战应用

QStyleOption 类提供了一个灵活而强大的框架,用于描述控件的样式选项和绘制参数。通过合理利用 QStyleOption 及其子类,可以为各种控件提供精细的样式绘制支持。结合 QStyle 和 QProxyStyle,开发者可以创建高度定制化的控件外观和行为,为用户提供一致且美观的用户界面体验。通过扩展和优化样式选项和绘制逻辑,可以进一步提升应用程序的视觉吸引力和响应速度。

科技改变人类,技术成就未来 853

QT风格(QStyle):绘制一个自定义QSpinBox

恢复设置,到drawPrimitive()绘制的原点还是在上下按钮的(0,0)点,设置painter->translate(option->rect.x(),option->rect.y());其中PrimitiveElement是原始元素,这里设置成向左和向右的箭头,也可以设置成别的,调用重载函数drawPrimitive()进行绘制,可以在该函数里自由绘制,如PE_IndicatorSpinUp默认绘制是一个上三角。要绘制一个自定义的QSpinBox只需要在自定义的风格里面绘制这几个元素就行了。

hw5230的博客 1085

Xilinx ZYNQ 7000学习笔记二(FSBL代码分析启动-汇编代码)

Xilinx ZYNQ 7000学习笔记

u011116085的博客 4246

移远EC20模块USB模式切换的底层逻辑与驱动适配探秘

本文深入探讨了移远EC20模块USB模式切换的底层逻辑与驱动适配机制,详细解析了AT命令控制下的USB0与WWAN0模式差异。通过分析USB协议栈、内核驱动框架及网络子系统的交互,提供了模式切换的完整操作流程和常见问题解决方案,助力开发者优化4G通信模块在嵌入式设备中的稳定连接。

cc789的博客 842

QStyle实现自绘界面项目实战(一)

通过项目实战来理解前几篇提到的内容

danshiming的博客 3195

TC264摄像头循迹进阶:八邻域与逐行遍历在复杂赛道边界提取中的实战对比

本文对比分析了TC264摄像头循迹中八邻域法与逐行遍历法在复杂赛道边界提取中的实战表现。八邻域法在边界连续性方面表现优异,适合处理环岛等复杂元素;逐行遍历法则在计算效率和岔路口识别上更具优势。文章提供了详细的代码实现和优化策略,帮助智能车竞赛选手根据赛道特点选择最佳算法方案。

rainy的博客 936

QStyle类用法总结(二)

QStyle类用法总结(二)

danshiming的博客 5150

极验点选click3.1.0所对应fullpage.js的逆向分析

极验3代点选验证,本文适用于使用click.3.1.0.js和fullpage919-eyz9lh.js版本的web验证码,没有细节内容,适合有基础的开发者阅读。

shanf7921的博客 647

Ubuntu-22.04安装VMware虚拟机并安装Windows10

最近在研究虚拟机,主要集中在KVM、Virtualbox和VMware这三种虚拟机上。前面我已经研究了前两种虚拟机的安装和使用方式,这篇文章介绍3兄弟中最后一个虚拟机安装和使用方式。Virtualbox虚拟机安装和使用KVM虚拟机安装和使用相比于前两种,VMware的安装方式最麻烦,但是综合体验下来我感觉流畅度最好。如果你确实有在Linux上使用VMware虚拟机的需求,那不妨跟着我看下去吧。1、gcc版本和内核版本一定要匹配上,否则会出各种错误。

jiexijihe945的博客 4114

Qt QStyle详解

QStyle类是 Qt 框架中用于控制应用程序界面元素外观的一个抽象基类。这个类提供了一种方式来定制窗口部件(widgets)的绘制和行为,可以通过改变主题或风格来更改应用程序的外观,而无需修改窗口部件本身的代码。Qt包含一组QStyle子类,这些子类模仿Qt支持的不同平台的样式(QWindowsStyle、QMacStyle等)。默认情况下,这些样式内置在Qt GUI模块中。样式也可以作为插件提供。Qt的内置widget使用QStyle来执行几乎所有的绘制,确保它们看起来与等效的本地小部件完全相同。

希望能帮助大家,希望大家多多支持,你们的支持是我前进的动力。 4846

7.29华为OD机试真题 新系统 - 能量对撞 (Java/Py/C/C++/Js/Go)

7.29华为OD机试真题 新系统 - 能量对撞 (Java/Py/C/C++/Js/Go)

算法大师! 1315

QStyle设置界面的外观和QCommonStyle继承关系图讲解和使用

简 述: 本文章讲解类容如下 讲述绘画自定义风格的 Style 的框架结构; 使用 QStyle 设置界面的外观 QCommonStyle 继承关系图 如何继承 QCommonStyle 类来创建自己的自定义的类 讲解如下函数:polish(),unpolish(),drawPrimitive(),drawControl(),subElementRect(),drawCom...

7059

Android 12.0 系统开机设置默认横屏显示

在12.0的系统产品开发中,对于产品需求来说,由于是宽屏设备所以产品需要开机默认横屏显示,开机横屏显示这就需要从两部分来实现,一部分是开机动画横屏显示,另一部分是系统显示横屏显示,从这两方面就可以做到开机默认横屏显示了。

安卓兼职framework和app工程师的博客 3743

Qt c++ llama.cpp 运行 LLaMA-3-8B 中文对话机器人(多模态输入)

助手:

寒寒豆豆软件公司的博客 218

QStyle自定义重绘QScrollBar

简介: QStyle自定义重绘QScrollBar(滚动条)样式。 文章目录本博文的简述or解决问题?同步博文:运行效果:QScrollbar官方教程:QScrollbar属性理解:开心分享: 本博文的简述or解决问题? ​ 详情: 见简介 编程环境: deepin 15.11 x64 专业版 Kernel: x86_64 Linux 4.15.0-30deepin-generi...

3081

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

QT中QStyle的使用

QStyle介绍:   Qt是一个跨平台的类库,相同的界面组件在不同的操作系统上显示效果是不一样的,QStyle封装了GUI界面组件外观的抽 象类,QT内置的界面组件都使用QStyle进行绘制,以保证他们与运行平台的界面效果一致。 运行结果图: 一.相关类和函数介绍: QStyleFactory类管理着Qt的内置样式。 QStringList QStyleFactory::keys():返回平台支持的QStyle的名称列表 QStyle *QStyleFactory::create(const QStr

Vivi的城 9858

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

QStyle类用法总结(一)

QStyle类用法总结

danshiming的博客 7094

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

QStyle自定义重绘QRubberBand控件

简介: 根据QStyle的继承关系和重绘原理;通过实现一个继承QCommonStyle类的实现,实现自己的自定义控件QRubberBand控件。 文章目录本博文的简述or解决问题?同步博文:运行效果:QRubberBand重绘:开心分享: 本博文的简述or解决问题? ​ 详情: 见简介 编程环境: deepin 15.11 x64 专业版 Kernel: x86_64 Linux ...

2343

QStyle/DTK重绘Qt-GUI已有控件,举例QScrollBar

简 述: 使用 QStyle / DTK 来实现重绘 Qt-GUI 已有的控件,此处以重绘 QScrollBar 举例。 文章目录编程环境:背景:查看 QScrollBar 的构成,如何查找源码?解析绘画控件的步骤:自定义风格完整代码如下:项目分析:源码下载: 编程环境: ????: MacOS10.14 (18G103) ???? Qt 5.12.6 ????: win10 x64 专业版 (1803) ...

3377

QStyle类用法总结(三)

自定义style、图形元素层次树

danshiming的博客 3832

重绘的QStyle中sizeFromContents()没有被调用

简介: 在自定义重绘QStyle的时候,继承于class ExCustomStyle : public QCommonStyle的类,在重写虚函数sizeFromContents()时候,却发现并没有被调用。在此处记录一个**"硬核深坑"sizeFromContents()没有被调用**。 文章目录本博文的简述or解决问题?同步博文:错误起因:解决原因:测试代码:开心分享: 本博文的简述or解...

1204

QStyle

一、描述 QStyle 类是一个抽象基类,它封装了 GUI 的外观。样式也可以作为插件使用。 Qt 的内置小部件使用 QStyle 来执行几乎所有的绘图,确保它们看起来与等效的原生小部件完全一样。下图显示了九种不同样式的 QComboBox。 1.1、设置样式 可以使用 QApplication::setStyle() 函数设置整个应用程序的样式。 如果没有指定样式,Qt 会为用户的平台或桌面环境选择最合适的样式。 也可以使用 QWidget::setStyle() 函数在单个小部件上设置样

友善啊,朋友的博客 4040

Qt QStyle

QStyle Class QStyle类是一个抽象基类,它封装了GUI的外观。 Qt 包含一组 QStyle 子类,这些子类可以模拟Qt支持不同的平台样式(QWindowsStyle,QMacStyle等)。默认情况下,这些样式内置在 Qt GUI 模块中,样式也可以作为插件使用。 Qt 的内置小窗口部件使用 QStyle 来执行几乎所有的绘图,从而确保它们看起来完全等同于等效的本级窗口小部件。下图展示了九中不同样式的 QCombox。 Setting a Style (设定风格) 可以使用 QAppli

暖暖_的_纠结的博客 6269

Qt自定义界面之QStyle

Qt自定义界面之QStyle

m0_60259116的博客 359
上一篇: QPalette类的使用和说明
下一篇: QWebEngineView崩溃及替代方案
荆楚闲人
博客等级 码龄20年 3万+粉丝 473原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值