QT学习笔记
窗口与属性
所有关于窗口的代码都在有参构造函数编写
- 设置窗口标题
this->setWindowTitle("主界面");
- 设置窗口大小 单位为像素点
this->resize(1200,800); //可拖动来改变大小 this->setFixedSize(600,400); //固定大小
- 获取窗口标题
QString title = this->windowTitle(); qDebug() << title << endl;
按钮控件
按钮控件 在堆区开辟空间 释放父对象时候自动释放子对象
如果要将控件A和控件B在控件C上显示,就必须要设置A和B的父对 象为C
一般控件都要在堆区开辟空间,因为每一个控件在举放空间的时候,同时会释放子对象列表中所有子对象的空间,
如果你创建的对象是栈区的,局部变量函数执行完毕会自动释放一次,
并且父对象释放空间的时候又释放一次,就会释放两次出现问题。
如果实在静态区开辟空间,又无法释放空间,所以最终选择在堆区
开辟空间,当父对象释放空间是会自动释放子对象的空间
按钮初始化
QPushButton构造函数
QPushButton(const QIcon &icon, const QString &text, QWidget *parent = nullptr)
QPushButton(const QString &text, QWidget *parent = nullptr)
QPushButton(QWidget *parent = nullptr)
QPushButton *button = new QPushButton;
QPushButton *button2 = new QPushButton("登陆", this);
//若无参初始化,必须设置按钮的父对象,即将按钮添加至窗口
button->setParent(this);
设置按钮属性
-
设置按钮内容
button->setText("注册");
-
设置按钮大小
button->setFixedSize(100,50);
-
设置按钮位置
button->move(100,250);
-
获取按钮内容
QString text = button->text(); qDebug() << text << endl
信号与槽
信号与槽概念
信号槽是 Qt 框架引以为豪的机制之一。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣它就会使用连接 (connect) 函数,将想要处理的信号和自己的一个函数 (称为槽 (slot) ) 绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。
相当于Linux系统编程里的信号与信号处理函数,或类似于单片机内的中断与中断服务函数。
们主要研究的是四个东西:信号的发起者、信号、信号接收者、槽函数
接收者接收到信号的处理方式函数: connect
connect(const QObject *sender, const char *signal,
const QObject *receiver, const char *method)
功能:接收者接收到指定信号的处理操作
参数:
sender: 信号的发起者
signal: 指定的信号,根据实际情况来确定信号
信号可以使用系统的,也可以自定义
receiver:信号接收方
method: 槽函数,根据实际情况来确定槽函数
槽函数可以使用系统的,也可以自定义
示例
connect(buttonQuit, &QPushButton::clicked, this, &QWidget::close);
- 用户自定义槽函数
//1.使用全局函数定义槽函数
connect(button, &QPushButton::clicked, this, button_slot);
//2.成员函数作为槽函数
connect(button2, &QPushButton::clicked, this, button2_slot);
//3.使用lambda函数作为槽函数
connect(button, &QPushButton::clicked, [=](){
qDebug() << "注册按钮被按下" << endl;
});
切换到新窗口
//FirstWindow.cpp
//窗口切换
//创建新窗口 SecondWindow类需提前创建
SecondWindow *secondWindow = new SecondWindow;
//绑定信号和槽 buttonNext按钮需提前创建
connect(buttonNext,&QPushButton::clicked,this,[=](){
secondWindow->show(); //显示新窗口
this->hide(); //隐藏原窗口
});
切换回原窗口
通过新窗口发送自定义信号,原窗口捕获新窗口发送的自定义信号,检测到信号时,隐藏新窗口,显示原窗口。
secondwindow.h
//类中自定义信号
signals:
void returnSig(); //自定义信号
void returnSigVal(int val); //自定义信号 带值
secondwindow.cpp
//新窗口发信号
connect(button_return, &QPushButton::clicked,[=](){
//emit 窗口发信号
emit returnSig();
});
firstwindow.cpp
//主窗口接收到新窗口的自定义信号
connect(secondWindow,&SecondWindow::returnSig,this,[=](){
secondWindow->hide(); //隐藏新窗口
this->show(); //显示原窗口
});
带值的窗口切换
页面切换之间可以通过信号和槽实现数据的传递
secondwindow.cpp
connect(button_returnVal, &QPushButton::clicked,[=](){
//发信号的同时传值
emit returnSigVal(888); // 窗口发信号 带int的值,也可以其他类型,如结构体等
});
firstwindow.cpp
//主窗口接收到新窗口的自定义信号 并带值
connect(secondWindow,&SecondWindow::returnSigVal,this,[=](int val){
secondWindow->hide(); //隐藏新窗口
this->show(); //显示原窗口
qDebug() << val << endl;
});
信号与槽总结
自定义信号与槽需要注意的事项:
- 发送者和接收者都需要是QObject的子类 (当然,槽函数是全局函数Lambda表达式等无需接收者的时候除外)
- 信号和槽函数返回值是 void
- 信号只需要声明,不需要实现
- 槽函数需要声明也需要实现
- 槽函数可以是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;一般定义为共有的
- 使用emit在恰当的位置发送信号
- 使用connect()函数连接信号和槽
- 任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数
- 信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。如果信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少
信号槽的拓展
- 一个信号可以和多个槽相连
- 多个信号可以连接到同一个槽
- 槽可以被取消链接
- 信号槽可以断开
QLineEdit 控件
行编辑器,用于输入输出一行内容
-
设置编辑器大小
edit->setFixedSize(580,100);
-
设置编辑器位置
edit->move(20,20);
-
设置行编辑器字体大小和类型
edit->setFont((QFont("黑体", 16)));
-
获取编辑器内容
QString textedit = edit1->text();
-
初始化行编辑器
QLineEdit *edit1 = new QLineEdit("你好", this);
-
设置行编辑器内容
edit1->setText("hello wolrd");
-
清空行编辑器内容
edit1->clear();
QMainWindow窗口类
QMainWindow 是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bar)、多个铆接部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。
菜单栏
-
设置菜单栏, 并将该菜单栏放入窗口
QMenuBar *menuBar = new QMenuBar(this); this->setMenuBar(menuBar);
-
创建菜单 并添加至菜单栏
QMenu *menuFile = new QMenu("文件", menuBar); QMenu *menuEdit = new QMenu("编辑", menuBar); QMenu *menuBuild = new QMenu("构建", menuBar); menuBar->addMenu(menuFile); menuBar->addMenu(menuEdit); menuBar->addMenu(menuBuild);
-
在菜单添加菜单项
//方式1 直接利用menu的方法 addAction menuFile->addAction("新建文件或项目"); //方式2 创建菜单项 再添加至菜单 QAction *actNew = new QAction("打开文件或项目",this); menuFile->addAction(actNew);
-
菜单栏添加信号与槽
//给菜单项设置信号与槽函数 connect(actNew,&QAction::triggered,[=](){ qDebug() << "新建文件或项目" << endl; }); connect(actSave,&QAction::triggered,[=](){ qDebug() << "保存文件" << endl; });
-
在菜单中设置分割线
menuFile->addSeparator();
-
菜单项设置快捷方式
void setShortcut(const QKeySequence &shortcut) actNew->setShortcut(QKeySequence(tr("Ctrl+N"))); actSave->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_S));
工具栏
-
创建工具栏
#include <QToolBar> QMainWindow Class: 添加工具栏 void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar) void addToolBar(QToolBar *toolbar) Qt::ToolBarArea area: Qt::LeftToolBarArea Qt::RightToolBarArea Qt::TopToolBarArea Qt::BottomToolBarArea
QToolBar *toolbar = new QToolBar("工具栏", this); this>addToolBar(Qt::LeftToolBarArea,toolbar); //默认在上方
-
在工具栏中添加菜单项
//创建菜单项 QAction *actWel = new QAction("欢迎",this); QAction *actEdit = new QAction("编辑",this); QAction *actDebug = new QAction("Debug",this); QAction *actPro = new QAction("项目",this); //将菜单项添加至工具栏 toolbar->addAction(actWel); toolbar->addAction(actEdit); toolbar->addAction(actDebug); toolbar->addAction(actPro);
-
设置工具栏允许停靠区域
toolbar->setAllowedAreas(Qt::LeftToolBarArea);
-
设置是否允许工具栏浮动
toolbar->setFloatable(false);
状态栏
- 创建并设置状态栏
#include <QStatusBar> QStatusBar *statusBar = new QStatusBar(this); this->setStatusBar(statusBar);
- 在状态栏添加组件
//在状态栏添加按钮 行编辑器和标签 QLineEdit * edit1 = new QLineEdit("",this); QPushButton *button1 = new QPushButton("按钮",this); QLabel *label1 = new QLabel("标签",this); //默认左侧添加 statusBar->addWidget(edit1); statusBar->addWidget(button1); //右侧添加 statusBar->addPermanentWidget(label1);
铆接部件和中心部件
铆接部件一般就是窗口中的浮动窗口
- 创建铆接部件
#include <QDockWidget> void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget) area: Qt::LeftDockWidgetArea Qt::RightDockWidgetArea Qt::TopDockWidgetArea Qt::BottomDockWidgetArea
//创建铆接部件 QDockWidget *dockWidget = new QDockWidget("铆接部件标题",this); //将铆接部件添加至窗口 this->addDockWidget(Qt::RightDockWidgetArea, dockWidget);
- 中心部件
中心部件,没有专门的类,任意控件可作为中心控件,但必须是QWidget 及其子类。//将文本编辑器作为中心控件 //添加文本编辑器 QTextEdit *textEdit = new QTextEdit("",this); //将文本编辑器放入中心控件 this->setCentralWidget(textEdit);
注:在铆接部件和中心部件中也可以添加其他组件,这里不再赘述。
对话框
模态和非模态对话框
模态对话框:阻塞,原本窗口不允许操作,使用exec函数完成
非模态对话框:阻塞,原本窗口允许操作,使用show操作
模态与非模态的实现:
- 使用 QDialog::exec() 实现应用程序级别的模态对话框
- 使用 QDialog::open() 实现窗口级别的模态对话框
- 使用 QDialog::show() 实现非模态对话框。
void Widget::on_button1_clicked()
{
QDialog *dialog = new QDialog(this);
//开启模态对话框
dialog->exec();
}
void Widget::on_button2_clicked()
{
QDialog *dialog = new QDialog(this);
//开启非模态对话框
dialog->show();
}
消息对话框
#include <QMessageBox>
消息对话框都是静态成员函数
错误对话框:
critical(QWidget *parent, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons = Ok,
QMessageBox::StandardButton defaultButton = NoButton)
问题对话框:
question(QWidget *parent, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons = StandardButtons(Yes | No),
QMessageBox::StandardButton defaultButton = NoButton)
消息对话框:
information(QWidget *parent, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons = Ok,
QMessageBox::StandardButton defaultButton = NoButton)
常用控件
参考博文:Qt 绘制图片自适应窗口大小
QLabel
-
写字符串
void setText(const QString &)
-
读字符串
QString text() const
-
label显示图片
根据label大小缩放图片QPixmap pixmap; pixmap.load(":/images/images/dog.jpg"); ui->label2->setScaledContents(true); ui->label2->setPixmap(pixmap);
效果:图片填充整个label,且可以随label变化而变化,缺点则会改变图片比例导致有些图片显示不正常
根据label长宽等比例缩放图片
QPixmap pixmap; pixmap.load(":/images/images/dog.jpg"); //根据label宽度等比例缩放图片 ui->label2->setPixmap(pixmap.scaledToWidth(ui->label2->width())); //根据label高度等比例缩放图片 ui->label2->setPixmap(pixmap.scaledToHeight(ui->label2->height()));
-
设置动画
demo//设置动画 QMovie *movie = new QMovie(":/images/images/test2.gif"); ui->label2->setMovie(movie); movie->setScaledSize(QSize(521,371)); //设置大小 movie->start(); //开启 movie->setSpeed(200); //2倍数
事件
QLabel->
鼠标进入事件
void enterEvent(QEvent *event);
鼠标离开事件
void leaveEvent(QEvent *event);
鼠标移动事件
void mouseMoveEvent(QMouseEvent *event);
鼠标按下事件
void mousePressEvent(QMouseEvent *ev);
鼠标松开事件
void mouseReleaseEvent(QMouseEvent *ev);
鼠标双击事件
void mouseDoubleClickEvent(QMouseEvent *event);
设置鼠标的跟踪模式
this->setMouseTracking(true);
//true代表不用按下鼠标
QMouseEvent->
获取鼠标的全局坐标(相对windows窗口)
int globalX()
int globalY()
获取鼠标的局部坐标(相对当前控件)
int x()
int y()
获取鼠标左右键盘
QMouseEvent->
Qt::MouseButton button() const //判断按下的左右键
Qt::LeftButton 左键
Qt::RightButton 右键