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

浙公网安备 33010602011771号