Qt Creator源码分析系列——UI界面:SiderBar类分析

该篇文章内容主要集中Qt Creator软件欢迎界面部分代码的分析。从分析插件中的welcome模块开始,项目文件在路径\qt-creator-master\qt-creator-master\src\plugins\welcome下。

分析welcomeplugin.cpp文件

SideBar类

SideBar类继承自QWidget类,该类除了继承QWidget的成员变量,还包含了一个public成员:垂直布局QVBoxLayout指针m_pluginButtons以及构造函数SiderBar(QWidget *parent)

SideBar(QWidget *parent) : QWidget(parent){
	setAutoFillBackground(true);
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
	setPalette(themeColor(Theme::Welcome_BackgroundColor));

这里的autoFillBackground是QWidget的属性(Properties),在Qt 4.1中引入的属性,它是bool类型的,且默认设置为false。此属性保存widget的背景是否自动填充。如果启用,将导致Qt在调用paint事件之前先填充widget背景。使用的颜色由widget的调色板属性palette的QPalette :: Window颜色角色(ColorRole)定义。另外,除非设置了WA_OpaquePaintEvent或WA_NoSystemBackground属性,否则Windows始终会用QPalette :: Window填充。
在这里插入图片描述
如果widget的父级对其背景具有静态渐变(static gradient),则无法关闭此属性(将其设置为false)。将此属性与Qt样式表一起使用时应谨慎。 当widget样式表具有有效的背景或边框图像时,将自动禁用此属性。
如下两个函数用于获取、设置该属性
在这里插入图片描述
这里的sizePolicy是QWidget的属性(Properties),它是QSizePolicy类型的,且默认设置为。此属性保存widget的默认布局行为。如果有一个布局管理器QLayout管理该widget的子级,则使用该布局指定的大小策略。如果没有QLayout,则使用此函数的结果。默认策略是Preferred/Preferred,这意味着可以自由调整窗口的大小,但最好使用sizeHint()返回的大小。类似于按钮的widget部件将大小策略设置为可以水平拉伸但垂直固定。这同样适用于lineedit控件(例如QLineEdit,QSpinBox或可编辑的QComboBox)和其他水平定向的widget部件(例如QProgressBar)。 QToolButton通常是正方形的,因此它们允许双向增长。支持不同方向的小部件(例如QSlider,QScrollBar或QHeader)仅指定在各个方向上的拉伸。可以提供滚动条的小部件(通常是QScrollArea的子类)倾向于指定它们可以使用额外的空间,并且可以用不到sizeHint()的大小来做事。
在这里插入图片描述
这里的palette调色板是QWidget的属性(Properties),它是QPalette类型,且默认设置为false。呈现标准组件时,窗口widget部件的样式使用该调色板,并且可以用作确保自定义窗口小部件可以与本机平台的外观保持一致。不同的平台或不同的样式具有不同的调色板是很常见的。当您为窗口小部件分配新的调色板时,该调色板中的颜色角色将与窗口小部件的默认调色板组合在一起,以形成窗口小部件的最终调色板。widget部件的背景角色调色板条目用于填充部件的背景(请参阅QWidget :: autoFillBackground),而前景角色则初始化QPainter的笔。
默认值取决于系统环境。 QApplication维护一个系统/主题面板,它是所有widget部件的默认选项。 对于某些类型的widget部件,可能还会有特殊的调色板默认设置(例如,在Windows XP和Vista中,从QMenuBar派生的所有类都具有特殊的默认调色板)。 您还可以通过向QApplication :: setPalette()传递自定义调色板和窗口小部件名称,来为窗口小部件定义默认调色板。 最后,样式始终可以选择在分配调色板时对其进行抛光polish(请参见QStyle :: polish())。
QWidget将显式调色板角色从父级传播到子级。 如果将画笔或颜色分配给调色板上的特定角色,然后将该调色板分配给widget部件,则该角色将传播到所有widget部件的子级,从而覆盖该角色的所有系统默认值。 请注意,除非启用了Qt :: WA_WindowPropagation属性,否则默认情况下,调色板不会传播到窗口(请参见isWindow())。
当前样式用于呈现所有标准Qt widget部件的内容,可以自由地从widget部件调色板中选择颜色和画笔,或者在某些情况下可以忽略调色板(部分或全部)。 特别是,某些样式(例如GTK样式,Mac样式,Windows XP和Vista样式)依赖于第三方API来呈现窗口widget部件的内容,并且这些样式通常不遵循调色板。 因此,不能保证将角色分配给窗口widget部件的调色板会更改窗口widget部件的外观。 相反,您可以选择应用styleSheet。请勿将此功能与Qt样式表一起使用。 使用样式表时,可以使用“color”,“background-color,“selection-color”,“selection-background-color”和“alternate-background-color”来自定义窗口widget部件的调色板。
在这里插入图片描述
这里的Theme::Welcome_BackgroundColor是\qt-creator-master\qt-creator-master\src\libs\utils\utils-lib\Sources下theme主题中的定义的Theme类的枚举类型。
themeColor是定义在welcomplugin.cpp中的函数,参数是上面所述的枚举类型。Utils是命名空间,而creatorTheme函数就是获取指向Theme的静态指针。而Theme对象的d成员变量的类型是ThemePrivate类。关于Theme类,这里只讲到这里,不展开讲,留下以后再详细讲。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建垂直布局管理器QVBoxLayout,后续代码就是加入下图中的各个子控件。

auto vbox = new QVBoxLayout(this);
vbox->setSpacing(0);
vbox->setContentsMargins(0, 27, 0, 0);

setSpacing用于设置间距,QVBoxLayout的这个方法是对父类QLayout::setSpacing的重新实现。spacing属性保存布局内widget部件之间的间距。如果未显式设置任何值,则布局的间距将从父布局或父窗口小部件的样式设置继承。
在这里插入图片描述
这是再Qt 4.3中引入的方法,设置要在布局周围使用的左,上,右和下页边距。默认情况下,QLayout使用样式提供的值。 在大多数平台上,所有方向上的边距均为11像素。

在这里插入图片描述
这里在上述的垂直布局vbox中加入垂直布局QVBoxLayout,并且将SideBar中定义的变量m_pluginButtons赋值为指向QVBoxLayout的指针。这里也就是图中放置Projects、示例和教程控件的布局管理器。

auto l = m_pluginButtons = new QVBoxLayout;
l->setContentsMargins(lrPadding, 0, lrPadding, 0);
l->setSpacing(19);
vbox->addItem(l);

lrPadding是定义的常变量
在这里插入图片描述

填充空白的widget作为分隔

addWeakVerticalSpacerToLayout(vbox, 62);

在这里插入图片描述

新建一个垂直布局管理器,加入相应的控件,并把整个垂直布局管理器加入vbox中。

auto l = new QVBoxLayout;
l->setContentsMargins(lrPadding, 0, lrPadding, 0);
l->setSpacing(12);
//新建Label控件
auto newLabel = new QLabel(tr("New to Qt?"), this);
newLabel->setFont(sizedFont(18, this));
l->addWidget(newLabel);
//新建Label控件
auto learnLabel = new QLabel(tr("Learn how to develop your own applications "
                                "and explore %1.").arg(Core::Constants::IDE_DISPLAY_NAME), this);
learnLabel->setMaximumWidth(200);
learnLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
learnLabel->setWordWrap(true);
learnLabel->setFont(sizedFont(12, this));
learnLabel->setPalette(lightText());
l->addWidget(learnLabel);

l->addSpacing(8);

auto getStartedButton = new WelcomePageButton(this);
getStartedButton->setText(tr("Get Started Now"));
getStartedButton->setOnClicked([] {
QDesktopServices::openUrl(QString("qthelp://org.qt-project.qtcreator/doc/index.html"));
            });
l->addWidget(getStartedButton);

vbox->addItem(l);

这里的setFont的函数设置的是父类widget的font属性,它是QFont类型。
在这里插入图片描述
在welcomeplugin.cpp中也定义了改变字体某些属性的自定义函数。先获取形参widget的字体QFont值,然后使用setPixlSize方法将字体大小设置为size像素,使用setUnderline方法设置下划线。
在这里插入图片描述
在这里插入图片描述

wordWrap属性保留标签的自动换行策略。如果此属性为true,则在断字时在必要时将标签文本包装起来; 否则,它根本不会被包裹。
在这里插入图片描述
这里LightText函数主要内容上面已经介绍过了,不详细解释。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
将大小为size的不可拉伸空间(QSpacerItem)添加到此框布局的末尾。 QBoxLayout提供默认的边距和间距。 此功能增加了额外的空间。

加入空白后,添加Get Started Now按钮。这里是自定义的WelcomePageButton按钮类,继承自WelcomPageFrame。对于这个自定义按钮类,后面分享继续讲解。
在这里插入图片描述

vbox->addStretch(1);
	{
     	auto l = new QVBoxLayout;
        l->setContentsMargins(0, 0, 0, 0);
        l->setSpacing(5);
        l->addWidget(new IconAndLink("qtaccount", tr("Qt Account"), "https://account.qt.io", this));
       l->addWidget(new IconAndLink("community", tr("Online Community"), "https://forum.qt.io", this));
       l->addWidget(new IconAndLink("blogs", tr("Blogs"), "https://planet.qt.io", this));
       l->addWidget(new IconAndLink("userguide", tr("User Guide"),
                                         "qthelp://org.qt-project.qtcreator/doc/index.html", this));
       vbox->addItem(l);
}
addWeakVerticalSpacerToLayout(vbox, vbox->contentsMargins().top());

再下面加入另外一个QVBoxLayout,依次加入IconAndLink自定义控件。其定义在welcomeplugin.cpp文件中。可以看出其继承自QWidget类

IconAndLink类

class IconAndLink : public QWidget
{
public:
    IconAndLink(const QString &iconSource, const QString &title, const QString &openUrl, QWidget *parent)
        : QWidget(parent), m_iconSource(iconSource), m_title(title), m_openUrl(openUrl)
    {
        setAutoFillBackground(true);
        setMinimumHeight(30);
        setToolTip(m_openUrl);

        const QString fileName = QString(":/welcome/images/%1.png").arg(iconSource);
        const Icon icon({{fileName, Theme::Welcome_ForegroundPrimaryColor}}, Icon::Tint);
        m_icon = new QLabel;
        m_icon->setPixmap(icon.pixmap());

        m_label = new QLabel(title);
        m_label->setFont(sizedFont(11, m_label, false));

        auto layout = new QHBoxLayout;
        layout->setContentsMargins(lrPadding, 0, lrPadding, 0);
        layout->addWidget(m_icon);
        layout->addSpacing(2);
        layout->addWidget(m_label);
        layout->addStretch(1);
        setLayout(layout);
    }

    void enterEvent(QEvent *) override
    {
        QPalette pal;
        pal.setColor(QPalette::Window, themeColor(Theme::Welcome_HoverColor));
        setPalette(pal);
        m_label->setFont(sizedFont(11, m_label, true));
        update();
    }

    void leaveEvent(QEvent *) override
    {
        QPalette pal;
        pal.setColor(QPalette::Window, themeColor(Theme::Welcome_BackgroundColor));
        setPalette(pal);
        m_label->setFont(sizedFont(11, m_label, false));
        update();
    }

    void mousePressEvent(QMouseEvent *) override
    {
        QDesktopServices::openUrl(m_openUrl);
    }

QString m_iconSource;  //图标名
QString m_title;  //文字
const QString m_openUrl; //url

QLabel *m_icon;  //放置图标的标签
QLabel *m_label; //放置文字的标签
};

IconAndLink的构造函数就是构造一个包含图标和文字的控件,并且覆写enterEvent、leaveEvent和mousePressEvent这三类事件。
在这里插入图片描述
可以在子类中重新实现此事件处理程序,以接收在事件参数中传递的部件输入事件。当鼠标光标进入窗口部件时,事件将发送到窗口部件。
leaveEvent同理,它们的代码就是设置默认调色盘和字体下划线以及恢复默认调色盘和取消下划线。

openUrl的行为是调用默认浏览器打开m_openUrl所指定的网址。

QDesktopServices::openUrl(m_openUrl);

这里涉及到的是QDesktopServices类,该类提供通用桌面服务的方法。许多桌面环境提供的服务可被应用程序用来以一致且兼顾用户应用程序首选项的方式执行常见任务(例如打开网页)。此类包含为这些服务提供简单接口的函数 表明他们是成功还是失败。 openUrl()函数用于在外部应用程序中打开位于任意URL的文件。 对于与本地归档系统上的资源相对应的URL(URL方案为“文件”),将使用合适的应用程序来打开文件; 否则,将使用网络浏览器来获取并显示文件。用户的桌面设置控制是打开某些可执行文件类型进行浏览还是执行它们。 一些桌面环境被配置为阻止用户执行从非本地URL获得的文件,或者在执行操作之前征询用户的许可。
在这里插入图片描述
这里先不对serUrlHandler函数详细介绍,后面的章节将对此进行介绍。

这里的"qthelp://org.qt-project.qtcreator/doc/index.html"是切换到帮助页面,是上面指明的使用合适的应用程序来打开文件,就是下图:
在这里插入图片描述

toolTip是QWidget类的属性(property),是QString类型。默认情况下,仅针对活动窗口的子窗口部件显示工具提示。您可以通过在窗口上而不是在带有工具提示的小部件上设置属性Qt :: WA_AlwaysShowToolTips来更改此行为。
如果要控制工具提示的行为,则可以拦截event()函数并捕获QEvent :: ToolTip事件(例如,如果要自定义应显示工具提示的区域)。默认情况下,此属性包含一个空字符串。
在这里插入图片描述
当鼠标移动到这个控件上时会出现提示框,上面显示的是需要连接的url。

这里的Icon类型定义在src/libs/utils/utils-lib\Headers\tooltip文件下的icon.h中,和theme一样都属于utils。以后会详细讲解。
在这里插入图片描述

在这里插入图片描述
返回布局周围使用的边距。默认情况下,QLayout使用样式提供的值。 在大多数平台上,所有方向上的边距均为11像素。返回类型是QMargins类,top方法返回顶部的边距。

总结

SideBar类是用于构造欢迎页的侧栏的类,提供了一个public垂直布局QVBoxLayout的指针m_pluginButtons成员用于实现图中的Projects、示例和教程控件布局。本节没有关注WelcomPageButton类、Utils中的Theme和Icon类的实现。

发布了134 篇原创文章 · 获赞 141 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/asmartkiller/article/details/104287209
今日推荐