QMainWindow 是一个为用户提供主窗口程序的类:
- 包含一个菜单栏(menu bar)
- 多个工具栏(tool bars)
- 多个铆接部件(dock widgets)
- 一个状态栏(status bar)
- 一个中心部件(central widget)
- 许多应用程序的基础,如文本编辑器,图片编辑器等。
一个主窗口最多 只有一个菜单栏
(MenuBar)。位于主窗口顶部、主窗口标题栏下面。
创建菜单栏:
//创建菜单栏:
#include
QMenuBar --> QMenuBar(QWidget *parent = Q_NULLPTR)
//添加菜单栏:
QMainWindow --> void setMenuBar(QMenuBar *menuBar)
创建菜单:
QMenu
的成员函数 addMenu
来添加菜单//创建菜单:
#include
QMenu --> QMenu(const QString &title, QWidget *parent = Q_NULLPTR)
//添加菜单:
MenuBar --> QAction *addMenu(QMenu *menu)
创建菜单项:
QMenu
的成员函数 addAction
来添加菜单项//创建菜单项:
#include
QAction --> QAction(const QString &text, QObject *parent = nullptr)
//添加菜单项:
QMenu --> addAction(const QAction *action)
示例:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setFixedSize(1200, 800);
setWindowTitle("菜单栏");
//获取当前窗口自带的菜单栏
//QMenuBar *menuBar = this->menuBar();
//1.1 创建一个菜单栏
QMenuBar *menuBar = new QMenuBar(this);
//1.2 设置菜单栏
this->setMenuBar(menuBar);
//2.1 创建菜单
QMenu *fileMenu = new QMenu("文件",menuBar);
//2.2 将菜单添加到菜单栏
menuBar->addMenu(fileMenu);
QMenu *editMenu = new QMenu("编辑",menuBar);
menuBar->addMenu(editMenu);
//3.1 创建活动(QAction)
QAction * na = new QAction("新建文件或项目",fileMenu);
//3.2 给菜单添加活动
fileMenu->addAction(na);
//4.1 菜单中的菜单
QMenu *sonMenu = new QMenu("最近打开的文件",fileMenu);
//4.2 菜单中添加菜单
fileMenu->addMenu(sonMenu);
QAction * sonA01 = new QAction("D:/a.txt",sonMenu);
QAction * sonA02 = new QAction("D:/b.txt",sonMenu);
QAction * sonA03 = new QAction("D:/c.txt",sonMenu);
sonMenu->addAction(sonA01);
sonMenu->addAction(sonA02);
sonMenu->addAction(sonA03);
//5 添加分割线
fileMenu->addSeparator();
QAction * exitA = new QAction("退出",fileMenu);
fileMenu->addAction(exitA);
//6 添加快捷键
na->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_N));
oa->setShortcut(QKeySequence(tr("ctrl+o")));
//7 设置信号与槽(点击退出关闭窗口)
connect(exitA,QAction::triggered,this,QWidget::close);
connect(na,QAction::triggered,[](){
qDebug() << "新建文件或项目活动被触发了" << endl;
});
}
MainWindow::~MainWindow()
{
delete ui;
}
结果:
主窗口的工具栏上可以有多个工具条,通常采用一个菜单对应一个工具条的的方式,也可根据需要进行工具条的划分。
注意:QMainWindow UI页面中自带一个工具栏,如果不想要需删除
相关函数:
//创建工具栏:
#include
QToolBar --> QToolBar(QWidget *parent = Q_NULLPTR)
//添加工具栏:
QMainWindow -->
void addToolBar(QToolBar *toolbar)
void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
Qt::LeftToolBarArea //左边显示
Qt::RightToolBarArea //右边显示
Qt::TopToolBarArea //上边显示
Qt::BottomToolBarArea //下边显示
//设置位置
setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea)
//设置可移动性
setMoveable(false) // 工具条不可移动, 只能停靠在初始化的位置上
示例:
//1.1 创建工具栏1
QToolBar *tbar01 = new QToolBar(this);
//1.2 添加工具类
this->addToolBar(tbar01);
//2.1 创建活动
QAction *tAction01 = new QAction("啦啦啦",tbar01);
//2.2 工具栏添加活动
tbar01->addAction(tAction01);
QAction *tAction02 = new QAction("德玛西亚",tbar01);
tbar01->addAction(tAction02);
//创建工具栏2
QToolBar *tbar02 = new QToolBar(this);
QAction *tAction03 = new QAction("艾欧尼亚",tbar01);
tbar02->addAction(tAction03);
//3 添加工具栏时指定停靠位置
this->addToolBar(Qt::LeftToolBarArea,tbar02);
//4 设置不允许拖拽改变其停靠位置
tbar01->setMovable(false);
状态栏也只能最多有一个
派生自 QWidget 类,使用方法与 QWidget 类似
相关函数:
//创建状态栏:
QStatusBar --> QStatusBar(QWidget *parent = Q_NULLPTR);
//将控件添加到左边栏
void addWidget(QWidget *widget, int stretch = 0)
//将控件添加到右边栏
void addPermanentWidget(QWidget *widget, int stretch = 0)
//添加状态栏:
QMainWindow --> void setStatusBar(QStatusBar *statusbar)
示例:
/*
QStatusBar:状态栏
*/
//创建状态栏
QStatusBar *sBar = new QStatusBar(this);
//设置状态栏
this->setStatusBar(sBar);
QPushButton *btn01 = new QPushButton("按钮1",sBar);
QPushButton *btn02 = new QPushButton("按钮2",sBar);
QPushButton *btn03 = new QPushButton("按钮3",sBar);
sBar->addWidget(btn01);
sBar->addWidget(btn02);
//添加到固定位置
sBar->addPermanentWidget(btn03);
相关函数:
//创建铆接部件:
QDockWidget -->QDockWidget(const QString &title, QWidget *parent = Q_NULLPTR)
//添加铆接部件:
QMainWindow -->void addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockwidget)
Qt::LeftDockWidgetArea //左边
Qt::RightDockWidgetArea //右边
Qt::TopDockWidgetArea //上边
Qt::BottomDockWidgetArea //下边
示例
/*
QDockWidget: 铆接部件
*/
QDockWidget *dock1 = new QDockWidget("铆接1", this);
this->addDockWidget(Qt::LeftDockWidgetArea, dock1);
QAction *action01 = new QAction("铆接部件中的内容", dock1);
dock1->addAction(action01);
除了以上几个部件,中心显示的部件都可以作为核心部件,例如一个记事本文件,可以利用QTextEdit 做核心部件。
setCentralWidget(QWidget *widget)
示例:
//中心控件
// //1.按钮中心控件
// QPushButton *btn04 = new QPushButton("中心控件",this);
// //设置中心控件
// //参数QWidget
// this->setCentralWidget(btn04);
//2.自定义设计师界面类,CenterWidget继承于Widget 设置 为中心控件
CenterWidget *c = new CenterWidget(this);
this->setCentralWidget(c);
Qt 资源系统是一个跨平台的 资源机制
,用于将程序运行时所需要的资源以二进制的形式存储于可执行文件内部。如果你的程序需要加载特定的资源(图标、文本翻译等),那么,将其放置在资源文件中,就再也不需要担心这些文件的丢失。也就是说,如果你将资源以资源文件形式存储,它是会编译到可执行文件内部。
1,创建image文件夹
2,将所需图片资源存储到该文件夹中
3,将该文件夹拷贝到项目下
4,先点击添加,选择添加文件
//label设置
QPixmap pix;
pix.load(":/image/up.png");
ui->label->setPixmap(pix);
//设置窗口图标
this->setWindowIcon(QIcon(":/image/Sunny.jpg"));
头文件:
#include
对话框
是 GUI 程序中不可或缺的组成部分。很多不能或者不适合放入主窗口的功能组件都必须放在对话框中设置。
对话框通常会是一个 顶层窗口
,出现在程序最上层
,用于实现 短期任务
或者 简洁的用户交互
。
Qt 中使用 QDialog 类实现对话框。就像主窗口一样,我们通常会设计一个类,继承 QDialog。
QDialog(及其子类,以及所有 Qt::Dialog 类型的类)的对于其 parent 指针
都有额外的解释:
parent
为 NULL
,则该对话框会作为一个 顶层窗口
;否则
则作为其父组件的子对话框
(此时,其默认出现的位置是 parent的中心
)。对话框分为 模态对话框 和 非模态对话框 :
模态对话框
:就是会 阻塞同一应用程序中其它窗口的输入
。 模态对话框很常见,比如“打开文件”功能。你可以尝试一下记事本的打开文件,当打开文件对话框出现时,我们是不能对除此对话框之外的窗口部分进行操作的。非模态对话框
:与 此相反
,例如查找对话框,我们可以在 显示
着查找对话框的同时
,继续
对记事本的内容进行编辑。Qt 的内置对话框大致分为以下几类:
注意:
- 使用
QDialog::exec()
实现应用程序级别的模态对话框- 使用
QDialog::open()
实现窗口级别的模态对话框- 使用
QDialog::show()
实现非模态对话框
对应的类:QMessageBox
对应的静态函数:Static Public Members
类名直接调用,不用创建对象;
//关于
void about(QWidget *parent, const QString &title, const QString &text)
//错误提示
StandardButton critical(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)
//信息提示
StandardButton information(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)
//问题(yes,no)
StandardButton question(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons = StandardButtons( Yes | No ), StandardButton defaultButton = NoButton)
//警告提示
StandardButton warning(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)
示例1:widget.cpp
文件,信息框
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setFixedSize(800,600);
setWindowTitle("对话框演示");
QPushButton *btn01 = new QPushButton("信息对话框", this);
btn01->setFixedSize(200, 50);
connect(btn01, QPushButton::clicked, [&](){
//this在父窗口中心显示
QMessageBox::information(this, "信息提示", "你好世界!");
});
}
Widget::~Widget()
{
delete ui;
}
示例2:错误提示框
QPushButton *btn02 = new QPushButton("错误对话框", this);
btn02->setFixedSize(200, 50);
btn02->move(0,50);
connect(btn02, QPushButton::clicked, [&](){
QMessageBox::critical(this, "错误提示", "严重问题");
});
示例3:警告提示框
QPushButton *btn03 = new QPushButton("警告对话框", this);
btn03->setFixedSize(200, 50);
btn03->move(0,100);
connect(btn03, QPushButton::clicked, [&](){
QMessageBox::warning(this, "警告提示", "请注意问题");
});
示例4:关于提示框
QPushButton *btn04 = new QPushButton("关于对话框", this);
btn04->setFixedSize(200, 50);
btn04->move(0,150);
connect(btn04, QPushButton::clicked, [&](){
QMessageBox::about(this, "关于提示", "今天有点冷");
});
示例5:选择提示框
QPushButton *btn05 = new QPushButton("选择对话框", this);
btn05->setFixedSize(200, 50);
btn05->move(0,200);
connect(btn05, QPushButton::clicked, [&](){
QMessageBox::StandardButton tag;
tag = QMessageBox::question(this, "选择", "c++/QT难不难");
if(tag == QMessageBox::StandardButton::Yes)
{
qDebug() << "有点难" << endl;
}
else
{
qDebug() << "just so so" << endl;
}
});
对应的类:QFileDialog
示例:
QPushButton *btn06 = new QPushButton("文件对话框",this);
btn06->setFixedSize(200,50);
btn06->move(0,250);
connect(btn06,QPushButton::clicked,[&](){
QString filePath;
//./当前用户目录下
filePath = QFileDialog::getOpenFileName(this,"文件","./","*.cpp");
qDebug() << filePath << endl;
});
对应的类:QColorDialog
示例:
QPushButton *btn07 = new QPushButton("颜色对话框",this);
btn07->setFixedSize(200,50);
btn07->move(0,300);
connect(btn07,QPushButton::clicked,[&](){
QColor color;
color = QColorDialog::getColor(Qt::green,this,"颜色选择");
qDebug() << color.red() << endl;
qDebug() << color.green() << endl;
qDebug() << color.blue() << endl;
});
//返回RGB
//255
//85
//0
对应的类:QFontDialog
示例:
QPushButton *btn08 = new QPushButton("字体对话框",this);
btn08->setFixedSize(200,50);
btn08->move(0,350);
connect(btn08,QPushButton::clicked,[&](){
bool tag = true;
QFont font;
font = QFontDialog::getFont(&tag,QFont("宋体"),NULL,"字体选择");
qDebug() << font.family() << endl;
qDebug() << font.pointSize() << endl;
});
//"宋体"
//12
使用
QPushButton *btn10 = new QPushButton("自定义对话框",this);
btn10->setFixedSize(200,50);
btn10->move(0,450);
connect(btn10,QPushButton::clicked,[&](){
//创建对话框对象
MyDialog *myDialog = new MyDialog(this);
//设置标题与icon
myDialog->setWindowTitle("自定义对话框");
//显示
myDialog->exec();
});
Qt 提供了两种组件定位机制:绝对定位和布局定位
1) 绝对定位: 是一种最原始的定位方法,给出这个组件的坐标和长宽值。
2) 布局定位: 只要把组件放入某一种布局,布局由专门的布局管理器进行管理,当需要调整大小或者位置的时候,Qt使用对应 的布局管理器进行调整。
Qt 提供的布局中以下三种是我们最常用的:
QHBoxLayout:按照水平方向从左到右布局;
QVBoxLayout:按照竖直方向从上到下布局;
QGridLayout:在一个网格中进行布局,类似于 HTML 的 table;
缺点:这4个为系统给我们提供的布局的控件,但是使用起来不是非常的灵活
作用:
setText设置文本
text获取文本
setPixmap显示图片
setMovie显示动画
示例:
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//寻找控件
//ui -> 控件名称
//获取文本
qDebug() << ui->text01->text() << endl;
//修改文本
ui->text01->setText("德玛西亚");
//设置图片
ui->img->setPixmap(QPixmap(":/image/LuffyQ.png"));
//设置动画
QMovie * movie = new QMovie(":/image/mario.gif");
ui->mlable->setMovie(movie);
//没有start则不会显示
movie->start();
//停止播放,放开后就只是图片
// movie->stop();
}
Widget::~Widget()
{
delete ui;
}
常用函数:
QString text() const
void setText(const QString &)
void setEchoMode(EchoMode mode)
QLineEdit::Normal //模式显示方式,按照输入的内容显示。
QLineEdit::NoEcho //不显示任何内容,此模式下无法看到用户的输入。
QLineEdit::Password //密码模式,输入的字符会根据平台转换为特殊字符。
QLineEdit::PasswordEchoOnEdit //编辑时显示字符否则显示字符作为密
void setTextMargins(int left, int top, int right, int bottom)
示例:
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//设置文本
ui->lineEdit->setText("请输入");
//密文显示
ui->lineEdit->setEchoMode(QLineEdit::Password);
}
Widget::~Widget()
{
delete ui;
}
//按钮点击
void Widget::on_pushButton_clicked()
{
//获取文本
QString str = ui->lineEdit->text();
qDebug() << str << endl;
}
代码:
//widget.h 头文件
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_rbn01_clicked();
void on_rbn02_clicked();
private:
Ui::Widget *ui;
QString sex;
QString hun;
QStringList list;
};
#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_rbn01_clicked()
{
hun = ui->rbn01->text();
qDebug() << hun << endl;
}
void Widget::on_rbn02_clicked()
{
hun = ui->rbn02->text();
qDebug() << hun << endl;
}
//多选
//arg1为2选中
//arg1为0取消
//转到槽函数用:stateChanged
void Widget::on_cb01_stateChanged(int arg1)
{
if(arg1 == 2)
{
list.append(ui->cb01->text());
}
else{
list.removeOne(ui->cb01->text());
}
for(int i = 0; i < list.size(); i++)
{
qDebug() << list.at(i) << " ";
}
qDebug() << endl;
}
void Widget::on_cb02_stateChanged(int arg1)
{
if(arg1 == 2)
{
list.append(ui->cb02->text());
}
else{
list.removeOne(ui->cb02->text());
}
for(int i = 0; i < list.size(); i++)
{
qDebug() << list.at(i) << " ";
}
qDebug() << endl;
}
void Widget::on_cb03_stateChanged(int arg1)
{
if(arg1 == 2)
{
list.append(ui->cb03->text());
}
else{
list.removeOne(ui->cb03->text());
}
for(int i = 0; i < list.size(); i++)
{
qDebug() << list.at(i) << " ";
}
qDebug() << endl;
}
示例:
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//下拉列表添加数据
ui->comboBox->addItem("西安");
//存入QStringList
QStringList list;
list << "西安" << "渭南" << "安康";
ui->comboBox->addItems(list);
}
Widget::~Widget()
{
delete ui;
}
//转到槽用currentIndexChanged(QString)
void Widget::on_comboBox_currentIndexChanged(const QString &arg1)
{
qDebug() << arg1 << endl;
}
//loginwidget.h登录页面头文件
#ifndef LOGINWIDGET_H
#define LOGINWIDGET_H
#include
#include
#include
#include
#include "mainwidget.h"
namespace Ui {
class LoginWidget;
}
class LoginWidget : public QWidget
{
Q_OBJECT
public:
explicit LoginWidget(QWidget *parent = 0);
~LoginWidget();
private slots:
void on_pushButton_clicked();
private:
Ui::LoginWidget *ui;
MainWidget *mWidget;
};
#endif // LOGINWIDGET_H
//loginwidget.cpp 登录页面源文件
#include "loginwidget.h"
#include "ui_loginwidget.h"
LoginWidget::LoginWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::LoginWidget)
{
ui->setupUi(this);
//创建mWidget对象
mWidget = new MainWidget();
//退出登录,发信号跳回登录页面,并关闭主页面
connect(mWidget,MainWidget::goBack,[&](){
this->show();
mWidget->close();
});
}
LoginWidget::~LoginWidget()
{
delete ui;
}
void LoginWidget::on_pushButton_clicked()
{
//获取账号与密码输入框中的内容
QString uname = ui->username->text();
QString pword = ui->password->text();
if(uname == "admin" && pword == "123456")
{
//登录成功,跳转主页面,并隐藏登录页面
mWidget->show();
this->hide();
}
else
{
QMessageBox::critical(this,"登录错误","账号密码不匹配");
}
}
//mainwidget.h 主页面头文件
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include
namespace Ui {
class MainWidget;
}
class MainWidget : public QWidget
{
Q_OBJECT
public:
explicit MainWidget(QWidget *parent = 0);
~MainWidget();
signals:
//信号函数
void goBack();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWidget *ui;
};
#endif // MAINWIDGET_H
//mainwidget.cpp 主页面源文件
#include "mainwidget.h"
#include "ui_mainwidget.h"
MainWidget::MainWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MainWidget)
{
ui->setupUi(this);
this->setFixedSize(800,600);
}
MainWidget::~MainWidget()
{
delete ui;
}
void MainWidget::on_pushButton_clicked()
{
//点击 退出登录 跳回登录页面
emit this->goBack();
}
定时器事件
定时器对象
延迟执行
使用步骤:
1,在头文件中声明int型变量用于记录定时器id
2,在头文件中声明定时器事件函数
3,在源文件中开启定时器
4,重写定时器事件函数
定时器id:为了后面关闭
相关函数:
//开启定时器
int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer)
//停止定时器
void killTimer(int id);
//定时器事件函数
virtual void timerEvent(QTimerEvent *e)
示例:
//widget.h 头文件
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_btnstart_clicked();
void on_btn_over_clicked();
virtual void timerEvent(QTimerEvent *event);
private:
Ui::Widget *ui;
int id;
};
#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_btnstart_clicked()
{
//开启定时器
//参数:间隔时间,单位毫秒
//返回值:开启的定时器唯一标识符,关闭时需要该标识符
//间隔时间到了以后,会发出timeout信号
//此时会执行timerEvent函数
id = this->startTimer(1000);
}
void Widget::on_btn_over_clicked()
{
this->killTimer(id);
}
void Widget::timerEvent(QTimerEvent *event)
{
QString num = ui->numlabel->text();
int x = num.toInt();
x--;
ui->numlabel->setText(QString::number(x));
if(x <= 0)
{
this->killTimer(id);
}
}
使用步骤:
1,在头文件中声明定时器对象
2,在源文件中创建定时器对象
3,设置定时器的信号与槽
4,在适当位置启动或停止定时器
相关函数与信号:
//函数
QTimer(QObject *parent = Q_NULLPTR);
void start(int msec);
//参数:延迟时间
void start();
void stop();
//信号
void timeout(QPrivateSignal);
示例:
//头文件
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_btns_clicked();
void on_btno_clicked();
void setNum();
private:
Ui::Widget *ui;
QTimer *timer;
};
#endif // WIDGET_H
//源文件
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//创建对象
timer = new QTimer();
//直接发信号
connect(timer,QTimer::timeout,this,Widget::setNum);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_btns_clicked()
{
//开启
timer->start(1000);
}
void Widget::on_btno_clicked()
{
//停止
timer->stop();
}
void Widget::setNum()
{
QString num = ui->label->text();
int x = num.toInt();
x--;
ui->label->setText(QString::number(x));
if(x <= 0)
{
timer->stop();
}
}
注意:只会执行一次
头文件:QTimer
相关函数:
void singleShot(int msec, Functor functor)
示例:
QTimer::singleShot(5000,[&](){
qDebug() << "延迟执行" << endl;
});