Qt那些事(之一)

  这几天因为工作的需要,从零开始学习Qt。从现在开始,对以后的学习过程有个清晰的记录,以此勉励自己不断坚持。

  对Qt的了解从学习嵌入式开发开始,那时知道Qt是搭建嵌入式UI界面的良好工具,优势就是其跨平台的特性。

  这里根据这两天做的一个小实例,简介一下用到的技术点,深化一下自己的理解。主要是运用Qt进行界面编程。

  主要的知识点有两个:一个是布局,一个是自定义标题栏。

一:布局管理的简介

  Qt的布局管理主要由QLayout类族实现,当然也可以逐个指定控件在界面上的位置。QHBoxLayout为横向布局、QVBoxLayout为纵向布局、QGridLayout为网格布局。三者的接口都类似。addWidget()向布局中添加一个QWidget,addLayout()向布局添加一个QLayout对象,addSpacing()和setSpacing分别可添加和设置控件间的“留白“,addMagrin()和setMagrin()是添加和设置layout中的边缘。addStretch()可在控件间添加一个具有伸展性的空间。

  布局类在使用是设定控件间和边缘处的“留白“,在将空间添加进入。最后调用setStretchFactor()设置控件占用Layout的比例。

  值得注意的地方是QGridLayout在调用addWidget时需要指出控件在网格中的第几行第几列,并且能够使用该函数设定控件占用多行或多列。

  如下是一段代码:

void Widget::insertPageThreeToStack()
{
    QWidget *widgetInStack  = new QWidget();
    QGridLayout *gridLayout = new QGridLayout(this);
    textBrowser = new QTextBrowser();

    lineEditA = new QLineEdit();
    lineEditB = new QLineEdit();

    ButtonOk = new myButton(tr("Ok"));
    //setStyleSheet("QPushButton{color:gray}");
    ButtonOk->setEnabled(false);

    myLabel *labelA = new myLabel(tr("name"));
    myLabel *labelB = new myLabel(tr("address"));
    QPixmap iconA("./Icon/woman_24px_1186493_easyicon.net.png");
    labelA->setPixmap(iconA);
    QPixmap iconB("./Icon/house_24px_1207925_easyicon.net.png");
    labelB->setPixmap(iconB);

    gridLayout->addWidget(labelA,0,2);
    gridLayout->addWidget(lineEditA,0,3);
    gridLayout->addWidget(labelB,1,2);
    gridLayout->addWidget(lineEditB,1,3);
    gridLayout->addWidget(ButtonOk,0,4,2,1);
    gridLayout->addWidget(textBrowser,2,2,3,3);

    widgetInStack->setLayout(gridLayout);
    this->Stack->addWidget(widgetInStack);

    connect(lineEditA,SIGNAL(textEdited(const QString &)), ButtonOk, SLOT(enableThisButton()));
    connect(ButtonOk, SIGNAL(pressed()), this, SLOT(finishInsert()));
    //connect(ButtonOk,SIGNAL(released()), ButtonOk, SLOT(disableThisButton()));
}

 二、自定义标题栏

  自定义标题栏首先要清除系统自带的标题栏:setWindowFlags(Qt::FramelessWindowHint)。然后显示自己定义的标题栏对象。

  这里采取了创建一个myTitleBar类,继承QWidget类的方式。在myTitleBar中定义图标iconLabel,标题titleLabel,最大化按钮maxSetButton,最小化按钮minSetButton,最小化按钮closeButton,并且使用QHBoxLayout管理布局。

  构造函数如此实现:

myTitleBar::myTitleBar(QWidget *parent)
    :QWidget(parent)
{
    setFixedHeight(30);

    iconLabel  = new QLabel(this);
    titleLabel = new QLabel(this);
    minSetButton = new QPushButton(this);
    maxSetButton = new QPushButton(this);
    closeButton  = new QPushButton(this);

    titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    iconLabel->setFixedSize(20, 20);
    iconLabel->setScaledContents(true);
    minSetButton->setFixedSize(27, 22);
    maxSetButton->setFixedSize(27, 22);
    closeButton->setFixedSize(27, 22);

    titleLabel->setObjectName("whiteLabel");
    minSetButton->setObjectName("minimizeButton");
    maxSetButton->setObjectName("maximizeButton");
    closeButton->setObjectName("closeButton");

    minSetButton->setStyleSheet("QPushButton{border-image: url(./Icon/Minimize_24px_1178218_easyicon.net.png)}");
    maxSetButton->setStyleSheet("QPushButton{border-image: url(./Icon/maximize_24px_1179260_easyicon.net.png)}");
    closeButton->setStyleSheet("QPushButton{border-image: url(./Icon/close_24px_1199932_easyicon.net.png)}");

    minSetButton->setToolTip("Minimize");
    maxSetButton->setToolTip("Maximize");
    closeButton->setToolTip("Close");

    QHBoxLayout *pLayout = new QHBoxLayout(this);
    pLayout->addWidget(iconLabel);
    pLayout->addSpacing(0);
    pLayout->addWidget(titleLabel);
    pLayout->addWidget(minSetButton);
    pLayout->addWidget(maxSetButton);
    pLayout->addWidget(closeButton);
    pLayout->setContentsMargins(0, 0, 0, 0);
iconLabel->installEventFilter(this); this->setStyleSheet("QWidget { background-color : gray ; color : white}"); connect(minSetButton, SIGNAL(clicked(bool)), this, SLOT(onClicked())); connect(maxSetButton, SIGNAL(clicked(bool)), this, SLOT(onClicked())); connect(closeButton, SIGNAL(clicked(bool)), this, SLOT(onClicked())); }

   在使用时创建myTitleBar对象放入布局中即可。

  自定义标题的第二步是对点击最大/最小/关闭按钮编写槽函数。其中三个信号都会触发onClicked函数,该函数是如此实现的:

void myTitleBar::onClicked()
{
    QPushButton *pButton = qobject_cast<QPushButton *>(sender());
    QWidget *pWindow = this->window();
    if (pWindow->isWindow())
    {
        if (pButton == minSetButton)
        {
            pWindow->showMinimized();
        }
        else if (pButton == maxSetButton)
        {
            pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized();
        }
        else if (pButton == closeButton)
        {
            pWindow->close();
        }
    }
}

   判断按钮对象并调用相应的方法。

  如此便实现了自定义的标题栏,当然还有拉伸窗口、拖动窗口等等,这些涉及到重写鼠标事件,今天太晚了,明天整理一番在写。

  参考博客如下:

  http://blog.csdn.net/xgbing/article/details/7764326

  http://blog.csdn.net/liang19890820/article/details/50555298

posted @ 2017-09-01 23:52  小学毕业未遂  阅读(192)  评论(0)    收藏  举报