qt三个窗口基本类

news/2025/1/16 5:57:57/

qt是一个gui框架,做图形用户界面的,本地可以跑,跟一些web框架那种做好点击网址跳转的不一样,python的web常用的flask和django,python也有gui框架比如pytqt和tkinter,这个专栏讲qt5,用c++写gui

qt三个窗口基本类

在创建项目的时候就是下面这三个

在这里插入图片描述

他们的关系如下:
在这里插入图片描述

  • 常用的窗口类有 3 个

    • 在创建 Qt 窗口的时候,需要让自己的窗口类继承上述三个窗口类的其中一个
  • QWidget
    
    • 所有窗口类的基类
    • Qt 中的控件 (按钮,输入框,单选框…) 也属于窗口,基类都是 QWidget
    • 可以内嵌到其他窗口中:没有边框
    • 可以不内嵌单独显示:独立的窗口,有边框
  • QDialog
    
    • 对话框类,有模态和非模态两种显示
    • 不能内嵌到其他窗口中
  • QMainWindow
    
    • 有工具栏,状态栏,菜单栏
    • 不能内嵌到其他窗口中

4.2 窗口的显示

  • 内嵌窗口
    • 依附于某一个大的窗口,作为了大窗口的一部分
    • 大窗口就是这个内嵌窗口的父窗口
    • 父窗口显示的时候, 内嵌的窗口也就被显示出来了
  • 不内嵌窗口
    • 这类窗口有边框,有标题栏
    • 需要调用函数才可以显示
c++
// QWidget是所有窗口类的基类, 调用这个提供的 show() 方法就可以显示将任何窗口显示出来
// 非模态显示
void QWidget::show();	// 显示当前窗口和它的子窗口// 对话框窗口的非模态显示: 还是调用show() 方法
// 对话框窗口的模态显示
[virtual slot] int QDialog::exec();

给出示例代码:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } //ui 界面的mainwindow类
QT_END_NAMESPACEclass MainWindow : public QMainWindow//QMainWindow Qt的基本窗口类
{Q_OBJECT// 这个宏是为了能够使用Qt中的信号槽机制public:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;// 定义指针指向窗口的 UI 对象
};
#endif // MAINWINDOW_H

testwidget.h

#ifndef TESTWIDGET_H
#define TESTWIDGET_H#include <QWidget>namespace Ui {
class TestWidget;
}class TestWidget : public QWidget
{Q_OBJECTpublic:explicit TestWidget(QWidget *parent = nullptr);~TestWidget();private:Ui::TestWidget *ui;
};#endif // TESTWIDGET_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "testwidget.h"
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) //窗口ui 被实例化了,ui界面也是个类其实
{ui->setupUi(this);//把cpp的mainwindow类和ui的绑定在一起//一般在qt的构造函数中进程初始化操作//显示当前窗口的时候,显示另一个窗口,TestWidget//我们就在MainWindow的构造函数里面构造TestWidget对象,main只调用MainWindow就行//创建窗口对象,没有给w对象指定父对象TestWidget* w=new TestWidget;w->show(); //显示窗口
}MainWindow::~MainWindow()
{delete ui;
}

testwidget.cpp

#include "testwidget.h"
#include "ui_testwidget.h"TestWidget::TestWidget(QWidget *parent) :QWidget(parent),ui(new Ui::TestWidget)
{ui->setupUi(this);
}TestWidget::~TestWidget()
{delete ui;
}

入口函数:main

#include "mainwindow.h"#include <QApplication>//应用程序类,后台维护了一个事件循环int main(int argc, char *argv[])
{QApplication a(argc, argv); //创建了一个应用程序的对象,只有一个MainWindow w;   //创建了一个窗口对象w.show();        //显示窗口return a.exec();   //阻塞函数,程序进入了事件循环
}

Qdwidget类

我们去创建一个ui界面类
在这里插入图片描述

进去选择模板,我选择了一个基类空模板widget类,进去之后自动跳到ui界面,我们就可以拖动控件去定制自己想要的样子
在这里插入图片描述
在这里插入图片描述

这么写会发现就是两个窗口

改一下MainWindow构造函数如下:

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) //窗口ui 被实例化了,ui界面也是个类其实
{ui->setupUi(this);//把cpp的mainwindow类和ui的绑定在一起//一般在qt的构造函数中进程初始化操作//显示当前窗口的时候,显示另一个窗口,TestWidget//我们就在MainWindow的构造函数里面构造TestWidget对象,main只调用MainWindow就行//创建窗口对象,没有给w对象指定父对象,他就是独立窗口//想要显示他,就得show一下
#if 0TestWidget* w=new TestWidget;w->show();
#else   //指定父对象,他就不是单独的窗口了//这样的话当前父窗口显示的时候,子窗口就一并显示出来//这时候子窗口是没有边框的//只有独立窗口是有边框的TestWidget* w=new TestWidget(this);#endif
}

会发现只有一个窗口,且窗口内嵌

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hpFOGE0A-1685551154091)(../AppData/Roaming/Typora/typora-user-images/image-20230531232002079.png)]

这样一会有边框一会没有,因为我们这个继承的是QWidget类,上面有讲他特性

我们在加个Qdialog类,看看效果

注意:qt里面这些类都是继承关系,你看传this,传的其实是父对象,也就是基类指针指向子类,达到多态的那种感觉

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) //窗口ui 被实例化了,ui界面也是个类其实
{ui->setupUi(this);//把cpp的mainwindow类和ui的绑定在一起//一般在qt的构造函数中进程初始化操作//显示当前窗口的时候,显示另一个窗口,TestWidget//我们就在MainWindow的构造函数里面构造TestWidget对象,main只调用MainWindow就行//创建窗口对象,没有给w对象指定父对象
#if 0TestWidget* w=new TestWidget;w->show();
#elseTestWidget* w=new TestWidget(this);
#endifTestDialog* dlg=new TestDialog(this);//对于他写不写父对象无所谓的,这个this//非模态dlg->show();
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1mFtjOTr-1685551154092)(../AppData/Roaming/Typora/typora-user-images/image-20230531233154528.png)]

注意非模态,对于多个子窗口是可以来回切换的

把TestWidget那块if取开,让他走上面那两句代码,因为那两句没有传父类widget对象,这样TestWidget窗口的就不会去嵌入主窗口,你在运行就会有三个窗口且来回鼠标可以去切换,点的动的!

而模态是什么呢?就是子窗口之间不能切换了

对于Dialog的模态模式,需要调用exec这个阻塞函数,跑下面代码,会发现没有主窗口,两个子窗口没法鼠标去切换,这就是模态。那是因为有exec这个函数存在,阻塞在那,dialog这个窗口不退出,相当于主窗口mainwindows没有构造成功,当你把dialog这个窗口关了,主窗口就出来了

这个模态也就dialog能调了,对了还有构造dialog的时候,那个this父类对象传不传都是可以的,对于mainwindowsnew构造的时候来说也是传不传this都一样,毕竟都是从widget继承来的,就widget传和不传才有什么独立和嵌套之分。我上面也有说他们区别

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) //窗口ui 被实例化了,ui界面也是个类其实
{ui->setupUi(this);//把cpp的mainwindow类和ui的绑定在一起//一般在qt的构造函数中进程初始化操作//显示当前窗口的时候,显示另一个窗口,TestWidget//我们就在MainWindow的构造函数里面构造TestWidget对象,main只调用MainWindow就行//创建窗口对象,没有给w对象指定父对象
#if 1TestWidget* w=new TestWidget;w->show();
#elseTestWidget* w=new TestWidget(this);
#endifTestDialog* dlg=new TestDialog(this);//对于他写不写父对象无所谓的,这个this//模态 ,得调一个函数exec(),阻塞程序执行dlg->exec();//写exec了show自动帮你调了一次show显示
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cx9HcFxv-1685551154092)(../AppData/Roaming/Typora/typora-user-images/image-20230531233813577.png)]

QMainWinow类

我们创建项目一开始的类,就是继承QMainWinow这个类,算是你的主窗口,菜单栏的这种,去对应的ui界面也能去拖动按钮,控件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8KGwD5u5-1685551154093)(../AppData/Roaming/Typora/typora-user-images/image-20230601000327961.png)]

Qt的坐标

坐标原点在左上角,从左上角向下向右递增

每个窗口都有一个坐标原点,但是点的位置都是基于父窗口的原点去移动构建的

比如父亲是(0,0),,有个儿子是(5,5),这个5,5是相对于父亲0,0的

儿子还有个儿子(10,10),这个(10,10)是相对于(5,5)来说的,相当于说是按照爷爷(0,0)偏移的(15,,15)这个位置

所以注意窗口嵌套的坐标位置都是基于父窗口的坐标系来算的

我们给主窗口构造函数加点控件看看:

#include "mainwindow.h"
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) //窗口ui 被实例化了,ui界面也是个类其实
{ui->setupUi(this);//把cpp的mainwindow类和ui的绑定在一起//创建一个按钮,作为当前窗口的子控件QPushButton *ba=new QPushButton(this);//内嵌进去//通过move去移动控件位置ba->move(10,10);  //x y//设置大小ba->setFixedSize(200,200);//宽度,高度QPushButton *ba1=new QPushButton(ba);//注意这里//通过move去移动控件位置ba1->move(10,10);  //相对于ba的位置//设置大小ba1->setFixedSize(100,100);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WoB4iKRx-1685551154094)(../AppData/Roaming/Typora/typora-user-images/image-20230601001431759.png)]

Qt自带内存回收

因为qt总是来回继承的,很多类都是qobject这个类的子类或者间接子类,qt后台继承会构建一颗继承树,,父类要析构就得先去析构子类,这下就明白吧。。不过这种内存回收前提就是这个类得继承在qobject这个对象树下

综上所述,我们可以得到一个结论: Qt中有内存回收机制, 但是不是所有被new出的对象被自动回收, 满足条件才可以回收 , 如果想要在 Qt 中实现内存的自动回收,需要满足以下两个条件:

  1. 创建的对象必须是 QObject 类的子类 (间接子类也可以)

QObject 类是没有父类的,Qt 中有很大一部分类都是从这个类派生出去的

Qt 中使用频率很高的窗口类和控件都是 QObject 的直接或间接的子类
其他的类可以自己查阅 Qt 帮助文档
2.创建出的类对象,必须要指定其父对象是谁,一般情况下有两种操作方式:

// 方式1: 通过构造函数
// parent: 当前窗口的父对象, 找构造函数中的 parent 参数即可 .h
QWidget::QWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags());
QTimer::QTimer(QObject *parent = nullptr);// 方式2: 通过setParent()方法
// 假设这个控件没有在构造的时候指定符对象, 可以调用QWidget的api指定父窗口对象
void QWidget::setParent(QWidget *parent);
void QObject::setParent(QObject *parent);

http://www.ppmy.cn/news/240948.html

相关文章

如何调整Magic mouse的鼠标灵敏度

1、打开终端 2、输入以下代码查看当前鼠标移动速度 defaults read -g com.apple.mouse.scaling 你会看到输出的是 “1”&#xff0c;这是初始速度 3、输入以下代码改变鼠标移动速度 defaults write -g com.apple.mouse.scaling 7 4.然后重新启动

鼠标事件(mouseover和mouseenter的区别)

mouseover和mouseenter都是鼠标移到元素身上就触发&#xff0c;区别是 1、mouseover经过自身盒子触发&#xff0c;经过子盒子也触发&#xff0c;拥有冒泡特性 2、mouseenter只经过自身盒子触发&#xff0c;没有冒泡特性 mouseenter不会冒泡&#xff0c;搭配鼠标离开事件mous…

基于STM32F103C8T6的超声波测距——串口输出

文章目录 前言一、超声波模块介绍1、产品特点2、超声波模块的时序图 二、STM32CubeMx创建工程1、配置项目2、keil代码设置3、效果 三、总结四、参考资料 前言 环境&#xff1a; 1、硬件&#xff1a;stm32f103c8t6 核心板 2、软件&#xff1a;STM32CubeMX 6.4.0 3、软件&#xf…

POWERBUILDER基础学习提纲

Chengg0769 2012年 版权信息保留&#xff1a; www.mis2erp.com http://blog.csdn.net/chengg0769 http://www.haojiaocheng.cc 这当时是给列给一位因伤休养的朋友。他有一段难捱的时间&#xff0c;想学习学习。这样复出之后也不至于工作无望或者浪费这段时间。 在SQL2000基础…

神州数码信息安全有关搭建与配置的学习体系整理

信息安全有关搭建与配置的学习体系整理 一、平台搭建... 1 ◆要求... 1 二、网络安全设备配置与防护... 2 ◆要求... 2 ◆主要学习内容... 2 ◎DCFW&#xff08;web登录&#xff09;... 2 1.SNMP. 2 2.DDos防护... 2 3.接口的安全域配置... 2 4.新增用户... 3 5.时间…

第十一章 Python第三方库纵览

文章目录 第十一章 Python第三方库纵览11.1 网络爬虫方向11.1.1 requests11.1.2 scrapy 11.2 数据分析方向11.2.1 numpy11.2.2 scipy11.2.3 pandas 11.3 文本处理方向11.3.1 pdfminer11.3.2 openpyxl11.3.3 python-docx11.3.4 beautifulsoup4 11.4 数据可视化方向11.4.1 matplo…

Flutter特殊用法介绍

Flutter特殊用法介绍 Flutter是一种开源移动应用程序开发框架&#xff0c;具有高效、快速、美观、灵活等特点。本文将介绍Flutter中的一些特殊用法&#xff0c;帮助开发者更好地使用Flutter进行应用程序开发。 1. Flutter与原生代码交互 Flutter可以与原生代码进行交互&…