QT的主窗口坐标是相对于屏幕的。当用move(0,0)时就是屏幕的原点。而子窗口的坐标系统是相对于父窗口的。
比如按钮的父类是窗口。那么按钮坐标系统是相对于窗口的。不包含边框。
#include "mainwidget.h"
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
this->move(0,0); /* 窗口移动到0,0的位置 */
this->resize(400, 300);
button = new QPushButton(this);
button->setText("确定");
button->resize(100, 100);
}
以左上角为原点,X向右增加,Y向下增加。
如上窗口可以使用resize而按钮也可以使用呢?
所有窗口及窗口控件都是从QWidget直接或间接派生出来的。
所有窗口及窗口控件都是从QWidget直接或间接派生出来的。而QWidget又是继承QObject。所以new出来的控件只要指定父对象。
都会形成对象数结构如下。当我们没有delete时系统会从上往下依次释放。
但是要满足两个条件:1. 指定父类 2. 直接或者间接继承与QObject
怎么证明呢?
用一个dome来证明
自定义一个类MyButton然后继承与QPushButton。那么MyButton也相当于一个按钮。然后在主窗口new MyButton对象。
当窗口关闭时。如果会释放一定会调用MyButton的析构函数。在析构函数里打印东西来确认。
mybutton.h
#ifndef MYBUTTON_H
#define MYBUTTON_H
#include <QPushButton>
class MyButton : public QPushButton
{
Q_OBJECT
public:
explicit MyButton(QWidget *parent = nullptr);
~MyButton();
};
#endif // MYBUTTON_H
mybutton.cpp
#include "mybutton.h"
#include <QDebug>
MyButton::MyButton(QWidget *parent)
: QPushButton{parent}
{
}
MyButton::~MyButton()
{
qDebug()<<"按钮被析构";
}
mainwidget.cpp
#include "mainwidget.h"
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
this->move(0,0); /* 窗口移动到0,0的位置 */
this->resize(400, 300);
button = new MyButton(this); /* 在堆区申请了MyButton对象空间,但并没有释放 */
button->setText("确定");
button->resize(100, 100);
}
MainWidget::~MainWidget()
{
}
当窗口关闭时,会打印" 按钮被析构 "。说明会自动释放。
QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个锚接部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。在这里创建工程里要选择
QMainWindow作为基类。
mainwindow.cpp
#include "mainwindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QDebug>
#include <QToolBar>
#include <QPushButton>
#include <QStatusBar>
#include <QLabel>
#include <QTextEdit>
#include <QDockWidget>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
//1.菜单栏
QMenuBar *mBar = menuBar();
//添加菜单
QMenu *pFile = mBar->addMenu("文件");
//添加菜单项,添加动作
QAction *pNew = pFile->addAction("新建");
connect(pNew, &QAction::triggered,
[=]()
{
qDebug() << "新建被按下";
}
);
pFile->addSeparator(); //添加分割线·
QAction *pOpen = pFile->addAction("打开");
//2.工具栏,菜单项的快捷方式
QToolBar *toolBar = addToolBar("toolBar");
//工具栏添加快捷键
toolBar->addAction(pNew);
QPushButton *b = new QPushButton(this);
b->setText("^_^");
//添加小控件
toolBar->addWidget(b);
connect(b, &QPushButton::clicked,
[=]()
{
b->setText("123");
}
);
//3. 状态栏
QStatusBar *sBar = statusBar();
QLabel *label = new QLabel(this);
label->setText("Normal text file");
sBar->addWidget(label);
//addWidget 从左往右添加
sBar->addWidget(new QLabel("2", this));
// addPermanentWidget 从右往左添加
sBar->addPermanentWidget(new QLabel("3", this));
//4. 核心控件
QTextEdit *textEdit = new QTextEdit(this);
setCentralWidget(textEdit);
//5. 浮动窗口
QDockWidget *dock = new QDockWidget(this);
addDockWidget(Qt::RightDockWidgetArea, dock);
//给浮动窗口添加控件
QTextEdit *textEdit1 = new QTextEdit(this);
dock->setWidget(textEdit1);
}
运行的结果:
总结:对于这个窗口区域无非就是add,set开头的函数。多看帮助文档。
什么是模态与非模态?
模态与非模态的实现?
模态对话框和非模态对话框的举例
#include "mainwindow.h"
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QMenuBar *mBar = menuBar();
setMenuBar(mBar);
QMenu *menu = mBar->addMenu("对话框");
QAction *p1 = menu->addAction("模态对话框");
connect(p1, &QAction::triggered,
[=]()
{
QDialog dlg;
dlg.exec(); /* 一直死循环 */
qDebug() << "111111";
}
);
QAction *p2 = menu->addAction("非模态对话框");
connect(p2, &QAction::triggered,
[=]()
{
QDialog *p = new QDialog;
p->setAttribute(Qt::WA_DeleteOnClose);
p->show();
}
);
}
所谓标准对话框,是 Qt 内置的一系列对话框,用于简化开发。事实上,有很多对话框都是通用的,比如打开文件、设置颜色、打印设置等。这些对话框在所有程序中几乎相同,因此没有必要在每一个程序中都自己实现这么一个对话框。
Qt 的内置对话框大致分为以下几类:
包含关于,信息,问题,告警对话框。
QMessageBox模态对话框的举例
#include "mainwindow.h"
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QDialog>
#include <QDebug>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QMenuBar *mBar = menuBar();
setMenuBar(mBar);
QMenu *menu = mBar->addMenu("对话框");
QAction *p1 = menu->addAction("关于对话框");
connect(p1, &QAction::triggered,
[=]()
{
QMessageBox::about(this, "about", "关于qt");
}
);
QAction *p2 = menu->addAction("问题对话框");
connect(p2, &QAction::triggered,
[=]()
{
int ret = QMessageBox::question(this,
"question", "Are you ok?",
QMessageBox::Ok |
QMessageBox::Cancel);
switch(ret)
{
case QMessageBox::Ok:
qDebug() << "i am ok";
break;
case QMessageBox::Cancel:
qDebug() << "i am bad";
break;
default:
break;
}
}
);
}
#include "mainwindow.h"
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QDialog>
#include <QDebug>
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QMenuBar *mBar = menuBar();
setMenuBar(mBar);
QMenu *menu = mBar->addMenu("对话框");
QAction *p1 = menu->addAction("文件对话框");
connect(p1, &QAction::triggered,
[=]()
{
QString path = QFileDialog::getOpenFileName(
this,
"open",
"../",
"souce(*.cpp *.h);;Text(*.txt);;all(*.*)"
);
qDebug() << path;
}
);
}
QFileDialog的参数
参数1: 父对象
参数2:文件对话框的标题
参数3:默认打开的路径
参数4:过滤器
返回值:选择文件的绝对路径
点击“选择…”按钮,打开“新建 Qt 资源文件”对话框。在这里我们输入资源文件的名字和路径:
点击下一步,选择所需要的版本控制系统,然后直接选择完成。我们可以在 Qt Creator 的左侧文件列表中看到“资源文件”一项,也就是我们新创建的资源文件:
右侧的编辑区有个“添加”,我们首先需要添加前缀,比如我们将前缀取名为 images。然后选中这个前缀,继续点击添加文件,可以找到我们所需添加的文件。这里,我们选择 document-open.png 文件。当我们完成操作之后,Qt Creator 应该是这样子的:
接下来,我们还可以添加另外的前缀或者另外的文件。这取决于你的需要。当我们添加完成之后,我们可以像前面一章讲解的那样,通过使用 : 开头的路径来找到这个文件。比如,我们的前缀是 /images,文件是 document-open.png,那么就可以使用:/images/document-open.png找到这个文件。
这么做带来的一个问题是,如果以后我们要更改文件名,比如将 docuemnt-open.png 改成 docopen.png,那么,所有使用了这个名字的路径都需要修改。所以,更好的办法是,我们给这个文件去一个“别名”,以后就以这个别名来引用这个文件。具体做法是,选中这个文件,添加别名信息:
这样,我们可以直接使用:/images/doc-open引用到这个资源,无需关心图片的真实文件名。
如果我们使用文本编辑器打开 res.qrc 文件,就会看到一下内容:
我们可以对比一下,看看 Qt Creator 帮我们生成的是怎样的 qrc 文件。当我们编译工程之后,我们可以在构建目录中找到 qrc_res.cpp 文件,这就是 Qt 将我们的资源编译成了 C++ 代码。
主要介绍了QT的坐标系统、回收机制、窗口的区域(菜单栏,工具栏、核心区域、状态栏,浮动窗口)以及各种对话框与资源文件。