qt-c++多窗口编程

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)

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QMessageBox>
#include <QButtonGroup>
#include <QDebug>
namespace Ui 
{
class Dialog;
}
class Dialog : public QDialog
{Q_OBJECT
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
private:Ui::Dialog *ui;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);
//连接按钮组槽函数
//按钮组信号buttonClicked(int),int是信号id
connect(btp,SIGNAL(buttonClicked(int)),this,SLOT(buttonClickedSlot(int)));
}
Dialog::~Dialog()
{
    delete ui;
    delete btp;
}
//按钮组槽函数
void Dialog::buttonClickedSlot(int id)
{if(id == 1){// 设置弹窗//弹窗返回值用StandardButton 枚举型变量接收QMessageBox::StandardButton stdb = QMessageBox::question(this,"question","是否需要关闭?");//判断弹窗返回值内容,执行相关命令if(stdb == QMessageBox::Yes){close();}else{}}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{qDebug() << "错误处理,没进入对应的模态对话框弹窗" ;}
}

2、QWidget类

QWidget类时所有窗口和组件的基类,之前认识此类更多是站在组件的角度,实际上QWidget身为所有窗口的基类,也具有很多窗口的特性,

新建一个项目,使自带窗口继承QWidget:

创建完成后运行时发现,与Dialog的窗口并无太大区别。表面上区别:

QWidget类作为所有窗口的基类,内部也规定了很多窗口的特性。

  • windowTitle : QString

QWidget()set窗口标记

  • windowFlags : Qt::WindowFlags

使用set函数这时多个标记,使用 “|”进行分割。实现无边框、窗口置于最上层。

setWindowFlags(Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint);

void	setWindowFlags(Qt::WindowFlags type)

设置窗口状态

// 参数是窗口的状态
Qt::WindowStates QWidget:: windowState() const

窗口状态:

窗口状态有时可能与窗口标记冲突。

示例代码:

setWindowState(Qt::WindowFullScreen);

3、parent参数

目前对parent参数的理解有以下几点:

  • parent参数表示子组件位于那个窗口给中。
  • parent参数决定了QWidget对象是独立窗口还是内嵌窗口。

实际上parent参数还表示Qt的内存回收机制,如果对象a作为对象b构造函数时的parent参数,表示对象a是对象b的父对象(不是继承关系)。这时一种内存回收的依赖关系,即对象b跟随对象a一并销毁。此时无需手动控制对象b进行销毁过程(手动调用delete)。

如果堆内存对象创建时不传递parent参数,表示对象销毁需要程序员手动销毁(需要手动delete)。

绝大多数情况下,建议堆内存对象传递parent参数。

这样做也有缺点,缺点内存占用,主窗口存在时,子窗口内存不会被释放掉。

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 "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{
    ui->setupUi(this);//手动添加选项(追加)
    ui->listWidget->addItem("第四页");
    ui->listWidget->addItem("第五页");// 连接信号槽,点击相应选项,发送相应序号,指定相应页码。connect(ui->listWidget,SIGNAL(currentRowChanged(int)),
            ui->stackedWidget,SLOT(setCurrentIndex(int)));
}
Widget::~Widget()
{
    delete ui;
}

5、QMainWindow主窗口类

QMainWindow是最适合作为主窗口的类型,因为包含多个组成部分。

5.1 QMenuBar菜单栏

菜单栏的构建可以通过Designer,也可以通过C++代码实现,不要混用。

代码实现菜单栏构建(不能与Designer混用),

1)向菜单栏中添加一级菜单

// 参数为菜单的文字
// 返回值是添加的菜单对象
QMenu * QMenuBar:: addMenu(const QString & title)

2)向菜单中添加动作

// 参数为动作的文字
// 返回值是添加的动作对象
QAction * QMenu:: addAction(const QString & text)

3)向菜单中添加菜单

// 参数为菜单显示的文字
// 返回值为添加的菜单对象
QMenu * QMenu:: addMenu(const QString & title)

例子:

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 * actionOpen = menuFile->addAction("打开");
    QAction * actionClose = menuFile->addAction("关闭");// 向一级菜单中添加二级菜单
    QMenu * menuRecent = menuFile->addMenu("最近访问的文件");// 向二级菜单中添加动作
    QAction * actionCpp = menuRecent->addAction("hello.cpp");
    QAction * actionH = menuRecent->addAction("hello.h");
}
MainWindow::~MainWindow()
{delete ui;
}

菜单信号

为了使QAction点击后有触发效果,需要使用对应的信号连接槽函数。信号函数如下:

//将带有文本的新段落追加到文本编辑的末尾。
void QTextEdit::​append(const QString & text)

示例:

QMainWindow.h

QMainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);//连接槽函数connect(ui->actionNew,SIGNAL(triggered()),this,SLOT(actionNewTriggeredSlot()));connect(ui->actionHello_cpp,SIGNAL(triggered()),this,SLOT(actionCppTriggeredSlot()));
}
MainWindow::~MainWindow()
{delete ui;
}
void MainWindow::actionNewTriggeredSlot()
{    ui->textBrowser->append("新创建了一个文件");
}
void MainWindow::actionCppTriggeredSlot()
{
    ui->textBrowser->append("打开了hello.cpp");
}

5.2 QToolBar 工具栏

工具栏按钮往往使用菜单栏中QAciton对象。但是需要给他设置图标。

// 添加一个已有的QAction(通常是设置图标)对象到工具栏
void QToolBar:: addAction(QAction * action)

5.3 QStatusBar 状态栏

可以使用槽函数进行信息展示:

// 在状态栏展示信息
// 参数1:展示的信息内容
// 参数2:信息展示的时间(单位毫秒),默认值0表示持续显示
void QStatusBar:: showMessage(const QString & message, int timeout = 0)[slot]

// 清空显示
void QStatusBar:: clearMessage()

显示5秒自动消失

通过QLabel控件,添加状态栏信息

状态栏显示拉伸比(拉伸因子):默认为0,按最小显示不拉伸

6、新建自定义窗口类

在一个项目中新创建一个Qt的窗口界面类,操作步骤如下:

  1. 在Qt Creator中选中项目名称,鼠标右键,点击“添加新文件”。
  2. 在弹出的窗口中,按照下图进行操作:

  1. 在弹出的窗口中选择界面模板后,点击“下一步”。

  1. 在弹出的窗口中,输入类名(注意帕斯卡/大驼峰),然后点击“下一步”。

  1. 在项目管理界面点击完成,可以看到新的窗口类文件已经创建完成,并添加到项目中了。

dialog.cpp

7、对象传值

7.1 父对象->子对象

此处指的是Qt的parent参数的依赖关系,并非继承关系。

【需求】,转动主窗口中的球,子窗口的球跟着转。

这种情况下最佳的解决方案1、信号槽传参 2、C++的成员函数传参。

7.2 子对象→父对象

【需求】:转动子窗口中的球,父窗口中的球跟着转。

这种情况最佳的解决方案是信号槽传参。子对象发射带参数的信号函数,父对象使用带参数的槽函数接收。

dialog.cpp

mydialog

8、事件机制

事件是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]

事件函数的基础使用只需要在对应的类中覆盖基类的事件函数即可。事件函数的参数就是包含了当前事件数据的对象。

// 绘制图片
// 参数1:横轴坐标
// 参数2:纵轴坐标
// 参数3:绘制宽度
// 参数4:绘制高度
// 参数5:绘制内容
void QPainter:: drawPixmap(int x, int y, int width, int height, const QPixmap & pixmap)

【需求】:按下键盘A、S、D、W控制进度条加或者减

void Dialog::keyPressEvent(QKeyEvent *event)
{if(event->key() == Qt::Key_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{}

事件函数的基础使用只需要在对应的类中覆盖基类的事件函数即可。事件函数的参数就是包含了当前事件数据的对象。

【问题】事件函数与信号槽的区别?

  • 事件由具体对象进行处理
  • 信号由具体对象主动产生
  • 改写事件处理函数可能导致程序行为发生改变
  • 信号是否存在对应的槽函数不会改变程序行为

6-多窗口编程

  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)

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QMessageBox>
#include <QButtonGroup>
#include <QDebug>
namespace Ui 
{
class Dialog;
}
class Dialog : public QDialog
{Q_OBJECT
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
private:Ui::Dialog *ui;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);
//连接按钮组槽函数
//按钮组信号buttonClicked(int),int是信号id
connect(btp,SIGNAL(buttonClicked(int)),this,SLOT(buttonClickedSlot(int)));
}
Dialog::~Dialog()
{
    delete ui;
    delete btp;
}
//按钮组槽函数
void Dialog::buttonClickedSlot(int id)
{if(id == 1){// 设置弹窗//弹窗返回值用StandardButton 枚举型变量接收QMessageBox::StandardButton stdb = QMessageBox::question(this,"question","是否需要关闭?");//判断弹窗返回值内容,执行相关命令if(stdb == QMessageBox::Yes){close();}else{}}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{qDebug() << "错误处理,没进入对应的模态对话框弹窗" ;}
}

2、QWidget类

QWidget类时所有窗口和组件的基类,之前认识此类更多是站在组件的角度,实际上QWidget身为所有窗口的基类,也具有很多窗口的特性,

新建一个项目,使自带窗口继承QWidget:

创建完成后运行时发现,与Dialog的窗口并无太大区别。表面上区别:

QWidget类作为所有窗口的基类,内部也规定了很多窗口的特性。

  • windowTitle : QString

QWidget()set窗口标记

  • windowFlags : Qt::WindowFlags

使用set函数这时多个标记,使用 “|”进行分割。实现无边框、窗口置于最上层。

setWindowFlags(Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint);

void	setWindowFlags(Qt::WindowFlags type)

设置窗口状态

// 参数是窗口的状态
Qt::WindowStates QWidget:: windowState() const

窗口状态:

窗口状态有时可能与窗口标记冲突。

示例代码:

setWindowState(Qt::WindowFullScreen);

3、parent参数

目前对parent参数的理解有以下几点:

  • parent参数表示子组件位于那个窗口给中。
  • parent参数决定了QWidget对象是独立窗口还是内嵌窗口。

实际上parent参数还表示Qt的内存回收机制,如果对象a作为对象b构造函数时的parent参数,表示对象a是对象b的父对象(不是继承关系)。这时一种内存回收的依赖关系,即对象b跟随对象a一并销毁。此时无需手动控制对象b进行销毁过程(手动调用delete)。

如果堆内存对象创建时不传递parent参数,表示对象销毁需要程序员手动销毁(需要手动delete)。

绝大多数情况下,建议堆内存对象传递parent参数。

这样做也有缺点,缺点内存占用,主窗口存在时,子窗口内存不会被释放掉。

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 "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{
    ui->setupUi(this);//手动添加选项(追加)
    ui->listWidget->addItem("第四页");
    ui->listWidget->addItem("第五页");// 连接信号槽,点击相应选项,发送相应序号,指定相应页码。connect(ui->listWidget,SIGNAL(currentRowChanged(int)),
            ui->stackedWidget,SLOT(setCurrentIndex(int)));
}
Widget::~Widget()
{
    delete ui;
}

5、QMainWindow主窗口类

QMainWindow是最适合作为主窗口的类型,因为包含多个组成部分。

5.1 QMenuBar菜单栏

菜单栏的构建可以通过Designer,也可以通过C++代码实现,不要混用。

代码实现菜单栏构建(不能与Designer混用),

1)向菜单栏中添加一级菜单

// 参数为菜单的文字
// 返回值是添加的菜单对象
QMenu * QMenuBar:: addMenu(const QString & title)

2)向菜单中添加动作

// 参数为动作的文字
// 返回值是添加的动作对象
QAction * QMenu:: addAction(const QString & text)

3)向菜单中添加菜单

// 参数为菜单显示的文字
// 返回值为添加的菜单对象
QMenu * QMenu:: addMenu(const QString & title)

例子:

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 * actionOpen = menuFile->addAction("打开");
    QAction * actionClose = menuFile->addAction("关闭");// 向一级菜单中添加二级菜单
    QMenu * menuRecent = menuFile->addMenu("最近访问的文件");// 向二级菜单中添加动作
    QAction * actionCpp = menuRecent->addAction("hello.cpp");
    QAction * actionH = menuRecent->addAction("hello.h");
}
MainWindow::~MainWindow()
{delete ui;
}

菜单信号

为了使QAction点击后有触发效果,需要使用对应的信号连接槽函数。信号函数如下:

//将带有文本的新段落追加到文本编辑的末尾。
void QTextEdit::​append(const QString & text)

示例:

QMainWindow.h

QMainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);//连接槽函数connect(ui->actionNew,SIGNAL(triggered()),this,SLOT(actionNewTriggeredSlot()));connect(ui->actionHello_cpp,SIGNAL(triggered()),this,SLOT(actionCppTriggeredSlot()));
}
MainWindow::~MainWindow()
{delete ui;
}
void MainWindow::actionNewTriggeredSlot()
{    ui->textBrowser->append("新创建了一个文件");
}
void MainWindow::actionCppTriggeredSlot()
{
    ui->textBrowser->append("打开了hello.cpp");
}

5.2 QToolBar 工具栏

工具栏按钮往往使用菜单栏中QAciton对象。但是需要给他设置图标。

// 添加一个已有的QAction(通常是设置图标)对象到工具栏
void QToolBar:: addAction(QAction * action)

5.3 QStatusBar 状态栏

可以使用槽函数进行信息展示:

// 在状态栏展示信息
// 参数1:展示的信息内容
// 参数2:信息展示的时间(单位毫秒),默认值0表示持续显示
void QStatusBar:: showMessage(const QString & message, int timeout = 0)[slot]

// 清空显示
void QStatusBar:: clearMessage()

显示5秒自动消失

通过QLabel控件,添加状态栏信息

状态栏显示拉伸比(拉伸因子):默认为0,按最小显示不拉伸

6、新建自定义窗口类

在一个项目中新创建一个Qt的窗口界面类,操作步骤如下:

  1. 在Qt Creator中选中项目名称,鼠标右键,点击“添加新文件”。
  2. 在弹出的窗口中,按照下图进行操作:

  1. 在弹出的窗口中选择界面模板后,点击“下一步”。

  1. 在弹出的窗口中,输入类名(注意帕斯卡/大驼峰),然后点击“下一步”。

  1. 在项目管理界面点击完成,可以看到新的窗口类文件已经创建完成,并添加到项目中了。

dialog.cpp

7、对象传值

7.1 父对象->子对象

此处指的是Qt的parent参数的依赖关系,并非继承关系。

【需求】,转动主窗口中的球,子窗口的球跟着转。

这种情况下最佳的解决方案1、信号槽传参 2、C++的成员函数传参。

7.2 子对象→父对象

【需求】:转动子窗口中的球,父窗口中的球跟着转。

这种情况最佳的解决方案是信号槽传参。子对象发射带参数的信号函数,父对象使用带参数的槽函数接收。

dialog.cpp

mydialog

8、事件机制

事件是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]

事件函数的基础使用只需要在对应的类中覆盖基类的事件函数即可。事件函数的参数就是包含了当前事件数据的对象。

// 绘制图片
// 参数1:横轴坐标
// 参数2:纵轴坐标
// 参数3:绘制宽度
// 参数4:绘制高度
// 参数5:绘制内容
void QPainter:: drawPixmap(int x, int y, int width, int height, const QPixmap & pixmap)

【需求】:按下键盘A、S、D、W控制进度条加或者减

void Dialog::keyPressEvent(QKeyEvent *event)
{if(event->key() == Qt::Key_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{}

事件函数的基础使用只需要在对应的类中覆盖基类的事件函数即可。事件函数的参数就是包含了当前事件数据的对象。

【问题】事件函数与信号槽的区别?

  • 事件由具体对象进行处理
  • 信号由具体对象主动产生
  • 改写事件处理函数可能导致程序行为发生改变
  • 信号是否存在对应的槽函数不会改变程序行为

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/633096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝凌EIS智慧协同平台frm_form_upload.aspx接口存在任意文件上传漏洞

@[toc] 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. 蓝凌EIS智慧协同平台frm_form_upload.aspx接…

C#winform上位机开发学习笔记2-串口助手的中文支持功能添加

分为两步&#xff1a; 1.串口接收支持中文显示 1.1.在软件初始化时写入此代码以支持汉字显示 //串口接收支持中文显示serialPort1.Encoding Encoding.GetEncoding("GB2312"); //串口1的解码支持GB2312汉字 2.串口发送支持中文输出 //支持中文输出Encoding Chine…

OpenAI 公布2024选举虚假信息打击计划

据统计&#xff0c;2024 年预计将有 50 多个国家举行大选&#xff0c;虚假信息的威胁成为人们关注的焦点。 人工智能聊天机器人 ChatGPT 和图像生成器 DALL-E 的开发商 OpenAI 近日宣布了一项新的措施&#xff0c;以防止在今年大选之前再次出现虚假信息滥用和误导事件。 本周…

域环境权限提升

Windows系统配置错误 在Windows系统中&#xff0c;攻击者通常会通过系统内核溢出漏来提权&#xff0c;但是如果碰到无法通过系统内核溢出漏洞法国提取所在服务器权限的情况&#xff0c;就会系统中的配置错误来提权。Windows系统中常见哦欸之错误包括管理员凭证配置错误&#x…

思绪记忆:伦敦金是以美元计价的黄金!

伦敦金是以美元计价的黄金衍生投资品种&#xff0c;是一种交易网络遍及各个主要市场的黄金保证金交易方式。目前投资者通过香港到伦敦金平台入市&#xff0c;只需要付出2%的保证金&#xff0c;就可以拥有一手100盎司、价值20多万的标准化黄金合约的交易权益&#xff0c;无论在涨…

ChatGPT Plus续费充值,到账延迟,如何申诉?

ChatGPT Plus充值总是到账延迟比较严重&#xff0c;一般多是通过充值链接代充值遇到&#xff0c;如果是账号登陆充值&#xff0c;是即时到账。但是有的客户不愿意提供账号密码&#xff0c;遇到延迟到账的情况如何解决呢&#xff1f;客户可按下面操作申诉&#xff0c;可快速到账…

npm pnpm yarn 报错或常见问题处理集锦

各种卡死&#xff0c;报错问题处理汇总 1. npm 安装 卡死了怎么办&#xff0c;npm # 切换源 npm config set registry https://registry.npmmirror.com # 查看源 npm config get registry2. pnpm安装 卡死了怎么办 方法1&#xff1a;切换源 npx pnpm config set registry h…

政务服务场景为何要打造AI交互数字人?

随着Chat GPT兴起&#xff0c;越来越多服务场景通过AI交互数字人以多模态交互形式实现人机交互。如近日昆山市档案馆推出了AI交互数字人“昆兰”&#xff0c;数字人设置于市档案馆一楼大厅入口处&#xff0c;市民可以与AI交互数字人进行实时问答交流&#xff0c;了解总书记关于…

Kafka-多线程消费及分区设置

目录 一、Kafka是什么&#xff1f;消息系统&#xff1a;Publish/subscribe&#xff08;发布/订阅者&#xff09;模式相关术语 二、初步使用1.yml文件配置2.生产者类3.消费者类4.发送消息 三、减少分区数量1.停止业务服务进程2.停止kafka服务进程3.重新启动kafka服务4.重新启动业…

Leetcode刷题笔记题解(C++):200. 岛屿数量

思路&#xff1a;利用深度优先搜索的思路来查找1身边的1&#xff0c;并且遍历之后进行0替换防止重复dfs&#xff0c;代码如下所示 class Solution { public:int numIslands(vector<vector<char>>& grid) {int row grid.size();int col grid[0].size();int n…

滚动菜单+图片ListView

目录 Fruit.java FruitAdapter MainActivity activity_main.xml fruit.xml 整体结构 Fruit.java public class Fruit {private String name;private int imageId;public Fruit(String name, int imageId) {this.name name;this.imageId imageId;}public String getNam…

【从零开始学习Redis | 第七篇】利用Redis构造全局唯一ID(含其他构造方法)

目录 前言&#xff1a; 什么是全局唯一ID&#xff1f; 尝试构造全局唯一ID&#xff1a; 其他构造全局唯一ID的方法 1.基于数据库自增构造全局唯一ID&#xff1a; 2.基于UUID构造全局唯一ID&#xff1a; 3.基于雪花算法构造全局唯一ID&#xff1a; 总结&#xff1a; 前…

在客户端访问远程Linux服务器的私有IP地址的URL

文章目录 环境背景SSH tunnel和正向/反向代理步骤第一步第二步效果考一考 其它多次跳转另一种方法&#xff1a;正向代理 参考 环境 服务器&#xff1a;Ubuntu 22.04客户端&#xff1a;Mac 14.2.1 背景 在远程Linux服务器上搭建了minikube环境。minikube提供了dashboard功能&…

ChatGPT付费创作系统V2.5.8独立版+前端

小狐狸ChatGPT付费创作系统V2.5.8版本最大特点新增PC端绘画功能全新升级。该版本为编译版无开源&#xff0c;本版本同样处理了后台弹窗、暗链网址。单独制作了2.5.5升级至2.5.8数据库升级包及升级文件&#xff0c;直接导入即可使用。本版本升级后唯一BUG后台绘画功能新增的翻译…

酷开科技将AR技术多方应用 打造全能酷开系统

酷开系统AR技术的核心是通过计算机视觉、图形渲染和深度感知等技术&#xff0c;将虚拟物体或信息精确地叠加到现实世界的场景中。通过智能摄像头捕捉真实环境的图像和视频&#xff0c;结合3D渲染技术&#xff0c;生成与现实场景相融合的虚拟图像&#xff0c;实现虚实结合的视觉…

最新ChatGPT/GPT4科研应用与AI绘图及论文高效写作

详情点击链接&#xff1a;最新ChatGPT/GPT4科研应用与AI绘图及论文高效写作 一OpenAI 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析&#xff0c;AI画图&#xff0c;图像识别&#xff0c;文档API 3.GPT Store 4.从0到1创建自己的GPT应用 5. 模型Gemini以及大模型Clau…

编译FFmpeg4.3.1 、x264并移植到Android

1、前言 FFmpeg 既是一款音视频编解码工具&#xff0c;同时也是一组音视频编解码开发套件。 2、准备工作 系统&#xff1a;LinuxNDK&#xff1a;android-ndk-r21b-linux-x86_64.zipFFmpeg&#xff1a;ffmpeg-snapshot.tar.bz2x264&#xff1a;x264 3、下载NDK 在linux环境中…

hanlp,pkuseg,jieba,cutword分词实践

总结&#xff1a;只有jieba,cutword,baidu lac成功将色盲色弱成功分对,这两个库字典应该是最全的 hanlp[持续更新中] https://github.com/hankcs/HanLP/blob/doc-zh/plugins/hanlp_demo/hanlp_demo/zh/tok_stl.ipynb import hanlp # hanlp.pretrained.tok.ALL # 语种见名称最…

RabbitMQ交换机(3)-Topic

1.Topic模式 RabbitMQ的Topic模式是一种基于主题的消息传递模式。它允许发送者向一个特定的主题&#xff08;topic&#xff09;发布消息&#xff0c;同时&#xff0c;订阅者也可以针对自己感兴趣的主题进行订阅。 在Topic模式中&#xff0c; 主题通过一个由单词和点号组成的字…

Git教程学习:07 打标签

文章目录 0 前言1 列出标签2 创建标签3 附注标签4 轻量标签5 后期打标签6 共享标签7 删掉标签8 检查标签 0 前言 像其他版本控制系统&#xff08;VCS&#xff09;一样&#xff0c;Git 可以给仓库历史中的某一个提交打上标签&#xff0c;以示重要。 比较有代表性的是人们会使用…