嵌入式学习-QT-Day06
六、多窗口编程
1、QMessageBox 消息对话框
2、QWidget类
3、parent参数
4、堆栈窗口(QStackedWidget)
5、新建自界说窗口类
6、对象传值
6.1 父对象 → 子对象
6.2 子对象 → 父对象
7、事件机制
8、QMainWindow主窗口类
8.1 QMenuBar 菜单栏
8.2 QToolBar 工具栏
8.3 QStatusBar状态栏
六、多窗口编程
1、QMessageBox 消息对话框
QMessageBox继续自QDialog。显式一个模态对话框,用于用户前台信息关照或者询问用户问题,并接收问题答案。
QDialog的Qt源码中,派生类往往都是一些在特定场合下使用的预设好的对话框窗口,这些窗口的使用无需创建对象,直接使用静态成员函数弹窗,使用函数的返回值作为这个窗口的效果。
- // QMessageBox的弹窗函数
- // 参数1:parent参数
- // 参数2:窗口标题
- // 参数3:信息内容,窗口展示的信息
- // 返回值:用户点击的按钮类型
- StandardButton critical(QWidget * parent, const QString & title, const QString & text)
- StandardButton information(QWidget * parent, const QString & title, const QString & text)
- StandardButton question(QWidget * parent, const QString & title, const QString & text)
- StandardButton warning(QWidget * parent, const QString & title, const QString & text)
- [static]
复制代码
dialog.h
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- #include <QMessageBox>
- #include <QButtonGroup>
- namespace Ui {
- class Dialog;
- }
- class Dialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit Dialog(QWidget *parent = 0);
- ~Dialog();
- private:
- Ui::Dialog *ui;
- private:
- QButtonGroup *btp;
- private slots:
- void buttonClickedSlot(int);
- };
- #endif // DIALOG_H
复制代码 dialog.cpp
- #include "dialog.h"
- #include "ui_dialog.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- btp = new QButtonGroup(this);
- btp->addButton(ui->pushButtonQ,1);
- btp->addButton(ui->pushButtonI,2);
- btp->addButton(ui->pushButtonW,3);
- btp->addButton(ui->pushButtonC,4);
- connect(btp,SIGNAL(buttonClicked(int)),
- this,SLOT(buttonClickedSlot(int)));
- }
- Dialog::~Dialog()
- {
- delete btp;
- delete ui;
- }
- void Dialog::buttonClickedSlot(int id)
- {
- if(id == 1)
- {
- // 设置弹窗
- QMessageBox::StandardButton stdb = QMessageBox::question(this,"question","是否需要关闭?");
- if(stdb == QMessageBox::Yes)
- {
- close();
- }
- else if(stdb == QMessageBox::No)
- {
- }
- }
- else if(id == 2)
- {
- QMessageBox::information(this,"information","已加载完成!!!!");
- }
- else if(id == 3)
- {
- QMessageBox::warning(this,"warning","您的输入有误!!!");
- }
- else if(id == 4)
- {
- QMessageBox::critical(this,"critical","程序异常,缺少必要文件!!");
- }
- else
- {
- }
- }
复制代码 2、QWidget类
QWidget类是所有窗口和组件的基类,之前熟悉此类更多是站在组件的角度,现实上QWidget身为所有窗口的基类,本身也具有许多窗口的特性,窗口类的继续布局如下所示:
新建一个项目,使自带的窗口类继续QWidget。
创建完成后运行时发现,与dialog的窗口并无太大区别。表面区别有:
- #include "widget.h"
- #include <QApplication>
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
-
- // 当QWidget类的构造函数parent参数使用默认值0时,表示创建的是独立窗口
- // 当QWidget类的构造函数parent参数传递参数时,新创建的QWidget类对象会成为子窗口(内嵌窗口)
- Widget w;
- w.show();
- return a.exec();
- }
复制代码 QWidget类作为所有窗口的基类,内部也规定了许多窗口特性:
- windowFlags : Qt::WindowFlags(窗口标志)
使用setter函数设置多个窗口标志,使用 | 分割(多个窗口标志之间可能会出现冲突)。实现窗口置于最上层、且没有边框。
设置窗口状态:
- // 设置窗口状态
- // 参数为窗口状态
- void QWidget::setWindowState(Qt::WindowStates windowState)
复制代码
3、parent参数
目前对parent参数的理解有以下几点:
- parent参数表现子组件位于那个窗口中。
- parent参数还决定了QWidget对象是独立窗口照旧内嵌窗口
现实上parent参数还表现Qt的内存接纳机制,如果对象a作为对象b的构造函数的parent参数时,表现对象a是对象b的父对象,这是一种内存接纳的依靠关系,即对象b跟随对象a一并销毁。此时无需手动控制对象b的销毁过程(手动调用delete)。
如果堆内存对象创建时不通报parent参数,表现对对象调用必要步调员手动delete。
这样做也有缺点,缺点就是内存占用,主窗口还存在时,子窗口内存不会被开释掉。
dialog.h
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- #include <QDebug>
- namespace Ui {
- class Dialog;
- }
- class Dialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit Dialog(QWidget *parent = 0);
- ~Dialog();
- private:
- Ui::Dialog *ui;
- private slots:
- void buttonClickedSlot();
- void buttonThisClickedSlot();
- };
- #endif // DIALOG_H
复制代码 dialog.cpp
- #include "dialog.h"
- #include "ui_dialog.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- connect(ui->pushButton,SIGNAL(clicked()),
- this,SLOT(buttonClickedSlot()));
- connect(ui->pushButtonThis,SIGNAL(clicked()),
- this,SLOT(buttonThisClickedSlot()));
- }
- Dialog::~Dialog()
- {
- qDebug() << "析构函数";
- delete ui;
- }
- void Dialog::buttonClickedSlot()
- {
- Dialog *dlg = new Dialog;
- dlg->show();
- }
- void Dialog::buttonThisClickedSlot()
- {
- Dialog *dlg = new Dialog(this);
- dlg->show();
- }
复制代码 4、堆栈窗口(QStackedWidget)
通常作为独立窗口的内嵌窗口(组件),并于QListWidget举行联动。
dialog.cpp
- #include "dialog.h"
- #include "ui_dialog.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- // 连接信号槽
- connect(ui->listWidget,SIGNAL(currentRowChanged(int)),
- ui->stackedWidget,SLOT(setCurrentIndex(int)));
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
复制代码 5、新建自界说窗口类
在一个项目中新建一个Qt的窗口界面类,操纵步骤如下:
- 在QtCreator中选中项目名称,鼠标右键,点击添加新文件。
- 在弹出的窗口中,按照下图所示举行操纵。
在弹出的窗口中选择界面模板后,点击“下一步”
在弹出的窗口,输入类名(注意帕斯卡命名法/大驼峰命名法)然后点击下一步。
在项目管理界面点击完成,可以看到新的窗口类文件就已经添加到项目中了。
ui格式如下:
dialog.h
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- #include "mydialog.h"
- namespace Ui {
- class Dialog;
- }
- class Dialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit Dialog(QWidget *parent = 0);
- ~Dialog();
- private:
- Ui::Dialog *ui;
- private slots:
- void btnClickedSlot();
- };
- #endif // DIALOG_H
复制代码 dialog.cpp
- #include "dialog.h"
- #include "ui_dialog.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- connect(ui->pushButton,SIGNAL(clicked()),
- this,SLOT(btnClickedSlot()));
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
- void Dialog::btnClickedSlot()
- {
- MyDialog *mydlg = new MyDialog(this);
- mydlg->show();
- }
复制代码 6、对象传值
6.1 父对象 → 子对象
此处指的是Qt的parent参数的依靠关系,并非继续关系。后文同。
【需求】转动左边球,右边球跟着转。
这种环境下最佳的办理方案是使用C++的成员函数传参。
dialog.h
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- #include "mydialog.h"
- namespace Ui {
- class Dialog;
- }
- class Dialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit Dialog(QWidget *parent = 0);
- ~Dialog();
- private:
- Ui::Dialog *ui;
- MyDialog *mydlg;
- private slots:
- void btnClickedSlot();
- void valueChangedSlot(int);
- };
- #endif // DIALOG_H
复制代码 dialog.cpp
- #include "dialog.h"
- #include "ui_dialog.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- connect(ui->pushButton,SIGNAL(clicked()),
- this,SLOT(btnClickedSlot()));
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
- void Dialog::btnClickedSlot()
- {
- mydlg = new MyDialog(this);
- mydlg->show();
- connect(ui->dial,SIGNAL(valueChanged(int)),
- this,SLOT(valueChangedSlot(int)));
- }
- void Dialog::valueChangedSlot(int value)
- {
- mydlg->setDialValue(value);
- }
复制代码 mydialog.h
- #ifndef MYDIALOG_H
- #define MYDIALOG_H
- #include <QDialog>
- namespace Ui {
- class MyDialog;
- }
- class MyDialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit MyDialog(QWidget *parent = 0);
- ~MyDialog();
- void setDialValue(int value);
- private:
- Ui::MyDialog *ui;
- };
- #endif // MYDIALOG_H
复制代码 myDialog.cpp
- #include "mydialog.h"
- #include "ui_mydialog.h"
- MyDialog::MyDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::MyDialog)
- {
- ui->setupUi(this);
- }
- MyDialog::~MyDialog()
- {
- delete ui;
- }
- void MyDialog::setDialValue(int value)
- {
- ui->dial->setValue(value);
- }
复制代码 6.2 子对象 → 父对象
此处指的是Qt的parent参数的依靠关系,并非继续关系。
【需求】转动子窗口的球,父窗口的球跟着转。
这种环境最佳的办理方案是信号槽传参,子对象发射带参数的信号函数,父对象使用带参数的槽函数接收。
dialog.h
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- #include "mydialog.h"
- namespace Ui {
- class Dialog;
- }
- class Dialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit Dialog(QWidget *parent = 0);
- ~Dialog();
- private:
- Ui::Dialog *ui;
- MyDialog *mydlg;
- private slots:
- void btnClickedSlot();
- void valueChangedSlot(int);
- void valueDialogSlot(int);
- };
- #endif // DIALOG_H
复制代码 dialog.cpp
- #include "dialog.h"
- #include "ui_dialog.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- connect(ui->pushButton,SIGNAL(clicked()),
- this,SLOT(btnClickedSlot()));
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
- void Dialog::btnClickedSlot()
- {
- mydlg = new MyDialog(this);
- mydlg->show();
- connect(ui->dial,SIGNAL(valueChanged(int)),
- this,SLOT(valueChangedSlot(int)));
- connect(mydlg,SIGNAL(valueSignal(int)),
- this,SLOT(valueDialogSlot(int)));
- }
- void Dialog::valueChangedSlot(int value)
- {
- mydlg->setDialValue(value);
- }
- void Dialog::valueDialogSlot(int value)
- {
- ui->dial->setValue(value);
- }
复制代码 myDialog.h
- #ifndef MYDIALOG_H
- #define MYDIALOG_H
- #include <QDialog>
- namespace Ui {
- class MyDialog;
- }
- class MyDialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit MyDialog(QWidget *parent = 0);
- ~MyDialog();
- void setDialValue(int value);
- private:
- Ui::MyDialog *ui;
- signals:
- void valueSignal(int); // 声明带参数的自定义信号
- private slots:
- void valueChangedSlot(int);
- };
- #endif // MYDIALOG_H
复制代码 myDialog.cpp
- #include "mydialog.h"
- #include "ui_mydialog.h"
- MyDialog::MyDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::MyDialog)
- {
- ui->setupUi(this);
- connect(ui->dial,SIGNAL(valueChanged(int)),
- this,SLOT(valueChangedSlot(int)));
- }
- MyDialog::~MyDialog()
- {
- delete ui;
- }
- void MyDialog::setDialValue(int value)
- {
- ui->dial->setValue(value);
- }
- void MyDialog::valueChangedSlot(int value)
- {
- // 发射带参数的信号函数
- emit valueSignal(value);
- }
复制代码 7、事件机制
事件是Qt的一种底层机制,经过层层筛选,步调员可以在通报的层级中检测或者处置惩罚这些事件。
本次学习主要在窗口类中实现事件函数,从而检测到事件的通报。利用事件的触发机制,从而实现一些特定的效果。事件函数浩繁,包罗但不限于:
- // 绘制事件
- void QWidget::paintEvent(QPaintEvent * event) [virtual protected]
- // 大小改变事件
- void QWidget::resizeEvent(QResizeEvent * event) [virtual protected]
- // 鼠标按压事件
- void QWidget::mousePressEvent(QMouseEvent * event) [virtual protected]
- // 鼠标释放事件
- void QWidget::mouseReleaseEvent(QMouseEvent * event) [virtual protected]
- // 鼠标双击事件
- void QWidget::mouseDoubleClickEvent(QMouseEvent * event) [virtual protected]
- // 鼠标移动事件
- void QWidget::mouseMoveEvent(QMouseEvent * event) [virtual protected]
- // 移动事件
- void QWidget::moveEvent(QMoveEvent * event) [virtual protected]
- // 按键按压事件
- void QWidget::keyPressEvent(QKeyEvent * event) [virtual protected]
- // 按键释放事件
- void QWidget::keyReleaseEvent(QKeyEvent * event) [virtual protected]
- // 获取焦点事件
- void QWidget::focusInEvent(QFocusEvent * event) [virtual protected]
- // 失去焦点事件
- void QWidget::focusOutEvent(QFocusEvent * event) [virtual protected]
- // 关闭事件
- void QWidget::closeEvent(QCloseEvent * event) [virtual protected]
- // 鼠标进入事件
- void QWidget::enterEvent(QEvent * event) [virtual protected]
- // 鼠标离开事件
- void QWidget::leaveEvent(QEvent * event) [virtual protected]
复制代码 事件函数的基础使用只必要在对应的类中覆盖基类的事件函数即可。事件函数的参数就是包含了当前事件数据的对象。
绘制事件:
dialog.h
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- #include <QPainter> // 画家类
- #include <QPixmap>
- #include <QDebug>
- namespace Ui {
- class Dialog;
- }
- class Dialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit Dialog(QWidget *parent = 0);
- ~Dialog();
- private:
- Ui::Dialog *ui;
- void paintEvent(QPaintEvent * event);
- };
- #endif // DIALOG_H
复制代码 dialog.cpp
- #include "dialog.h"
- #include "ui_dialog.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
- void Dialog::paintEvent(QPaintEvent *event)
- {
- // 创建画家类对象
- // 参数为 QPaintDevice *表示可绘制的对象
- QPainter painter(this);
- QPixmap map(":/new/prefix1/meinv.png");
- // 绘制图片
- // 参数1:横轴坐标
- // 参数2:纵轴坐标
- // 参数3:绘制宽度
- // 参数4:绘制高度
- // 参数5:绘制内容
- painter.drawPixmap(0,0,this->width(),this->height(),map);
- qDebug() << this->width() << this->height();
- qDebug() << this->x() << this->y();
- }
复制代码 【案例】按下键盘A、D、W、S键控制进度条加或者减
dialog.h
- #ifndef DIALOG_H
- #define DIALOG_H
- #include <QDialog>
- #include <QPainter> // 画家类
- #include <QPixmap>
- #include <QDebug>
- #include <QKeyEvent>
- namespace Ui {
- class Dialog;
- }
- class Dialog : public QDialog
- {
- Q_OBJECT
- public:
- explicit Dialog(QWidget *parent = 0);
- ~Dialog();
- private:
- Ui::Dialog *ui;
- void paintEvent(QPaintEvent * event);
- void keyPressEvent(QKeyEvent * event);
- };
- #endif // DIALOG_H
复制代码 dialog.cpp
- #include "dialog.h"
- #include "ui_dialog.h"
- Dialog::Dialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::Dialog)
- {
- ui->setupUi(this);
- }
- Dialog::~Dialog()
- {
- delete ui;
- }
- void Dialog::paintEvent(QPaintEvent *event)
- {
- // 创建画家类对象
- // 参数为 QPaintDevice *表示可绘制的对象
- QPainter painter(this);
- QPixmap map(":/new/prefix1/meinv.png");
- // 绘制图片
- // 参数1:横轴坐标
- // 参数2:纵轴坐标
- // 参数3:绘制宽度
- // 参数4:绘制高度
- // 参数5:绘制内容
- painter.drawPixmap(0,0,this->width(),this->height(),map);
- qDebug() << this->width() << this->height();
- qDebug() << this->x() << this->y();
- }
- void Dialog::keyPressEvent(QKeyEvent *event){ if(event->key() == Qt::Key_A) // 如果按键是A { int value = ui->progressBar->value(); ui->progressBar->setValue(--value); } else if(event->key() == Qt::Key_D) { int value = ui->progressBar->value(); ui->progressBar->setValue(++value); } else if(event->key() == Qt::Key_W) { ui->progressBar->setValue(100); } else if(event->key() == Qt::Key_S) { ui->progressBar->setValue(0); } else { }}
复制代码 8、QMainWindow主窗口类
QMainWindow是最适互助为主窗口的类型,因为其中包含了多个构成部分:
8.1 QMenuBar 菜单栏
菜单栏的构成如下所示:
菜单栏的构建可以通过Designer,也可以通过C++代码实现,但是不要混用。
- // 向菜单栏中添加一级菜单
- // 参数为菜单的文字
- // 返回值是添加的菜单对象
- QMenu * QMenuBar::addMenu(const QString & title)
复制代码 - // 向菜单中添加动作
- // 参数为菜单的文字
- // 返回值是添加的动作对象
- QAction * QMenu::addAction(const QString & text)
复制代码 QMainwindow.cpp
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- QMenu* menuFile = ui->menuBar->addMenu("文件");
- QMenu* menuEdit = ui->menuBar->addMenu("编辑");
- QMenu* menuHelp = ui->menuBar->addMenu("帮助");
- // 向一级菜单中添加动作
- QAction* actionNew = menuFile->addAction("新建");
- QAction* actionSave = menuFile->addAction("保存");
- QAction* actionOpen = menuFile->addAction("打开");
- // 向一级菜单中添加二级菜单
- QMenu* menuRecent = menuFile->addMenu("最近访问的文件");
- // 向二级菜单中添加动作
- QAction* actionCpp = menuRecent->addAction("hello.cpp");
- QAction* actionH = menuRecent->addAction("hello.h");
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
复制代码
mainwindow.h
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- #include <QMenu>
- namespace Ui {
- class MainWindow;
- }
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
- private:
- Ui::MainWindow *ui;
- private slots:
- void actionNewTriggredSlot();
- void actionCppTriggredSlot();
- };
- #endif // MAINWINDOW_H
复制代码 mainwindow.cpp
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- // QMenu* menuFile = ui->menuBar->addMenu("文件");
- // QMenu* menuEdit = ui->menuBar->addMenu("编辑");
- // QMenu* menuHelp = ui->menuBar->addMenu("帮助");
- // // 向一级菜单中添加动作
- // QAction* actionNew = menuFile->addAction("新建");
- // QAction* actionSave = menuFile->addAction("保存");
- // QAction* actionOpen = menuFile->addAction("打开");
- // // 向一级菜单中添加二级菜单
- // QMenu* menuRecent = menuFile->addMenu("最近访问的文件");
- // // 向二级菜单中添加动作
- // QAction* actionCpp = menuRecent->addAction("hello.cpp");
- // QAction* actionH = menuRecent->addAction("hello.h");
- connect(ui->action_2,SIGNAL(triggered()),
- this,SLOT(actionNewTriggredSlot()));
- connect(ui->actionHello_cpp,SIGNAL(triggered()),
- this,SLOT(actionCppTriggredSlot()));
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- }
- void MainWindow::actionNewTriggredSlot()
- {
- ui->textBrowser->append("新建了一个文件");
- }
- void MainWindow::actionCppTriggredSlot()
- {
- ui->textBrowser->append("打开了hello.cpp");
- }
复制代码 8.2 QToolBar 工具栏
工具栏按钮往往使用菜单栏中的QAction对象,但是必要给QAction设置图标。
8.3 QStatusBar状态栏
QStatusBar支持自界说样式,可以通过下面的函数添加组件。
- // 状态栏显式信息
- // 参数1:组件对象
- // 参数2:拉伸因子
- void QStatusBar::addWidget(QWidget * widget, int stretch = 0)
复制代码
普通使用可以通过下面槽函数举行显示和消除。
- // 在状态栏展示信息
- // 参数1:显示的信息内容
- // 参数2:信息显示的时间(单位毫秒),默认值0表示持续显示
- void QStatusBar::showMessage(const QString & message, int timeout = 0)[slot]
复制代码
- // 清空显示
- void QStatusBar::clearMessage()[slot]
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |