一、Qt的GUI程序有一个常用的顶层窗口,叫做MainWindow

MainWindow继承自QMainWindow。QMainWindow窗口分成几个主要的区域:
 

二、QAction类

QAction类保存有关于这个动作,也就是action的信息,比如它的文本描述、图标、快捷键、回调函数(也就是信号槽),等等。神奇的是,QAction能够根据添加的位置来改变自己的样子——如果添加到菜单中,就会显示成一个菜单项;如果添加到工具条,就会显示成一个按钮。

把QAction添加到菜单和工具条上:

QAction *openAction;   openAction = new QAction(tr("&Open"),this);  openAction->setShortcut(QKeySequence::Open);  openAction->setStatusTip(tr("Open a file."));

QAction:

QAction(const QString &text, QObject* parent);

第一个text是这个动作的文本描述,用来显示文本信息;第二个是parent,它的作用是指明这个QAction的父组件,当这个父组件被销毁时,与其相关联的这个QAction也会自动被销毁。

shortcut是这个动作的快捷键。

setStatusTip函数。这是添加状态栏的提示语句

QMenu *file = menuBar()->addMenu(tr("&File"));   file->addAction(openAction);    QToolBar *toolBar = addToolBar(tr("&File"));   toolBar->addAction(openAction);

第一句menuBar()函数返回一个菜单栏指针,addMenu()函数添加一个菜单,菜单栏指针调用addMenu()函数把菜单添加到菜单栏中。

第二句菜单栏指针调用addAction()函数将QAction对象添加到菜单中使QAction成为一个菜单项(QAction能够根据添加的位置来改变自己的样子——如果添加到菜单中,就会显示成一个菜单项).

第三句addToolBar()函数添加一个工具栏返回这个工具栏的指针,addAction()函数将QAction对象添加到工具栏中使其成为一个工具项(一个按钮,如果添加到工具条,就会显示成一个按钮)

三、利用资源文件给菜单项和工具条按钮添加图标

添加图标。QAction的图标会显示在菜单项的前面以及工具条按钮上面显示

openAction->setIcon(QIcon(":/Open.png"));

使用setIcon添加图标,添加的类是QIcon,构造函数需要一个参数,是一个字符串。由于我们要使用qrc中定义的图片,所以字符串以 : 开始,后面跟着prefix,因为我们先前定义的prefix是/,所以就需要一个/,然后后面是file的路径。

为QAction添加事件响应

private slots:         void open();         因为我们的open()目前只要在类的内部使用,因此定义成private slots即可。

connect(openAction, SIGNAL(triggered()), this, SLOT(open()));

triggered()信号:

这个信号时产生一个动作是由用户激活;例如,当用户单击一个菜单选项,工具栏按钮或按操作的快捷键组合,或当trigger()函数调用时。值得注意的是, 当setChecked() or toggle() 被调用时,信号不发射。

void MainWindow::open() {         QMessageBox::information(NULL, tr("Open"), tr("Open a file"));     }

四、状态栏

状态栏位于主窗口的最下方,提供一个显示工具提示等信息的地方。一般地,当窗口不是最大化的时候,状态栏的右下角会有一个可以调节大小的控制点;当窗口最大化的时候,这个控制点会自动消失。Qt提供了一个QStatusBar类来实现状态栏。QMainWindow类里面就有一个statusBar()函数,用于实现状态栏的调用。类似menuBar()函数,如果不存在状态栏,该函数会自动创建一个,如果已经创建则会返回这个状态栏的指针。如果你要替换掉已经存在的状态栏,需要使用QMainWindow的setStatusBar()函数。

在Qt里面,状态栏显示的信息有三种类型:临时信息、一般信息和永久信息。

QStatusBar继承自QWidget,因此它可以添加其他的QWidget。

private:         QAction *openAction;         QLabel *msgLabel

在其构造函数中添加:

msgLabel = new QLabel;         msgLabel->setMinimumSize(msgLabel->sizeHint());         msgLabel->setAlignment(Qt::AlignHCenter);         statusBar()->addWidget(msgLabel);

第一行创建一个QLabel的对象,然后设置最小大小为其本身的建议大小,这样设置之后,这个最小大小可能是变化的——最后设置显示规则是水平居中(HCenter)。最后一行使用statusBar()函数将这个label添加到状态栏。

我们很快发现一个问题:当没有任何提示时,状态栏会有一个短短的竖线:

其实,这是QLabel的边框。当没有内容显示时,QLabel只显示出自己的一个边框。但是,很多情况下我们并不希望有这条竖线,于是,我们对statusBar()进行如下设置:

statusBar()->setStyleSheet(QString("QStatusBar::item{border: 0px}"));//把QStatusBar的子组件的border设置为0,也就是没有边框

QStatusBar右下角的大小控制点可以通过setSizeGripEnabled()函数来设置是否存在.

由于QStatusBar可以添加多个QWidget,因此,我们可以构建出很复杂的状态栏。

五、Qt的标准对话框之QFileDialog

QFileDialog是Qt中用于文件打开和保存的对话框

这种方法是使用静态函数的方法来创建一个文件打开对话框

void MainWindow::open() {         QString path = QFileDialog::getOpenFileName(this, tr("Open Image"),".", tr("Image Files(*.jpg *.png)"));         if(path.length() == 0) {                 QMessageBox::information(NULL, tr("Path"), tr("You didn't select any files."));         }else {                 QMessageBox::information(NULL, tr("Path"), tr("You selected ") + path);         } }

QFileDialog提供了很多静态函数,用于获取用户选择的文件。这里我们使用的是getOpenFileName(), 也就是“获取打开文件名”

Qt提供了另外的写法:

        QFileDialog *fileDialog =new QFileDialog(this);         fileDialog->setWindowTitle(tr("Open Image"));         fileDialog->setDirectory(".");         fileDialog->setFilter(tr("Image Files(*.jpg *.png)"));         if(fileDialog->exec() == QDialog::Accepted) {                 QString path = fileDialog->selectedFiles()[0];                 QMessageBox::information(NULL, tr("Path"), tr("You selected ") + path);         }else {                 QMessageBox::information(NULL, tr("Path"), tr("You didn't select any files."));         }
 这两种写法虽然功能差别不大,但是弹出的对话框却并不一样。getOpenFileName()函数在Windows和MacOS X平台上提供的是本地的对话框,而QFileDialog提供的始终是Qt自己绘制的对话框
QString QFileDialog::getOpenFileName (
          QWidget * parent = 0,
          const QString & caption = QString(),
          const QString & dir = QString(),
          const QString & filter = QString(),
          QString * selectedFilter = 0,
          Options options = 0 )
第一个参数parent,用于指定父组件。注意,很多Qt组件的构造函数都会有这么一个parent参数,并提供一个默认值0;
第二个参数caption,是对话框的标题;
第三个参数dir,是对话框显示时默认打开的目录,"." 代表程序运行目录,"/" 代表当前盘符的根目录(Windows,Linux下/就是根目录了),也可以是平台相关的,比如"C:\\"等; 
第四个参数filter,是对话框的后缀名过滤器,比如我们使用"Image Files(*.jpg *.png)"就让它只能显示后缀名是jpg或者png的文件。如果需要使用多个过滤器,使用";;"分割,比如"JPEG Files(*.jpg);;PNG Files(*.png)";
第五个参数selectedFilter,是默认选择的过滤器;
第六个参数options,是对话框的一些参数设定,比如只显示文件夹等等,它的取值是enum QFileDialog::Option,每个选项可以使用 | 运算组合起来。
如果要想选择多个文件怎么办呢?Qt提供了getOpenFileNames()函数,其返回值是一个QStringList。你可以把它理解成一个只能存放QString的List,也就是STL中的list<string>。

我们已经能够选择打开文件了。保存也是类似的,QFileDialog类也提供了保存对话框的函数getSaveFileName(),具体使用还是查阅API.

六、Qt的标准对话框之QColorDialog

使用QColorDialog也很简单,Qt提供了getColor()函数,类似于QFileDialog的getOpenFileName(),可以直接获得选择的颜色。

        QColor color = QColorDialog::getColor(Qt::white,this);         QString msg = QString("r: %1, g: %2, b: %3").arg(QString::number(color.red()), QString::number(color.green()), QString::number(color.blue()));         QMessageBox::information(NULL,"Selected color", msg);

第一行QColorDialog::getColor()调用了QColorDialog的static函数getColor()。这个函数有两个参数,第一个是QColor类型,是对话框打开时默认选择的颜色,第二个是它的parent。

第二行比较长,涉及到QString的用法,QString("r: %1, g: %2, b: %3")创建了一个QString对象。我们使用了参数化字符串,也就是那些%1之类。其实这都是一些占位符,也就是,后面会用别的字符串替换掉这些值。占位符的替换需要使用QString的arg()函数。这个函数会返回它的调用者,因此可以使用链式调用写法。它会按照顺序替换掉占位符。然后是QString::number()函数,这也是QString的一个static函数,作用就是把int、double等值换成QString类型。这里是把QColor的R、G、B三个值输出了出来。

第三行使用一个消息对话框把刚刚拼接的字符串输出。
QColorDialog还有一些其他的函数可以使用:

QColorDialog::setCustomColor()可以设置用户自定义颜色。这个函数有两个值,第一个是自定义颜色的索引,第二个是自定义颜色的RGB值,类型是QRgb

QColorDialog::setCustomColor(0, QRgb(0x0000FF));

getColor()还有一个重载的函数,签名如下:

QColorDialog::getColor(const QColor & initial, QWidget * parent, const QString & title, ColorDialogOptions options = 0 )
 第一个参数initial和前面一样,是对话框打开时的默认选中的颜色;
 第二个参数parent,设置对话框的父组件;
 第三个参数title,设置对话框的title;
 第四个参数options,是QColorDialog::ColorDialogOptions类型的,可以设置对话框的一些属性,如是否显示Alpha值等,具体属性请查阅API文档。特别的,这些值是可以使用OR操作的。

七、Qt标准对话框之QMessageBox

QMessageBox::information

QMessageBox::information(NULL,"Title", "Content", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
 

API中看看它的函数签名:

 
static StandardButton QMessageBox::information ( QWidget * parent,const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton );
 第一个参数parent,说明它的父组件;第二个参数title,也就是对话框的标题;第三个参数text,是对话框显示的内容;第四个参数buttons,声明对话框放置的按钮,默认是只放置一个OK按钮,这个参数可以使用或运算,例如我们希望有一个Yes和一个No的按钮,可以使用QMessageBox::Yes |QMessageBox::No,所有的按钮类型可以在QMessageBox声明的StandarButton枚举中找到;第五个参数defaultButton就是默认选中的按钮,默认值是NoButton,也就是哪个按钮都不选中。
Qt提供了五个类似的接口,用于显示类似的窗口。
QMessageBox::critical(NULL,"critical", "Content", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
 危险窗口 
QMessageBox::warning(NULL,"warning", "Content", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
警告窗口 
QMessageBox::question(NULL,"question", "Content", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
  疑问窗口
QMessageBox::about(NULL,"About", "About this application");
 关于窗口
请注意,最后一个about()函数是没有后两个关于button设置的按钮的!
 
QMessageBox对话框的文本信息时可以支持HTML标签的。例如:
 
QMessageBox::about(NULL,"About", "About this <font color='red'>application</font>");
 
运行效果如下:
 
 
如果我们想自定义图片的话,也是很简单的。这时候就不能使用这几个static的函数了,而是要我们自己定义一个QMessagebox来使用:
 
QMessageBox message(QMessageBox::NoIcon,"Title", "Content with icon."); message.setIconPixmap(QPixmap("icon.png")); message.exec();
 
这里我们使用的是exec()函数,而不是show(),因为这是一个模态对话框,需要有它自己的事件循环,否则的话,我们的对话框会一闪而过哦(感谢laetitia提醒).
需要注意的是,同其他的程序类似,我们在程序中定义的相对路径都是要相对于运行时的.exe文件的地址的。比如我们写"icon.png",意思是是在.exe的当前目录下寻找一个"icon.png"的文件。这个程序的运行效果如下:
 
 
还有一点要注意,我们使用的是png格式的图片。因为Qt内置的处理图片格式是png,所以这不会引起很大的麻烦,如果你要使用jpeg格式的图片的话,Qt是以插件的形式支持的。在开发时没有什么问题,不过如果要部署的话,需要注意这一点。
 
最后再来说一下怎么处理对话框的交互。我们使用QMessageBox类的时候有两种方式,一是使用static函数,另外是使用构造函数。
 
首先来说一下static函数的方式。注意,static函数都是要返回一个StandardButton,我们就可以通过判断这个返回值来对用户的操作做出相应。
 
QMessageBox::StandardButton rb = QMessageBox::question(NULL,"Show Qt", "Do you want to show Qt dialog?", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if(rb == QMessageBox::Yes) {         QMessageBox::aboutQt(NULL,"About Qt"); }
 
如果要使用构造函数的方式,那么我们就要自己运行判断一下啦:
 
QMessageBox message(QMessageBox::NoIcon,"Show Qt", "Do you want to show Qt dialog?", QMessageBox::Yes | QMessageBox::No, NULL); if(message.exec() == QMessageBox::Yes) {         QMessageBox::aboutQt(NULL,"About Qt"); }
 

八、Qt标准对话框之QInputDialog

QInputDialog用于接收用户的输入。QInputDialog提供了一些简单的static函数,用于快速的建立一个对话框

首先来看getText函数:
bool isOK; QString text = QInputDialog::getText(NULL,"Input Dialog",                                                    "Please input your comment",                                                    QLineEdit::Normal,                                                    "your comment",                                                    &isOK); if(isOK) {        QMessageBox::information(NULL,"Information",                                            "Your comment is: <b>" + text +"</b>",                                            QMessageBox::Yes | QMessageBox::No,                                            QMessageBox::Yes); }

代码比较简单,使用getText函数就可以弹出一个可供用户输入的对话框:

下面来看一下这个函数的签名:
 
static QString QInputDialog::getText ( QWidget * parent,
                                                      const QString & title,
                                                      const QString & label,
                                                      QLineEdit::EchoMode mode = QLineEdit::Normal,
                                                      const QString & text = QString(),
                                                      bool * ok = 0,
                                                      Qt::WindowFlags flags = 0 )
 第一个参数parent,也就是那个熟悉的父组件的指针;第二个参数title就是对话框的标题;第三个参数label是在输入框上面的提示语句;第四个参数mode用于指明这个QLineEdit的输入模式,取值范围是QLineEdit::EchoMode,默认是Normal,也就是正常显示,你也可以声明为password,这样就是密码的输入显示了,第五个参数text是QLineEdit的默认字符串;第六个参数ok是可选的,如果非NULL,则当用户按下对话框的OK按钮时,这个bool变量会被置为true,可以由这个去判断用户是按下的OK还是Cancel,从而获知这个text是不是有意义;第七个参数flags用于指定对话框的样式。
函数的返回值是QString,也就是用户在QLineEdit里面输入的内容。
QInputDialog不仅提供了获取字符串的函数,还有getInteger,getDouble,getItem三个类似的函数。

Qt学习之路MainWindow学习过程中的知识点的更多相关文章

  1. Qt 学习之路 2(7):MainWindow 简介

    Qt 学习之路 2(7):MainWindow 简介  豆子  2012年8月29日  Qt 学习之路 2  29条评论 前面一篇大致介绍了 Qt 各个模块的相关内容,目的是对 Qt 框架有一个高屋建 ...

  2. Qt 学习之路 2(71):线程简介

    Qt 学习之路 2(71):线程简介 豆子 2013年11月18日 Qt 学习之路 2 30条评论 前面我们讨论了有关进程以及进程间通讯的相关问题,现在我们开始讨论线程.事实上,现代的程序中,使用线程 ...

  3. Qt 学习之路 2(70):进程间通信

    Qt 学习之路 2(70):进程间通信 豆子 2013年11月12日 Qt 学习之路 2 16条评论 上一章我们了解了有关进程的基本知识.我们将进程理解为相互独立的正在运行的程序.由于二者是相互独立的 ...

  4. Qt 学习之路 2(67):访问网络(3)

    Qt 学习之路 2(67):访问网络(3) 豆子 2013年11月5日 Qt 学习之路 2 16条评论 上一章我们了解了如何使用我们设计的NetWorker类实现我们所需要的网络操作.本章我们将继续完 ...

  5. Qt 学习之路 2(66):访问网络(2)

    Home / Qt 学习之路 2 / Qt 学习之路 2(66):访问网络(2) Qt 学习之路 2(66):访问网络(2)  豆子  2013年10月31日  Qt 学习之路 2  27条评论 上一 ...

  6. Qt 学习之路 2(61):使用 SAX 处理 XML

    Qt 学习之路 2(61):使用 SAX 处理 XML  豆子  2013年8月13日  Qt 学习之路 2  没有评论 前面两章我们介绍了使用流和 DOM 的方式处理 XML 的相关内容,本章将介绍 ...

  7. Qt 学习之路 2(60):使用 DOM 处理 XML

    Qt 学习之路 2(60):使用 DOM 处理 XML  豆子  2013年8月3日  Qt 学习之路 2  9条评论 DOM 是由 W3C 提出的一种处理 XML 文档的标准接口.Qt 实现了 DO ...

  8. Qt 学习之路 2(59):使用流处理 XML

    Qt 学习之路 2(59):使用流处理 XML 豆子 2013年7月25日 Qt 学习之路 2 18条评论 本章开始我们将了解到如何使用 Qt 处理 XML 格式的文档. XML(eXtensible ...

  9. Qt 学习之路 2(53):自定义拖放数据

    Qt 学习之路 2(53):自定义拖放数据 豆子  2013年5月26日  Qt 学习之路 2  13条评论上一章中,我们的例子使用系统提供的拖放对象QMimeData进行拖放数据的存储.比如使用QM ...

随机推荐

  1. 认清Javascript的地位并编写合理的Javascript代码

    作为前端程序员,一定要认清javascript的地位,不要被它乱七八糟的特点所迷惑.JavaScript主要是用来操控和重新调整DOM,通过修改DOM结构,从而达到修改页面效果的目的. 要用这个中心思 ...

  2. webpack打包处理html、css、js、img、scss文件

    webpack --help 查看webpack命令启动服务 npm run dev (先配置好服务)进入对应文件夹并初始化npmcd demo npm init 安装webpack npm inst ...

  3. 格式化JSON字符串

    提出需求 异步调用获取JSON数据时非常不直观,每次都需要格式化一次,才能直观的看到数据集合的结构,现在需要实现输出带缩进的格式. 实现效果 在浏览器的查看源文件中已经实现格式化,如果是页面使用,可以 ...

  4. Web.py 框架学习笔记 - ctx

    摘要: ctx用于存取web请求的环境变量,基于ThreadedDict类进行实例化.ThreadedDict类可实例化字典类型的对象,该对象某些属性可用于存取处理线程的id. 这样字典化实例的线程池 ...

  5. 物联网socket通讯设备android

    http://cache.baiducontent.com/c?m=9d78d513d99c16ee19bec1291a17a7384215c634608090027ea48439e573284b50 ...

  6. java对象 深度克隆(不实现Cloneable接口)和浅度克隆

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt128 为什么需要克隆: 在实际编程过程中,我们常常要遇到这种情况:有一个对象 ...

  7. WebForm页面间传值方法(转)

    Asp.NET WEB FORMS 给开发者提供了极好的事件驱动开发模式.Asp .NET为我们提供了三种方式,一种是可以通过用QueryString来传送相应的值,再一种是通过session变量来传 ...

  8. Spring Ioc DI 原理

    IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.Java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用 ...

  9. 集美大学网络1413第十一次作业成绩(团队七) -- Alpha冲刺之事后诸葛亮

    题目 团队作业7--Alpha冲刺之事后诸葛亮 团队作业7成绩  团队/分值 设想和目标 计划 资源 变更管理 设计/实现 测试/发布 团队角色. 管理.合作 总结 讨论照片 团队成员 角色.贡献 总 ...

  10. 201521123037 《Java程序设计》第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 1. String[] list1=str.split(" ...