Qt学习第3节课

目录

  1. 1. 第三章窗口部件
    1. 1.1. 3.1基础窗口部件QWidget
      1. 1.1.1. 3.1.1窗口、子部件以及窗口类型
      2. 1.1.2. 3.1.2窗口几何布局
      3. 1.1.3. 3.1.3程序调试
    2. 1.2. 3.2 对话框QDialog
      1. 1.2.1. 3.2.1 模式和非模式对话框
      2. 1.2.2. 3.2.2 多窗口切换
        1. 1.2.2.0.1. 1.认识信号和槽
    3. 1.2.3. 3.2.3标准对话框
      1. 1.2.3.1. 1.颜色对话框
      2. 1.2.3.2. 2.文件对话框
      3. 1.2.3.3. 3.字体对话框

第三章窗口部件

3.1基础窗口部件QWidget

Qt creator提供的默认类型只有QMainWindow、QWidget、QDialog三种。
其中QMainWindow是带有菜单栏和工具栏的主窗口类,QDialog是各种对话框的基类,他们全部继承自QWidget,不仅如此,其实所有的窗口部件都继承自QWidget。

3.1.1窗口、子部件以及窗口类型

  1. 窗口与子部件
    例子1,创建空的qmake项目

     //mywidget1.pro
     greaterThan(QT_MAJOR_VERSION, 4):QT +=widgets
    
     SOURCES += \
     main.cpp
     //============
     //main.cpp
         #include"QtWidgets"
    
     int main(int argc, char* argv[])
     {
         QApplication a(argc, argv);
         QWidget *widget = new QWidget(); //新建QWidget类对象,默认parent参数是0,所以他是个窗口
         widget->setWindowTitle(QObject::tr("我是widget"));
    
         QLabel *label = new QLabel();   //新建QLabel类,默认parent参数为0
         label->setWindowTitle(QObject::tr("我是label"));
         label->setText(QObject::tr("label:我是窗口"));  //设置显示的信息
         label->resize(180, 20);
    
         QLabel * label2 = new QLabel(widget);
         label2->setText(QObject::tr("label2:我不是独立窗口,只是widget的子窗口"));
         label2->resize(250, 20);
    
         label->show();
         widget->show();
    
         int ret = a.exec();
         delete label;
         delete widget;
         return ret;
     }
    
     /*
     结果:
     显示两个窗口。
     */
  2. 窗口类型
    QWidget的构造函数有两个参数:QWidget *parent = 0Qt::WindowFlags f=0,前面的parent指父窗口部件,默认值为0,表明没有父窗口;而后面的f参数是Qt::WindowFlags类型的,是Qt::WindowFlags枚举类型值得或组合,指明各种窗口系统类型属性;f=0为Qt::widget,其他还有:Qt::DialogQt::SplashScreen
    于是将上面的代码中的两行改成这样:

     QWidget *widget = new QWidget(0, Qt::Dialog);    //对话框
     Qlabel *label = new label(0, Qt::SplashScreen`);//欢迎窗口

    再次更改:

     QWidget *widget = new QWidget(0, Qt::Dialog | Qt::FramelessWindowHint);    
     Qlabel *label = new label(0, Qt::SplashScreen`);
     //Qt::FramelessWindowHint 用来产生一个没有边框的窗口,而Qt::WindowStaysTopHint用来使该窗口停留在其他窗口上面。

    补充:QWidget中还有一个setWindowState()函数用来设置窗口的状态,其参数由Qt::WindowState枚举类型值得或组合。
    Qt::WindowMaxmized—最大化
    Qt::WindowMinmized—最小化
    Qt::WindowFullScreen—全屏显示
    Qt::WindowActive—活动窗口
    默认是Qt::WindowNostate

3.1.2窗口几何布局

3.1.3程序调试

  1. 程序自带,
  2. 使用qDebug()函数qDebug() << xxx,使用之前要在前面添加#include "QDebug"

3.2 对话框QDialog

3.2.1 模式和非模式对话框

QDialog类是所有对话框窗口类的基类。对话框窗口是一个经常用来完成短小任务或者和用户进行简单交互的顶层窗口。按照运行对话框时是否还可以和该程序的其他窗口进行交互,对话框经常被分为两类:模态的(model)和非模态的(modeless)。
例子_1讲解
创建基类为QWidget的工程,类名为MyWidget,然后在mywidget.cpp中添加如下代码:

#include "mywidget.h"
#include "ui_mywidget.h"
#include "QDialog"
myWidget::myWidget(QWidget *parent): QWidget(parent), ui(new Ui::myWidget)
{
    ui->setupUi(this);
    QDialog dialog(this);    //定义了一个parent为this的对象
    dialog.show();
}
myWidget::~myWidget()
{
    delete ui;
}

运行结果:有一个窗口一闪而过,显示MyWidget窗口,原因在于,dialog对象只是在这个构造函数中有用,等构造函数执行结束,dialog也会消失。为了不让dialog消失,可以改成如下代码:

QDialog *dialog = new QDialog(this); //定义了一个指向QDialog类对象的指针变量
dialog->show();

窗口一闪而过的现象消失了。原因分析:使用QDialog对象指针,并使用new运算符开辟了内存空间,再运行程序就可以正常显示了。
其实也可以不用指针也可以实现对话框显示:

QDialog dialog(this);
dialog.exec();

执行结果便是:对话框弹出来,而MyWidget窗口并没有,当关闭对话框窗口时,MyWidget窗口才出现。我们把这种对话框称为模态对话框,前面的称为非模态对话框
完整定义:
模态对话框就是在关闭它之前,不能再与同一个应用程序的其他窗口进行交互。例如:新建项目的弹出对话框。
非模态对话框,既可以进行交互,也可以与同一程序中的其他窗口进行交互。

    QDialog *dialog = new QDialog(this);
    dialog->setModal(true);
    dialog->show();

执行结果分析:生成的对话框是模式的,但是,他与exec()函数时的效果是不一样的,因为现在MyWidget窗口也显示出来了。这是因为调用完show()函数后立即将控制权交给调用者,程序可以继续执行。而使用exec()函数不同,只有当对话框被关闭时才会返回。
setModel()函数相似的还有:setWindowModality()函数,它有一个参数来设置模态对话框要阻塞的窗口类型,它可以是Qt::NonModel(不阻塞任何窗口,就是非模态)、Qt::WindowModel(阻塞他的父窗口,所有祖先窗口以及他们的子窗口)或者Qt::ApplicationModel(阻塞整个应用程序的所有窗口),默认为Qt::ApplicationModel

3.2.2 多窗口切换

1.认识信号和槽

认识:Qt中使用信号和槽机制来完成对象之间的协同操作。信号和槽都是函数,例如点击窗口上的一个按钮后想要弹出一个对话框,那么可以将这个按钮的点击信号和自定义的槽关联起来。
1.自己手写:
第一步:在窗口头文件中,这里是myWidget.h里面,类为mywidget,加入

public slots:
    void showChildDialog();

还有就是更改.ui文件,加入pushButton和Label
第二步:在窗口文件(非ui文件)中,这里是myWidget.cpp中加入,将槽函数进行外部定义

void MyWidget::showChildDialog()
{
    QDialog * dialog = new QDialog(this);
    dialog->show();
}

更改MyWidget类的构造函数,可以改成这样:

myWidget::myWidget(QWidget *parent) : QWidget(parent), ui(new Ui::myWidget)
{
    ui->setupUi(this);
    connect(ui->showChildButton, &QPushButton::clicked, this, &myWidget::showChildDialog);
}

关于connect()函数的说明解释:
第一个参数是:发射信号的对象
第二个参数是:发射的信号
第三个参数是:接收信号的
第四个参数是:要执行的槽
2.自定义对话框
文件结构为

mydialog.h
mywidget.h
main.cpp
mydialog.cpp
mywidget.cpp
mydialog.ui
mywidget.ui

这里先编辑dialog窗口,后编辑widget窗口
加入退出按钮

  1. 在对应ui文件中进行修改,选中Edit Signal/Slots F4,左键选中,拖动到窗口界面上,这时松开鼠标左键,在弹出的配置连接对话框中选择“显示QWidget继承的信号和槽”选项,然后再左边的QpushButton栏中选择信号clicked(),在右边的QDialog栏中选择对应的槽close(),完成之后点击OK。
  2. 进入主界面按钮的信号和槽的关联。左键选中,选择转到槽,进入代码编辑界面。一般是窗口.cpp文件。
void MyDialog::on_pushButton_clicked()
{
    accept();
}

这个accept()函数是QDialog类中的一个槽,对于exec()函数实现的模态对话框,执行了这个槽就会隐藏这个模态对话框,并返回QDialog::Accept值,这里就是要使用这个值来判断是哪个按钮被按下了。

  1. 主界面中使用自定义的对话框,更改main.cpp
#include "mywidget.h"
#include "mydialog.h"
#include "QDebug"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    myWidget w;
    myDialog dia;
    if(dia.exec() == QDialog::Accepted){
        w.show();
        qDebug() << "正确_1";
        return a.exec();
    }
    else
        return 0;
}

双击mywidget.ui文件,在设计模式中加入两个Push Button,命名 重新登陆, 退出
重新登陆中加入:

void myWidget::on_pushButton_clicked()
{
    close();
    myDialog dlg;
    if(dlg.exec() == QDialog::Accepted){
        qDebug() << "正确_2";
        show();
    }
}

3.2.3标准对话框

Qt提供了一些常见的对话框类型,他们全部继承自QDialog类,并增加了自己的特色功能,比如获取颜色、显示特定信息等。

1.颜色对话框

第一步建立QWidgets,点击ui文件编辑,拖拽一个PushButton
第二步,转到槽,进行如下编辑:

//先在文件头加入#include<QDebug>,#include<QColorDialog>
void myWidget::on_pushButton_clicked()
{
    QColor color = QColorDialog::getColor(Qt::red, this, tr("颜色对话框"));
    qDebug()<<"color: "<<color;
}

getColor()函数解释:第一个参数是设置默认值;第二个参数是设置parent值这里填this;第三个参数填标题,还有第四个参数,其他设置。例如加入:QColorDialog::ShowAlphaChannel,改变颜色值显示办法。

2.文件对话框

第一步,如法炮制。
第二步,转到槽,改写槽函数

//在.cpp中添加#include "QFileDialog"
void myWidget::on_pushButton_2_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,tr("文件对话框"),"D:",tr("图片文件(*png *jpg)"));
    qDebug() << "fileName: "<< fileName;
}

getOpenFileName()函数的解释:第一个参数是parent值;第二个参数是弹出框的标题,具体是点击按钮之后弹出窗口的标题;第三个标题是选择路径;第四个参数是选择文件类型,文件类型方面可以是多样性的,例如改其为:tr("图片文件(*png *jpg);;文本文件(*txt)");,中间用;;隔开。

选择多个文件 :将函数改成getOpenFileNames即可。还有获取文件路径:getExistingDirectory函数。

3.字体对话框

第一步,如法炮制。
第二步,转到槽,改写槽函数。

//在.cpp文件中添加#include "QFontDialog"
void myWidget::on_pushButton_3_clicked(bool checked)
{
    QFont font = QFontDialog::getFont(&checked, this);
    if(checked)
        ui->pushButton_3->setFont(font);
    else
        qDebug() << tr("没有选择字体");
}

函数getFont()解释:返回判断按钮是否被点击,返回parent