引言

QMainWindow 是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个锚接部件(dock widgets)、一个状态栏(status bar)及一个中心部件(central widget),是许多应用程序的基础,如文本编辑器,图片编辑器等。(本篇主要介绍菜单栏和工具栏)



 一,菜单栏

一个主窗口最多只有一个菜单栏。位于主窗口顶部、主窗口标题栏下面。
  • 创建菜单栏。
QMenuBar* menuBar = new QMenuBar(this);
  • 创建菜单,调用 QMenu 的成员函数 addMenu 来添加菜单 
QAction* addMenu(QMenu * menu)
QMenu* addMenu(const QString & title)
QMenu* addMenu(const QIcon & icon, const QString & title)
  • 创建菜单项,调用 QMenu 的成员函数 addAction 来添加菜单项
QAction* activeAction() 
QAction* addAction(const QString & text)
QAction* addAction(const QIcon & icon, const QString & text)
QAction* addAction(const QString & text, const QObject * receiver, const char * member, const QKeySequence & shortcut = 0)
QAction* addAction(const QIcon & icon, const QString & text, const QObject * receiver, const char * member,const QKeySequence & shortcut = 0)

实例演示:(vs2019+qt5)

 //创建菜单栏
QMenuBar* menuBar = new QMenuBar(this);
//创建菜单(用addMenu方法添加入菜单栏)
QMenu* filename = menuBar->addMenu(QStringLiteral("文件(&F)"));
//创建菜单项
QAction* openfile = new QAction(QStringLiteral("打开文件(&O)"));
QAction* opendlg = new QAction(QStringLiteral("打开对话框(&D)"));
//给菜单项添入图标
openfile->setIcon(QIcon(":/D:/image/Luffy.png"));
opendlg->setIcon(QIcon(":/D:/image/LuffyQ.png"));
//用addAction加入菜单项
filename->addAction(opendlg);
filename->addAction(openfile);

注意:使用 QStringLiteral 宏可以在编译期把代码里的常量字符串 str 直接构造为 QString 对象,于是运行时就不再需要额外的构造开销了。


资源文件的添加

openfile->setIcon(QIcon(":/D:/image/Luffy.png"));
对于该句代码":/D:/image/Luffy.png"是以相对路径添加的(即以:/开头的是资源文件),那么如何添加资源文件呢?
  • 添加->新建项->Qt->Qt Resource File。

  •  在Resource1.qrc中添加说需要的资源(比如图片)

最后以冒号+前缀+名称(相对路径)写入资源。


二,工具栏

主窗口的工具栏上可以有多个工具条,通常采用一个菜单对应一个工具条的的方式,也可根据需要进行工具条的划分。 
添加头文件
  • 直接调用 QMainWindow 类的 addToolBar()函数获取主窗口的工具条对象,每增加一个工具条都需要调用一次该函数
  • 插入属于工具条的动作,即在工具条上添加操作。通过 QToolBar 类的 addAction 函数添加
  • 工具条是一个可移动的窗口,它的停靠区域由 QToolBar 的 allowAreas 决定,包括:
  1. Qt::LeftToolBarArea  停靠在左侧
  2. Qt::RightToolBarArea停靠在右侧
  3. Qt::TopToolBarArea  停靠在顶部
  4. Qt::BottomToolBarArea停靠在底部
  5. Qt::AllToolBarAreas以上四个位置都可停靠

使用 setAllowedAreas()函数指定停靠区域:

setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea)
使用 setMoveable()函数设定工具栏的可移动性:
setMoveable(false)//工具条不可移动, 只能停靠在初始化的位置上

三,对话框 QDialog 

对话框是 GUI 程序中不可或缺的组成部分。很多不能或者不适合放入主窗口的功能组件都必须放在对话框中设置。对话框通常会是一个顶层窗口,出现在程序最上层,用于实现短期任务或者简洁的用户交互。 
Qt 中使用 QDialog 类实现对话框。就像主窗口一样,我们通常会设计一个类继承 QDialog。QDialog(及其子类,以及所有 Qt::Dialog 类型的类)的对于其parent 指针都有额外的解释:如果 parent 为 NULL,则该对话框会作为一个顶
层窗口,否则则作为其父组件的子对话框(此时,其默认出现的位置是 parent的中心)。顶层窗口与非顶层窗口的区别在于,顶层窗口在任务栏会有自己的位置,而非顶层窗口则会共享其父组件的位置。 
1️⃣对话框分为模态对话框和非模态对话框。
  • 模态对话框,就是会阻塞同一应用程序中其它窗口的输入。模态对话框很常见,比如“打开文件”功能。你可以尝试一下记事本的打开文件,当打开文件对话框出现时,我们是不能对除此对话框之外的窗口部分进行操作的。
  • 与此相反的是非模态对话框,例如查找对话框,我们可以在显示着查找对话框的同时,继续对记事本的内容进行编辑。
模态与非模态的实现:
  • 使用 QDialog::exec()实现应用程序级别的模态对话框
  • 使用 QDialog::open()实现窗口级别的模态对话框
  • 使用 QDialog::show()实现非模态对话框。

模态对话框实例:

我们调用了 exec()将对话框显示出来,因此这就是一个模态对话框。当对话框出现时,我们不能与主窗口进行任何交互,直到我们关闭了该对话框。
QDialog dlg1(this);
dlg1.resize(300,200);
dlg1.setWindowTitle(QStringLiteral("模态对话框"));
dlg1.exec();

非模态对话框实例:

下面我们试着将 exec()修改为 show(),看看非模态对话框:
QDialog dlg1(this);
dlg1.resize(300,200);
dlg1.setWindowTitle(QStringLiteral("模态对话框"));
dlg1.show();
是不是事与愿违?对话框竟然一闪而过!这是因为,show()函数不会阻塞当前线程,对话框会显示出来,然后函数立即返回,代码继续执行。注意,dialog 是建立在栈上的,show()函数返回,函数结束,dialog超出作用域被析构,因此对话框消失了。知道了原因就好改了,我们将 dialog改成堆上建立(即new一个对象),当然就没有这个问题了。
QDialog *dlg2 = new QDialog();
dlg2->resize(200, 200);
dlg2->setAttribute(Qt::WA_DeleteOnClose);//关闭时清理内存
dlg2->show();

注意:在堆上就不能用点(.)了,要用->。而且由于使用 new 在堆上分配空间,却一直没有 delete。因此我们用setAttribute()函数设置对话框关闭时,自动销毁对话框。

2️⃣标准文件对话框

QFileDialog,也就是文件对话框。
我们使用 QFileDialog::getOpenFileName()来获取需要打开的文件的路径。这个函数原型如下: 
QString getOpenFileName(QWidget * parent = 0,                //父窗口
const QString & caption = QString(), //对话框标题
const QString & dir = QString(), //对话框打开的默认路径
const QString & filter = QString(), //过滤器(例如我们使用“imagefile(*.jpg*.png)”则只显示jpg和png文件。多个过滤器用“;;”分割。
QString * selectedFilter = 0, //默认选择的过滤器
Options options = 0 //对话框的参数设定
)
下面是最主要的 openFile()和 saveFile()这两个函数的代码:
//打开文件
void MainWindow::openFile()
{
QString path = QFileDialog::getOpenFileName(this, tr("Open File"), ".", tr("Text Files(*.txt)"));
if(!path.isEmpty())
{
QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::warning(this, tr("Read File"), tr("Cannot open file:\n%1").arg(path));
return;
}
QTextStream in(&file);
textEdit->setText(in.readAll());
file.close();
}
else
{
QMessageBox::warning(this, tr("Path"), tr("You did not select any file."));
}
}
//保存文件
void MainWindow::saveFile()
{
QString path = QFileDialog::getSaveFileName(this, tr("Open File"), ".", tr("Text Files(*.txt)"));
if(!path.isEmpty())
{
QFile file(path);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QMessageBox::warning(this, tr("Write File"), tr("Cannot open file:\n%1").arg(path));
return;
}
QTextStream out(&file);
out << textEdit->toPlainText();
file.close();
}
else
{
QMessageBox::warning(this, tr("Path"), tr("You did not select any file."));
}
}

实例演示:创建菜单栏,菜单项为打开文件夹和对话框。点击打开对应功能。

//菜单文件
// 使用 QStringLiteral 宏可以在编译期把代码里的常量字符串 str 直接构造为 QString 对象,于是运行时就不再需要额外的构造开销了。
QMenuBar* menuBar = new QMenuBar(this);
QMenu* filename = menuBar->addMenu(QStringLiteral("文件(&F)"));
QAction* openfile = new QAction(QStringLiteral("打开文件(&O)"));
QAction* opendlg = new QAction(QStringLiteral("打开对话框(&D)"));
openfile->setIcon(QIcon(":/D:/image/Luffy.png"));
opendlg->setIcon(QIcon(":/D:/image/LuffyQ.png"));
filename->addAction(opendlg);
filename->addAction(openfile);
//打开对话框
connect(opendlg, &QAction::triggered, [=]() {
//模态对话框(不可对其他对话框操作)
QDialog dlg1(this);
dlg1.resize(300,200);
dlg1.setWindowTitle(QStringLiteral("模态对话框"));
dlg1.exec();
//非模态对话框(可以对其他对话框操作)
// QDialog *dlg2 = new QDialog();
//dlg2->resize(200, 200);
//dlg2->setAttribute(Qt::WA_DeleteOnClose);//关闭时清理内存
//dlg2->show();
});
//打开文件夹
connect(openfile, &QAction::triggered, [=]() {
QFileDialog fdlg(this);
fdlg.getOpenFileName(this, QStringLiteral("选择文件"), "D:\\", tr("Image(*.jpg*.png)")); });

QT常用控件(一)——菜单栏和对话框的更多相关文章

  1. Qt常用控件

    Qt常用控件 QWidget与QFrame QWidget所有图形控件的基类 QFrame与QWidget的区别 QFrame是基本控件的基类, QWidget是QFrame的基类. 因此QFrame ...

  2. QT常用控件(三)——自定义控件封装

    引言 Qt已经提供了很多的基础控件供开发使用,而Qt原生的控件有时候并不能满足我们的需求,特别是在工业的运用上,比如我们需要一个日期时间的选择器,Qt虽然已经提供了原生的QDateTime控件,但这个 ...

  3. QT 常用控件二

    QT提供QHBoxLayout类.QVBoxlayout类及QGridLayout类等的基本布局管理,分别是水平排列布局,垂直排列布局和网格排列布局 addWidget()方法用于向布局中加入需要布局 ...

  4. Qt——常用控件样式

    下面是我设计.调整.修改的Qt控件样式,仅供参考. Github地址:https://github.com/ikongziming/QtDemo/tree/master/StyleSheetDemo ...

  5. QT 常用控件一

    QWidget 创建窗口 如果widget未使用腹肌进行创建,则在显示时视为窗口或顶层widget. 由于顶层widget没有父级对象类来确保在其不再使用时删除,所以需要开发人员在应用程序中对其进程跟 ...

  6. QT+常用控件_Line Edit

    #include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> #incl ...

  7. QT_7_资源文件_对话框_QMessageBox_界面布局_常用控件

    资源文件 1.1. 将资源导入到项目下 1.2. 添加文件—>Qt -->Qt Resource File 1.3. 起名称 res ,生成res.qrc文件 1.4. 右键 open i ...

  8. Qt基本控件及三大布局

    Qt基本控件及三大布局 来源: http://blog.csdn.net/a2604539133/article/details/73920696 Qt基本模块 一.Qt的三大布局 QHBoxLayo ...

  9. winform常用控件介绍

    1.窗体 12.Label 控件 33.TextBox 控件 44.RichTextBox控件 55.NumericUpDown 控件 76.Button 控件 77.GroupBox 控件 78.R ...

随机推荐

  1. Terraform模块Module管理,聚合资源的抽取与复用

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 最近工作中用到了Terraform,权当学习记录一下,希望能帮助到其它人. Terraform系列文章如下: T ...

  2. 二QT中使用QTimer定时器

    QT中的定时器类叫QTimer(5.8以上版本才有),构造函数只需要提供父对象的指针 使用的话,需要调用QTImer的start方法,该方法以毫秒单位,每过指定毫秒时间,该类对象就会发出一个timeo ...

  3. 29、vi和vim用法详解

    vi类似于windows中的文本文件,用于普通的文本文件 vim:专家版的文件编辑器,用于shell程序型文件,带颜色,自检查语法 一般模式快捷键 O:光标到一行的首 $:光标到一行的尾 H:光标到整 ...

  4. GDI+中发生一般性错误的解决办法(转载)

    今天在开发.net引用程序中,需要System.Drawing.Image.Save 创建图片,debug的时候程序一切正常,可是发布到IIS后缺提示出现"GDI+中发生一般性错误" ...

  5. [心得体会]Spring容器的初始化

    1. Spring容器的初始化过程 public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {   ...

  6. 关于Feign的Fallback处理

    Feign的不恰当的fallback Feign的坑不少,特别与Hystrix集成之后. 在微服务引入Feign后,上线不久后便发现,对于一个简单的查询类调用,在下游返回正常的"404-资源 ...

  7. PHP单例模式 (转)

      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 ...

  8. 了解Javascript中函数作为对象的魅力

    前言 Javascript赋予了函数非常多的特性,其中最重要的特性之一就是将函数作为第一型的对象.那就意味着在javascript中函数可以有属性,可以有方法, 可以享有所有对象所拥有的特性.并且最重 ...

  9. Javascript实现数组去重 [转]

    1.遍历数组法 它是最简单的数组去重方法(indexOf方法) 实现思路:新建一个数组,遍历去要重的数组,当值不在新数组的时候(indexOf为-1)就加入该新数组中: var arr=[2,8,5, ...

  10. 深入理解索引和AVL树、B-树、B+树的关系

    目录 什么是索引 索引的分类 索引和AVL树.B-树.B+树的关系 AVL树.红黑树 B-树 B+树 SQL和NoSQL索引 什么是索引 索引时数据库的一种数据结构,数据库与索引的关系可以看作书籍和目 ...