Qt 窗口系统

Qt 窗口系统

Qt窗口坐标系统

坐标系统是以左上角为原点,X向右增加, Y向下增加
对于嵌套窗口,其坐标是相对于父窗口而言的。

QWidget
所有窗口及窗口控件都是从QWidget直接或间接派生出来的。
对象模型
在Qt中创建对象时,会提供一个parent对象指针QObject是以对象树形式组织起来的。

  • 创建一个QObject对象时,QObject的构造函数接收一个QObject指针作为参数,该参数是父对象指针parent。在创建QObject对象时,可提供一个其父对象,创建的QObject对象会自动添加其父对象的children()列表
  • 当父对象析构时,该列表中的所有对象也会被析构,值得注意,这里父对象不是指继承意义上的父类

QWidget是能够在屏幕上显示的一切组件的父类。

  • QWidget继承自QObject,也继承了这种对象树关系。一个孩子自动成为父组件的一个子组件。如用户关闭一个对话框时,应用程序将其删除,属于这个对话框的按钮,图标等应该一起被删除,因为这些组件为对话框的子组件。
  • 也可以自己删除子对象,他们会自动从其父对象列表中删除,如当删除一个工具栏时,其所在的主窗口会自动将该工具栏从其子对象列表中删除,并且自动调整屏膜显示。

Qt引入对象树概念,在一定程度上解决了内存问题

  • 当一个QObject对象在堆上创建时,Qt会自动为其创建一个对象树,但对象数中对象顺序没有被定义,同时 销毁对象的顺序也是未定的。
  • 任何对象树中的QObject对象delete时,若对象有parent,则自动将其从parent的children()列表中删除;若有子对象,则自动delete每一个孩子。Qt保证没有QObject会被delete两次,这由析构顺序决定的。

若QObject在栈上创建,Qt保持同样的行为。

{
	QWidget window;
	QPushBUtton quit("Quit",&windows);
}

作为父组件的window和作为子组件的quit都是QObject的子类(他们都是QWiget的子类,而QWidget是QObject的子类)。quit的析构函数不会被调用两次,因为标准C++要求,局部对象的析构顺序应该按照其创建顺序的想反过程。因此,这段代码在超出作用域时,会先调用quit的析构函数,将其从父对象window的子对象列表中删除,然后才会在调用window的析构函数

{
	PushBUtton quit("Quit");
	QWidget window;
	quit.setParent(&windows);
}

与上例不同,析构顺序有问题,作为父对象的window会首先被析构,因为它是最后一个创建的对象。在析构过程中,它会调用子对象列表中每一个对象的析构函数,quit此时被析构了。然后代码继续执行,在window析构之后,quit也会被析构,因为quit也是一个局部变量,在超出作用域时,也需要被析构。此时,第二次调用quit的析构函数,C++不允许调用两次析构函数,这会导致程序崩溃

小结:Qt的对象树机制虽然帮助用户在一定程序上解决了内存问题,但是也引入了一些值得注意的事,在后续的开发中需要注意该些问题,养成良好的编程习惯,在Qt中,在构造是指定parent对象,并且在堆上创建(内存回收机制)。
QMainWindow

对话框QDialog

基本概念

标准对话框
QMessageBox

The QMessageBox class provides a modal dialog for informing the user or for asking the user a question and receiving an answer.
A message box displays a primary text to alert the user to a situation, an informative text to further explain the alert or to ask the user a question, and an optional detailed text to provide even more data if the user requests it. A message box can also display an icon and standard buttons for accepting a user response.
Two APIs for using QMessageBox are provided, the property-based API, and the static functions. Calling one of the static functions is the simpler approach, but it is less flexible than using the property-based API, and the result is less informative. Using the property-based API is recommended.

//06_Dialogdemo/mainwindow.cpp
#include "mainwindow.h"
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <qDebug>
#include <QDialog>
#include <QMessageBox>
#include <QString>
#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    //菜单栏
    QMenuBar *mBar =  menuBar();
    setMenuBar(mBar);
    //添加菜单
    QMenu *menu = mBar->addMenu("add menu");
	//添加模态对话框
    QAction *p1 = menu->addAction("motai duihuakuang");
	//连接函数
    connect(p1,&QAction::triggered,
            [=]()
            {
//                QDialog dlg;
//                dlg.show();
//                qDebug()<<"asdfas";
                QDialog *p2 = new QDialog;
                p2->setAttribute(Qt::WA_DeleteOnClose);
                p2->show();
            }
            );
            
    QAction *p3 = menu->addAction("guanyu duihuakuang");
    connect(p3,&QAction::triggered,
            [=]()
            {
                int ret = QMessageBox::question(this,
                                                "question","Are you ok>"0x00004000|QMessageBox::No);//可以指定按钮,OK,cancel...
                switch(ret){
                case QMessageBox::Yes:
                    qDebug() << "ok";
                case QMessageBox::No:
                    qDebug() << "bad";
                    break;
                default:
                    break;
                }

            });

    QAction *p4 = menu->addAction("file duihuakuang");
    connect(p4,&QAction::triggered,
            [=]()
            {
                QString path = QFileDialog::getOpenFileName(
                            this,
                            "open",
                            "../",
                            "source(*.cpp *.h);;Text(*.txt);;all(*.*)"
                            );
                qDebug() << path;
            });
}
}

MainWindow::~MainWindow()
{

}

运行结果
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值