头文件的小技巧
#include <QtWidgets>
// 在自动生成的 .h 里面加上此句
适用条件:
QT 的内存管理
当父窗体被关闭时,子部件的内存会自动释放。
对象树是一种管理对象生命周期的机制。当一个对象被添加到另一个对象的子对象列表中时,Qt 会自动将其设置为父对象的子对象,并在父对象被销毁时自动销毁其所有子对象。这种机制可以避免内存泄漏和悬空指针的问题。
UI 编辑器
注意事项
UI 编辑器会在项目构建目录中自动生成一个 ui_xxx.h(构建一次后才会生成),来表示 UI 编辑器界面的代码,属于自动生成的,一定不要修改。代码中如果要修改界面中的某个部件的属性,应该用 ui->xxx 获取到部件,然后调用相应的方法修改。
// 自动生成的 ui_widget.h(可忽略)
/********************************************************************************
** Form generated from reading UI file 'widget.ui'
**
** Created by: Qt User Interface Compiler version 5.2.1
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_WIDGET_H
#define UI_WIDGET_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QButtonGroup>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QWidget>
#include <mybutton.h>
QT_BEGIN_NAMESPACE
class Ui_Widget
{
public:
Mybutton *newBtn;
QLineEdit *lineEdit;
void setupUi(QWidget *Widget)
{
if (Widget->objectName().isEmpty())
Widget->setObjectName(QStringLiteral("Widget"));
newBtn = new Mybutton(Widget);
newBtn->setObjectName(QStringLiteral("newBtn"));
newBtn->setGeometry(QRect(410, 510, 112, 34));
lineEdit = new QLineEdit(Widget);
lineEdit->setObjectName(QStringLiteral("lineEdit"));
lineEdit->setGeometry(QRect(220, 120, 561, 231));
retranslateUi(Widget);
QMetaObject::connectSlotsByName(Widget);
} // setupUi
void retranslateUi(QWidget *Widget)
{
Widget->setWindowTitle(QApplication::translate("Widget", "Widget", 0));
newBtn->setText(QApplication::translate("Widget", "newBtn", 0));
} // retranslateUi
};
namespace Ui {
class Widget: public Ui_Widget {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_WIDGET_H
信号与槽
在设计界面,右键相应的组件,选择“转到槽”选项,会自动跳转到槽函数。
这种方法不会有 connect 的体现,遵循的是 qt 内部名字匹配规则。
匹配规则:on_AAA_BBB —— 代表连接 AAA 对象 的 BBB 信号 到此槽。
比如要响应 对象 myBtn 的 clicked 信号,就会生成 on_myBtn_clicked 的槽。
// widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_loginBtn_clicked(); // 连接 对象loginBtn 的 clicked信号 到 此槽
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
// widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_loginBtn_clicked()
{
if (ui->usrEdit->text() == "0828" && ui->pwdEdit->text() == "0828")
{
this->close();
}
}
客制化组件
按钮的样式及功能
定制一个按钮,实现自定义样式及功能。比如每个按钮拥有自己的 key 值,按钮字体的默认颜色是红色,背景色灰色。大小固定为 90*70。
mybutton.h
#ifndef MYBUTTON_H
#define MYBUTTON_H
#include <QPushButton>
#include <QTWidgets>
class Mybutton : public QPushButton
{
Q_OBJECT
int key;
public:
explicit Mybutton(QWidget *parent = 0);
int getKey() { return this->key; }
void setKey(int key) { this->key = key; }
signals:
public slots:
};
#endif // MYBUTTON_H
mybutton.cpp
#include "mybutton.h"
Mybutton::Mybutton(QWidget *parent) :
QPushButton(parent)
{
key = 0;
this->setStyleSheet("color: red; background-color: grey");
this->setFixedSize(90, 70);
this->setText("默认文字");
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QtWidgets>
#include "mybutton.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
private:
Ui::Widget *ui;
Mybutton *btn;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->resize(480, 300);
btn = new Mybutton(this);
qDebug() << "Key(before): " << btn->getKey();
btn->setKey(17);
qDebug() << "Key(after): " << btn->getKey();
}
Widget::~Widget()
{
delete ui;
}
提升部件
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
this->resize(480, 300);
// btn = new Mybutton(this);
// qDebug() << "Key(before): " << btn->getKey();
// btn->setKey(17);
// qDebug() << "Key(after): " << btn->getKey();
qDebug() << "Key: " << ui->newBtn->getKey();
}
Widget::~Widget()
{
delete ui;
}
内建对话框
对话框帮助文档要关注 Static Public Members 部分,参考帮助文档 demo 使用即可。
QMessageBox
QInputDialog
QColorDialog
QFontDialog
QFileDialog
QString getOpenFileName(QWidget * parent = 0, const QString & caption = QString(), \
const QString & dir = QString(), const QString & filter = QString(), \
QString * selectedFilter = 0, Options options = 0);
功能:打开文件对话框
参数:
parent:父窗口,一般填this
caption:弹出窗口的标题
dir:默认打开目录
filter:过滤条件
剩余参数默认即可
返回值:成功会返回打开的文件路径,如果失败那么返回空
弹出文件选择窗口
在界面加入一个按钮和一个文本编辑框,点击按钮后弹出文件选择窗口,选择文件后把文件绝对路径增加到文本编辑框内。取消选择弹出对话框提示“打开失败”。
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QTWidgets>
#include "mybutton.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_newBtn_clicked();
private:
Ui::Widget *ui;
Mybutton *btn;
};
#endif // WIDGET_H
打开生成的 ui_widget.h 文件,找到拖拽产生的 QLineEdit,复制对象名字(直接记住也行)。
在 widget.cpp 中,使用复制下来的名字(记住现找也行)。
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_newBtn_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
"e:", tr("Files (*.chm)"));
if (fileName.isEmpty())
{
qDebug() << "Failed to open file";
return;
}
ui->lineEdit->setText(fileName); // lineEdit 名字 与 UI 生成的名字 保持一致
}