文章目录
- 信号槽机制
- .pro文件
- 按钮(QPushButton)
- Qt窗口坐标系
- Lambda
- QMainWindow
- 菜单栏:
- 工具栏
- 状态栏
- 铆接部件(浮动窗口)
- 核心部件(中心部件)
- 资源文件
- 对话框
- 布局管理
- widget
- QLabel
- QLineEdit
- 自定义控件
- 消息机制和事件
- event()
- 事件过滤器
- 文件系统
信号槽机制
信号槽机制是Qt框架的特色, 可以简单描述为,一个对象触发了一个信号,如果某个对象 对这个 信号感兴趣,那么就可以进行连接,当这个对象接收到这个信号后,可以做相应的处理,通常这种处理是交给槽函数来实现的。
// 信号槽的使用
// connect(sender,signal,receiver,slot)
// sender 信号发送者 signal 要发送的信号 receiver 信号接收者 slot 槽函数
class Teacher{
// 自定义信号
signal:
// 注意 信号 只声明 不实现
void hungry();
};
class Student{
slots:
// 槽函数
void treat();
};
// 槽函数实现
void Student::treat(){
qDebug() << "该吃饭了!";
}
// 触发信号方法
void MyWidget::classIsOver(){
// 发送信号
emit teacher ->hungry();
}
teacher = new Teacher(this); // this 添加children 表 方便回收
student = new Student(this);
// 信号槽连接
connect(teacher,&Teacher::hungry,student,&Student::treat);
/*
注意:
1.对于有重载的信号和槽 使用函数指针处理
void(Teacher::*teacherSignal)(QString)=&Teacher::hungry; // 这里假设hungry信号 被重载过
void(Student::*studentSlot)(QSting)=&Student::treat; // 这里treat 槽函数被重载过
connect(teacher,teacherSignal,student,studentSlot);// 重载后的连接
2.信号和槽函数的返回值是void
3.槽函数是普通成员函数 会受到public private protected的影响
4.使用emit 关键字触发信号
5.任何成员函数、static 函数、全局函数 lambda表达式都可以作为槽函数
6.信号 和 槽必须保持 参数一致 即类型一致,槽函数的参数可以比信号少
7.一个信号可以和多个槽连接
8.多个信号可以连接到一个槽
9.一个信号可以连接到另外的一个信号
10.信号槽可以取消连接
*/
.pro文件
QT += core gui # 项目包含的模块
greaterThan(QT_MAJOR_VERSION,4): QT += widgets # 大于Qt4版本才包含widget模块
TARGET=QfFirst # 生成的应用程序名称 Windows下是.exe 文件名称
TEMPLATE=app # 模板类型 应用程序使用的模板
SOURCES+=main.cpp\ # 源文件
mywidget.cpp
HEADERS += mywidget.h # 头文件
说明:
1. 注释 从# 开始直到 一行结束
2. TEMPLATE 模板变量告诉qmake 为这个应用程序生成哪种makefile
- app 建立一个应用程序的makefile,这是默认值,所以如果这个模板没有被指定,这个将被使用
- lib 建立一个库的makefile
- vcapp 建立一个应用程序的VisualStudio项目文件
- subdirs 这是一个特殊的模板,它可以创建一个能够进入特定目录并且为一个项目文件生成makefile 并且为它调用make的makefile
- TARGET 指定生成应用程序名:
- HEADERS 指定工程包含的头文件
- FORMS 工程中包含的 ui 设计文件
- SOURCES 工程中包含的源文件
- RESOURCES 工程包含的资源文件
- CONFIG += c++11 # 使用c++11的特性
按钮(QPushButton)
#include <QPushButton>
QPushButton *btn = new QPushButton;
// 设置父窗口
btn ->setParent(this);
// 设置文字
btn ->setText("文件");
// 移动位置
btn ->move(100,100)
/*第二种创建方式*/
QPushButton *btn2 = new QPushButton("哈比布",this);
// 重新指定窗口大小
this ->resize(600,400);
// 设置窗口标题
this ->setWindowTitle("第一个窗口");
// 限制窗口大小
this ->setFixedSize(600,400);
Qt窗口坐标系
以左上角为原点(0,0) X 向右增加 Y向下增加
Lambda
c++11 中的Lambda 表达式用于定义并创建匿名的函数对象
语法:
/*
[函数对象参数](操作符重载函数参数)mutable ->返回值{函数体}
*/
[] 函数对象参数 标识一个lambda 的开始 必须存在,函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。
- 空 没有使用任何函数对象参数
- = 函数体可以使用Lambda 所在作用范围内所有可见的局部变量,包括Lambda所在类的this,并且是值传递方式 相当于告诉编译器自动按值传递所有局部变量
- & 告诉编译器按引用传递了局部变量
- a 将a按值传递,按值传递时候,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的, 要修改a的拷贝 可以添加 mutable 修饰符
- &a 将a 按引用传递
- a,&b 将a 安值进行传递,b按引用传递
- =,&a,&b 除了a和b 按引用传递外,其他参数都按值传递
- &,a,b 除a和b 按值传递外,其他参数都按引用传递
mutable 可修改标识符:按值传递参数时,加上mutable 修饰符 可以安值传递进来的宝贝
函数返回值: -> 返回值类型 标识函数返回值的类型 当返回为void,或者只有一处 return的地方
{} 是函数体 这部分不能省略 但函数体可以为空
QMainWindow
QMainWindow 是一个为用户提供主窗口程序的类,包含一个菜单栏(men bar),多个工具栏(tool bars),多个铆接部件(dock widgets),一个状态栏 及一个中心部件(central widget),是许多应用程序的基础。
菜单栏:
一个主窗口最多只有一个菜单栏,位于主窗口顶部,主窗口标题栏下面
- 创建菜单栏
QMenuBar *menBar() const
- 创建菜单,调用QMenu成员函数 addMenu 来添加菜单
QAction* addMenu(QMenu *menu);
QMenu* addMenu(const QString &title);
QMenu* addMenu(const QIcon &icon,const QString &title);
- 创建菜单项
// 调用 QMenu 的成员函数 addAction来添加菜单项
QAction *addAction(const QString &text);
// addSeparator 用于添加分隔线
/*
Qt并没有专门的菜单项类,只是使用一个QAction类,抽象出公共的动作。当我们把QAction 对象添加到菜单,就显示一个菜单项,添加工具栏,就显示成一个工具按钮.用户可以通过点击菜单项,点击工具栏按钮,点击快捷键来激活这个动作。
*/
工具栏
主窗口的工具栏上可以有多个工具条。一般采用一个菜单对应一个工具条的方式,也可根据需要进行工具条的划分 QToolBar *toolBar = new QToolBar(this) 生成工具栏
- 直接调用QMainWindow类的addToolBar() 函数获取主窗口的工具条对象,每增加一个工具条需要调用一次该函数
- 插入工具条的动作,在工具条上添加操作,通过QToolBar 类的 addAction 函数添加
- 工具条是一个可移动的窗口,它的停靠区由QToolBar 的 allowAreas 决定
Qt::LeftToolBarArea 停靠在左侧
Qt::RightToolBarArea 停靠在右侧
Qt::TopToolBarArea 停靠在顶部
Qt::BottomToolBarArea 停靠在底部
Qt::AllToolBarAreas 以上四个位置都可停靠
使用 setAllowedAreas() 函数指定停靠区域
setAllowAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea)
使用setMoveable() 函数设定工具栏的可移动性:
状态栏
- 派生自QWidget 类,使用方法与QWidget 类似
- 状态栏也最多有一个
QStatusBar *stBar = statusBar();
setStatusBar(stBar);
QLabel *label = new QLabel(提示信息,this);
stBar ->addWidget(label); // 添加提示信息到左侧
QLabel *label2 = new QLabel("右侧提示信息",this);
stBar ->addPermanentWidget(label2);
铆接部件(浮动窗口)
QDockWidget *dock = new QDockWidget("标题",this);
addDockWidget(Qt::BottomDockWidgetArea,dock);
// 设置停靠范围
dock ->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
核心部件(中心部件)
核心部件只能有一个,中心显示的部件都可以作为核心部件
QTextEdit *edit = new QTextEdit(this);
setCentralWidget(edit);
资源文件
Qt 资源系统是一个跨平台的资源机制,用于将程序运行时所需要的资源以二进制的形式存储与可执行文件内部。如果你的程序需要加载特定的资源(图标、文本翻译等),那么,将其放置在资源文件中,就不需担心这些文件的丢失。如果你将资源以资源文件形式存储,它是会编译到可执行文件内部。使用Qt Creator可以很方便地创建资源文件。我们可以在工程上点右键,选择添加文件,在Qt分类下找到Qt资源文件:
点击 “选择…” 按钮,打开 “新建Qt 资源文件” 对话框。在这里我们输入资源文件的名称和路径:
点击下一步,选择所需要的版本控制系统,然后直接选择完成。我们可以在Qt Creator 的左侧文件列表中看到 “资源文件” 一项,也就是我们新创建的资源文件:
右侧的编辑区有个"添加",我们首先需要添加前缀,比如我们将前缀取名为images。然后选中这个前缀,继续点击添加文件,可以找到我们所需添加的文件。
对话框
对话框是GUI 程序中不可缺少的组成部分,很多不能或者不适合放入主窗口的功能组件都必须放在、对话框中设置。对话框通常会是一个顶层窗口,出现在程序的最上层,用于实现短期任务或者简洁的用户交互。
/*
设计一个类继承 QDialog (QDialog 及其子类,以及所有的Qt::Dialog类型的类 对于parent 指针都有额外的解释: 如果 parent 为 NULL,则该对话框会作为一个顶层窗口,否则则作为其父组件的子对话框 默认出现的位置是 parent 的中心 顶层窗口与非顶层窗口的区别在于,顶层窗口在任务栏会有自己的位置,而非顶层窗口则会共享其父组件的位置)
1. 模态对话框 会阻塞同一应用程序中其他窗口的输入
1) 应用程序级别的模态
当该种模态的对话框出现时,用户必须首先对对话框进行交互,直到关闭对话框,然后才能访问程序中替他的窗口
2) 该模态仅仅阻塞与对话框关联的窗口,但是依然允许用户与程序中其他窗口交互。窗口级别的模态尤其使用于多窗口模式。
2. 非模态对话框 不会阻塞
*/
布局管理
/*
1. 绝对定位
1.1 要素:组件的坐标 和长宽值
1.2 布局定位: 将组件放入布局,由布局管理器进行管理
* QHBoxLayout: 水平从左向右布局
* QVBoxLayout: 竖直从上到下布局
* QGridLayout:网格布局 类似于HTML的table
*/
widget
/*
使用Containers 容器进行布局
将控件放入容器中
在widget 中使用 水平、垂直、栅格 进行布局
*/
QLabel
/*
作用: 显示文本、图片、和动画
*/
// 设置显示内容
void setText(const QString &);
// 普通字符串文本显示
QLable *lable = new QLable;
lable ->setText("hello world");
// 显示HTML字符串 比如超链接
label ->setText("<a href='www.baidu'>百度一下</a>");
//显示图片 setPixmap(QLabel成员函数) 设置图片
void setPixmap(const QPixmap &)
// 步骤
QPixmap pixmap // 定义QPixmap 图像
pixmap.load(":资源路"); //加载图片 指定资源路径 比如:/image/boat.jpg
// 将图片放置到QLabel 中
QLabel *label = new QLabel;
label.setPixmap(pixmap);
// 显示动画 只能用于gif 动画
void setMoive(QMovie *moive);
// 步骤
QMovie *movie = new QMovie(":/Mario.gif"); //定义QMovie 对象并初始化
movie ->start(); // 播放加载动画
// 将动画放置到QLabel 中
QLabel *label = new QLabel;
label ->setMovie(movie);
QLineEdit
// 提供单行文本编辑框
QString text() const; // 获取编辑框内容
void setText(const QString &); // 设置编辑框内容
void setEchoMode(EchoMode mode); // 设置显示模式
/*
EchoMode 是枚举类型
QLineEdit::Normal 按照输入的内容显示
QLineEdit::NoEcho 不显示任何内容 无法看到用户的输入
QLineEdit::Password 密码模式 输入的字符根据平台转为特殊字符
QLineEdit::PasswordEchoEdit 编辑时显示字符,否则显示字符作为密码
void setTextMargins(int left,int top,int right,int bottom); // 设置QLineEdit左侧留出空白区域
*/
自定义控件
// SmallWidget控件 继承自 QWidget
SmallWidget::SmallWidget(QWidget* parent):QWidget(parent){
spin = new QSpinBox(this);
slider = new QSlider(Qt:Horizontal,this);
// 创建布局对象
QHBoxLayout *layout = new QHBoxLayout;
// 将控件添到布局中
layout ->addWidget(spin);
layout ->addWidget(slider);
// 将布局设置到窗口中
setLayout(layout);
// 信号槽添加
connect(spin,static_case<void (QSpinBox:: *)(int)>(&QSpinBox::valueChanged),slider,&QSlider::setValue);
connect(slider,&QSlider::valueChanged,spin,&QSpinBox::setValue);
}
消息机制和事件
/*
1. Qt程序 需要在main() 函数创建一个 QApplication对象 然后调用exec() 函数,执行exec() 函数之后,程序进入事件循环监听
2. Qt中所有的事件类 继承自QEvent, 这个事件传递给QObject的event() 函数,event()函数不直接处理事件,是按照事件对象类型分派特定的事件处理函数(event handler)
*/
/*
QWidget 事件处理回调函数
keyPressEvent()
keyReleaseEvent()
mouseDoubleClickEvent()
mouseMoveEvent()
mousePressEvent()
mouseReleaseEvent()
*/
class EventLabel : public QLabel{
protected:
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleseEvent(QMouseEvent *event);
};
void EventLabel::mouseMoveEvent(QMouseEvent *event){
this ->setText(QString("<center><h1>Press:(%1,%2)</h1></center>").arg(QString::number(event ->x()),QString::number(event ->y())));
}
void EventLabel::mousePressEvent(QMouseEvent *event){
this ->setText(QString("<center><h1>Press:(%1,%2)</h1></center>").arg(QString::number(event ->x()),QString::number(event ->y())));
}
void EventLabel::mouseReleaseEvent(QMouseEvent *event){
QString msg;
msg.sprintf("<center><h1>Relese:(%d,%d)</h1></center>",event ->x(),event ->y());
this ->setText(msg);
}
int main(int argc,char *argv[]){
QApplication *label = new EventLabel;
EventLabel *label = new EventLabel;
label ->setWindowTitle("MouseEvent~~~");
label ->resize(300,300);
label ->show();
return 0;
}
event()
/*
1.事件创建完毕后,Qt将这个事件对象传递给 QObject的 event() 函数,event() 函数负责分发给不同的事件处理器
2.如果希望在事件分发之前 做一些操作 重写event() 函数
*/
bool CustomWidget::event(QEvnet *e){
if(e ->type() == QEvent::KeyPress){
QKeyEvent *keyEvent = static_case<QKeyEvent *>(e);
if(keyEvent() ->key() == Qt::Key_Tab){
qDebug() << "You press tab";
return true;
}
}
return QWidget::event(e);
}
事件过滤器
class MainWindow : public QMainWindow{
public:
MainWinow();
protected:
bool eventFilter(QObject *obj,QEvent *event);
private:
QTextEdit *textEdit;
}
MainWindow::MainWindow(){
textEdit = new QTextEdit;
setCenterWidget(textEdit);
textEdit ->installEvent(this);
}
bool MainWindow::eventFilter(QObject *obj,QEvent *event){
if(obj == textEdit){
if(event ->type() == QEvent::KeyPress){
QKeyEvent * keyEvent = static_case<QKeyEvent *>(event);
qDebug() << keyEvent ->key();
return true;
}else{
return false;
}
}else{
return QMainWindow::eventFilter(obj,event);
}
}
/*
MainWindow 是我们定义一个类,重写eventFilter()函数,过滤特定组件上的事件,首先需要判断这个对象是不是我们感兴趣的组件
是返回true 也就是过滤了这个事件, false 不关注的事件 其他组件则调用父类的函数处理
eventFilter() 相当于创建了过滤器,可以通过removeEventFilter() 函数移除 过滤器
installEventFilter() 如果一个对象存在多个事件过滤器 最后一个安装的会第一个执行,先进先执行的顺序
文件系统
/*
QIODevice: 所有I/O 设备的父类
QFileDevice: 提供文件操作的通用实现
QFile: 访问本地文件或者嵌入资源
QTemporaryFile: 创建和访问本地文件系统的临时文件
QBuffer: 读写QbyteArray,内存文件
QProcess: 运行外部程序,处理进程间通讯
QAbstractSocket: 所有套接字类的父类
QTcpSocket: Tcp 协议网络数据传输
QUdpSocket: 传输UDP 报文
QSslSocket: 使用SSL/TLS 传输数据
*/
int main(int argc,char *argv[]){
QApplication app(argc,argv);
QFile file("in.txt");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "Open file failed";
return -1;
}else{
while(!file.atEnd()){
qDebug() << file.readLine();
}
}
QFileInfo info(file);
qDebug() << info.isDir();
qDebug() << info.isExacutable();
qDebug() << info.baseName();
qDebug() << info.completeBaseName();
qDebug() << info.suffix();
qDebug() << info.completeSuffix();
return app.exec();
}
更多推荐
Qt(c++)入门知识总结
发布评论