欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt-窗口部件

程序员文章站 2022-05-30 17:32:58
...

窗口部件

  1. 基础窗口部件QWidget

QWidget类是所有用户界面对象的基类,被称为基础窗口部件。

  1. 窗口与子部件:
#include<QtWidgets>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //新建QWidget类对象,默认parent参数是0,所有它是个窗口
    QWidget *widget = new QWidget();
    //设置窗口标题
    widget->setWindowTitle(QObject::tr("我是窗口"));
    //新建QLabel对象,默认参数是0,所以它是个窗口
    QLabel *label=new QLabel();
    label->setWindowTitle(QObject::tr("我是label"));
    //设置要显示的信息
    label->setText(QObject::tr("label: 我是个窗口"));
    //改变部件大小,以便能显示出完整的内容
    label->resize(180,20);
    //label2指定了父窗口为widget,所以不是窗口
    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;
}

Qt-窗口部件

Qt-窗口部件

程序中定义了一个QWidget类对象的指针widget和两个Qlabel对象指针label和label2,其中label没有父窗口,而label2在widget中,widget是其父窗口。

注意:这里使用new操作符为label2分配了空间,但是并没有使用delete进行释放,这是因为在Qt中销毁父对象的时候会自动销毁子对象。

 

  1. 窗口类型

QWidget的构造函数有两个参数:QWidget * parent = 0和Qt::WindowFlags f = 0,前面的parent指父窗口部件,默认值为0,表明没有父窗口;而后面的f参数是Qt::WindowFlags类型的,是Qt::WindowType枚举类型的值或组合。 Qt::WindowType包括了很多类型,下面演示其中的Qt:Dialog和Qt::Splash-Screen,更改程序中新建对象的那两行代码:

QWidget *widget = new QWidget(0,Qt::Dialog);

QLabel *label=new QLabel(0,Qt::SplashScreen);

可以看到,更改窗口类型后窗口的样式发生了改变,一个是对话框类型,一个是欢迎窗口类型。 而窗口标志Qt::WindowFlags可以是多个窗口类型枚举值进行位或操作,下面再次更改那两行代码:

QWidget *widget = new QWidget(0,Qt::Dialog|Qt::FramelessWindowHint);

QLabel *label=new QLabel(0,Qt::SplashScreen|Qt::WindowStaysOnTopHint);

Qt::FramelessWindowHint用来产生一个没有边框的窗口,而Qt::WindowStaysOnTopHint用来使该窗口停留在所有其他窗口上面。

 

  1. 窗口几何布局

这里的函数分为两类:

包含框架: x(),y(),frameGeometry(),pos()和move()等函数;

不包含框架: geometry(),width(),height(),rect()和size()等函数。

使用qDebug()函数:

程序调试过程中常用的是qDebug()函数,它可以将调试信息直接输出到控制台。

#include <QApplication>
#include <QWidget>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QWidget widget;
    widget.resize(400, 300);       // 设置窗口大小
    widget.move(200, 100);         // 设置窗口位置
    widget.show();
    int x = widget.x();
    qDebug("x: %d", x);            // 输出x的值
    int y = widget.y();
    qDebug("y: %d", y);
    QRect geometry = widget.geometry();
    QRect frame = widget.frameGeometry();
    qDebug() << "geometry: " << geometry << "frame: " << frame;

    return a.exec();
}

这里使用了两种输出方法,一种是直接将字符串当作参数传给qDebug()函数,例如上面使用这种方法输出x和y的值。 另一种方法是使用输出流的方式一次输出多个值,它们的类型可以不同,如程序中输出geometry和frame的值。

在“return a.exec();”一行代码前添加如下代码:

    qDebug() << "geometry: " << geometry << "frame: " << frame;

qDebug()<<"pos:"<<widget.pos()<<endl<<"rect:"<<widget.rect()

       <<endl<<"size:"<<widget.size()<<endl<<"width:"

      <<widget.width()<<endl<<"height:"<<widget.height();

 

程序运行结果:

x: 200

y: 100

geometry: QRect(213,158 400x300) frame: QRect(200,100 426x371)

pos: QPoint(200,100)

rect: QRect(0,0 400x300)

size: QSize(400, 300)

width: 400

height: 300

 

其中,pos()函数返回窗口的位置,是一个坐标值,上面的x()和y()函数返回的就是它的x、y坐标值;rect()函数返回不包含边框的窗口内部矩形,窗口内部左上角是(0,0)点;size()函数返回不包含边框的窗口大小信息;width()和height()函数分别返回窗口内部的宽和高。

 

  1. 对话框QDialog
  1. 模态和非模态对话框

QDialog类是所有对话框窗口类的基类。 对话框窗口是一个经常用来完成短小任务或者和用户进行简单交互的顶层窗口。 按照运行对话框时是否还可以和该程序的其他窗口进行交互,对话框常被分为两类:模态的(model)和非模态的(modeless)。

#include "mywidget.h"
#include "ui_mywidget.h"

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    QDialog dialog(this);
    dialog.show();
}

在MyWidget类的构造函数中定义了一个QDialog类对象,还指定了dialog的父窗口为MyWidget类对象(即this参数的作用),最后调用show()函数让其显示。 运行程序时就发现,一个窗口一闪而过,然后就只显示MyWidget窗口了,为什么会这样呢?因为对于一个函数中定义的变量,等这个函数执行结束后,它就会自动释放。 也就是说,这里的dialog对象只在这个构造函数中有用,等这个构造函数执行完了,dialog也就消失了。 为了不让dialog消失,可以将QDialog对象的创建代码更改如下:

QDialog * dialog = new QDialog(this);

dialog->show();

Qt-窗口部件

其实,不用指针也可以让对话框显示出来,可以将创建代码更改如下:

QDialog dialog(this);

dialog.exec();

这时运行程序就会发现对话框弹出来了,但是MyWidget窗口并没有出来,当关闭对话框后,MyWidget窗口才弹出来。 这个对话框与前面那个对话框的效果不同,称它为模态对话框,而前面那种对话框称为非模态对话框。

模态对话框就是在没有关闭它之前,不能再与同一个应用程序的其他窗口进行交互,比如新建项目时弹出的对话框。 而对于非模态对话框,既可以与它交互,也可以与同一程序中的其他窗口交互,如Microsoft Word中的查找替换对话框。 就像前面看到的,要想使一个对话框成为模态对话框,则只需要调用它的exec()函数;而要使其成为非模态对话框,则可以使用new操作来创建,然后使用show()函数来显示。 其实使用show()函数也可以建立模态对话框,只须在其前面使用setModal()函数即可。

   QDialog * dialog = new QDialog(this);

   dialog->setModal(true);

   dialog->show();

Qt-窗口部件

运行程序后可以看到,生成的对话框是模态的。 但是,它与用exec()函数时的效果是不一样的,因为现在的MyWidget窗口也显示出来了。

 

  1. 多窗口切换

认识信号和槽:

Qt中使用信号和槽机制来完成对象之间的协调操作。

双击mywidget.ui文件,在设计模式中往界面添加一个Label和一个Push Button,在属性栏中将Push Button的objectName改为showChildButton,然后更改Label的显示文本为“我是主界面!”,更改按钮的显示文本为“显示子窗口”。 然后回到编辑模式打开mywidget.h文件,在MyWidget类声明的最后添加槽的声明:

public slots:

    void showChildDialog();

Qt-窗口部件

在mywidget.cpp文件中将showChildDialog()槽的实现更改如下:

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()函数将按钮的单击信号clicked()与新建的槽进行关联。 C

这个函数中的4个参数分别是发射信号的对象、发射的信号、接受信号的对象和要执行的槽。 运行程序,然后单击主界面上的按钮就会弹出一个对话框。

Qt-窗口部件

自定义对话框:

第一步: 添加自定义对话类框。 首先向该项目中添加Qt设计师界面类。 然后在设计模式中向窗口添加两个Push Button,并且分别更改其显示文本为“进入主界面”和“退出程序”。

第二步: 设计信号和槽。 在“进入主界面”按钮上右击,在弹出的级联菜单中选择“转到槽”,然后在弹出的对话框中选择clicked()信号,并单击OK。 这时便会进入代码编辑模式,并且定位到自动生成的on_pushButton_clicked()槽中。 在其中添加代码:

void MyDialog::on_pushButton_clicked()

{

    accept();

}

在主界面中使用自定义的对话框:

更改main.cpp函数内容如下:

#include "mywidget.h"
#include <QApplication>
#include "mydialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyDialog dialog;                        // 新建MyDialog类对象
    if(dialog.exec()==QDialog::Accepted){   // 判断dialog执行结果
        MyWidget w;
        w.show();              // 如果是按下了“进入主界面”按钮,则显示主界面
        return a.exec();                    // 程序正常运行
    }
    else return 0;                          // 否则,退出程序
}

主函数中建立MyDialog对象,然后判断其exec()函数返回值,如果按下了“进入主界面”按钮,返回值应该是QDialog::Accepted,则显示主界面,并且正常执行程序;如果不是,则直接退出程序。

双击mywidget.ui文件,在设计模式中再向界面添加两个Push Button,分别更改它们的显示文本为“重新登陆”和“退出”。 然后使用信号和槽模式将“退出”按钮的clicked()信号和MyWidget界面的close()槽关联。 完成后再转到“重新登陆”按钮的clicked()信号的槽,并更改如下:

void MyWidget::on_pushButton_clicked()
{
    // 先关闭主界面,其实它是隐藏起来了,并没有真正退出。然后新建MyDialog对象
    close();
    MyDialog dlg;
    // 如果按下了“进入主窗口”按钮,则再次显示主界面
    // 否则,因为现在已经没有显示的界面了,所以程序将退出
    if(dlg.exec() == QDialog::Accepted) show();
}

Qt-窗口部件

Qt-窗口部件

  1. 标准对话框

Qt-窗口部件

颜色对话框:

颜色对话框类QColorDialog提供了一个可以获取指定颜色的对话框部件。 先在mywidget.cpp文件中添加#include<QDebug>和#include<QColorDialog>头文件,然后从设计模式进入“颜色对话框”按钮的clicked()单击信号槽,更改如下:

void MyWidget::on_pushButton_clicked()

{

    QColor color=QColorDialog::getColor(Qt::red,this,tr("颜色对话框"));

    qDebug()<<"color: "<<color;

}

这里使用了QColorDialog的静态函数getColor()来获取颜色,它的3个参数的作用分别是:设置初始颜色、指定父窗口和设置对话框标题。

 

文件对话框:

文件对话框QFileDialog类提供了一个允许用户选择文件或文件夹的对话框。 继续在mywidget.cpp中添加#include<QFileDialog>头文件,然后从设计模式转到“文件对话框”按钮的单击信号槽,并更改如下:

void MyWidget::on_pushButton_2_clicked()

{

    QString fileName=QFileDialog::getOpenFileName(this,tr("文件对话框"),

                                                  "D: ",tr("图片文件(*png *jpg)"));

    qDebug()<<"fileName: "<<fileName;

}

这里使用了QFileDialog类中的getOpenFileName()函数来获取选择的文件名,这个函数会以模态方式运行一个文件的对话框。 打开后选择一个文件,单击“打开”按钮后,这个函数便可以返回选择的文件的文件名。 它的4个参数的作用分别是:指定父窗口、设置对话框标题、指定默认打开的目录路径和设置文件类型过滤器。

如果不指定文件过滤器,则默认选择所有类型的文件。 这里指定了只选择png和jpg两种格式的图片文件。

Qt-窗口部件

字体对话框:

字体对话框QFontDialog类提供了一个可以选择字体的对话框部件。 先添加#include<QFontDialog>头文件,然后转到“字体对话框”按钮的单击信号槽,更改如下:

void MyWidget::on_pushButton_3_clicked()
{
    //ok用于标记是否单击了OK按钮
    bool ok;
    QFont font=QFontDialog::getFont(&ok,this);
    //如果单击OK按钮,那么让“字体对话框”按钮使用新字体
    //如果单击Cancel按钮,那么输出信息
    if(ok)ui->pushButton_3->setFont(font);
    else qDebug()<<tr("没有选择新字体!");
}

Qt-窗口部件

输入对话框:

输入对话框QInputDialog类用来提供一个对话框,可以让用户输入一个单一的数值或字符串。 先添加头文件#include<QInputDialog>,然后进入“输入对话框”按钮的单击信号槽,更改如下:

void MyWidget::on_pushButton_4_clicked()
{
    bool ok;
    //获取字符串
    QString string=QInputDialog::getText(this,tr("输入字符串对话框"),tr("请输入用户名:"),
                                         QLineEdit::Normal,tr("admin"),&ok);
    if(ok)qDebug()<<"string: "<<string;
    //获取整数
    int value1=QInputDialog::getInt(this,tr("输入整数对话框"),
                                   tr("请输入-1000到1000之间的数值"),100,-1000,1000,10,&ok);
    if(ok)qDebug()<<"value1: "<<value1;
    //获取浮点数
    double value2=QInputDialog::getDouble(this,tr("输入浮点数对话框"),
                                          tr("请输入-1000到1000之间的数值"),0.00,
                                          -1000,1000,2,&ok);
    if(ok)qDebug()<<"value2: "<<value2;
    QStringList items;
    items<<tr("条目 1")<<tr("条目 2");
    //获取条目
    QString item=QInputDialog::getItem(this,tr("输入条目对话框"),
                                       tr("请选择或输入一个条目"),items,0,true,&ok);
    if(ok) qDebug()<<"item:"<<item;
}

这里一共创建了4个不同类型的输入对话框。

getText()函数可以提供一个可输入字符串的对话框,各参数的作用分别是:指定父窗口、设置窗口标题、设置对话框中的标签显示文本、设置输入字符串的显示模式(例如密码可以显示成小黑点,这里选择了显示用户输入的实际内容)、设置输入框中的默认字符串和设置获取按下按钮信息的bool变量。

getInt()函数可以提供一个输入整型数值的对话框,其中的参数100表示默认的数值是100,-1000表示可输入的最小值是-1000,1000表示可输入的最大值是1000,10表示使用箭头按钮,数值每次变化10。

getDouble()函数可以提供一个输入浮点型数值的对话框,其中的参数2表示小数的位数为2。

getItem()函数提供一个可以输入一个条目的对话框,需要先给它提供一些条目,例如这里定义的QStringList类型的items,其中参数0表示默认显示列表中的第0个条目(0就是第一个),参数true设置条目是否可以被更改,true就是可以被更改。

Qt-窗口部件

Qt-窗口部件

Qt-窗口部件

Qt-窗口部件

消息对话框:

消息对话框QMessageBox类提供了一个模态的对话框来通知用户一些信息,或者向用户提出一个问题并且获取答案。 先添加头文件#include<QMessageBox>,然后转到“消息对话框”按钮的单击信号槽中,添加如下代码:

void MyWidget::on_pushButton_5_clicked()
{
    // 问题对话框
    int ret1 = QMessageBox::question(this, tr("问题对话框"),
                                     tr("你了解Qt吗?"), QMessageBox::Yes, QMessageBox::No);
    if(ret1 == QMessageBox::Yes) qDebug() << tr("问题!");
    // 提示对话框
    int ret2 = QMessageBox::information(this, tr("提示对话框"),
                                        tr("这是Qt书籍!"), QMessageBox::Ok);
    if(ret2 == QMessageBox::Ok) qDebug() << tr("提示!");
    // 警告对话框
    int ret3 = QMessageBox::warning(this, tr("警告对话框"),
                                    tr("不能提前结束!"), QMessageBox::Abort);
    if(ret3 == QMessageBox::Abort) qDebug() << tr("警告!");
    // 错误对话框
    int ret4 = QMessageBox::critical(this, tr("严重错误对话框"),
                                     tr("发现一个严重错误!现在要关闭所有文件!"), QMessageBox::YesAll);
    if(ret4 == QMessageBox::YesAll) qDebug() << tr("错误");
    // 关于对话框
    QMessageBox::about(this, tr("关于对话框"),
                       tr("Qt Creator"));

}

这里创建了4个不同类型的消息对话框,分别拥有不同的图标还有提示音,几个参数分别用于设置父窗口、标题栏、显示信息和拥有的按钮。

Qt-窗口部件

Qt-窗口部件

Qt-窗口部件

Qt-窗口部件

Qt-窗口部件

进度对话框:

进度对话框QProgressDialog对一个耗时较长操作的进度提供了反馈。 先添加#include<QProgessDialog>头文件,然后转到“进度对话框”按钮的单击信号槽,更改如下:

void MyWidget::on_pushButton_6_clicked()
{
    QProgressDialog dialog(tr("文件复制进度"), tr("取消"), 0, 50000, this);
    dialog.setWindowTitle(tr("进度对话框"));     // 设置窗口标题
    dialog.setWindowModality(Qt::WindowModal);  // 将对话框设置为模态
    dialog.show();
    for(int i=0; i<50000; i++) {                // 演示复制进度
        dialog.setValue(i);                     // 设置进度条的当前值
        QCoreApplication::processEvents();      // 避免界面冻结
        if(dialog.wasCanceled()) break;         // 按下取消按钮则中断
    }
    dialog.setValue(50000);    // 这样才能显示100%,因为for循环中少加了一个数
    qDebug() << tr("复制结束!");
}

这里首先创建一个QProgressDialog类对象,构造函数的参数分别用于设置对话框的标签内容、取消按钮的显示文本、最小值、最大值和父窗口。 然后将对话框设置为模态并进行显示。 for()循环语句模拟了文件复制过程,setValue()函数使进度条向前推进;为了避免长时间操作而使用户界面冻结,必须不断地调用QCoreApplication类地静态函数processEvent(),可以将它放在for()循环语句中。 使用QProgressDialog的wasCanceled()函数来判断用户是否按下了“取消”按钮,如果是,则中断复制过程。

Qt-窗口部件

错误信息对话框:

错误信息对话框QErrorMessage类提供了一个显示错误信息的对话框。 首先打开mywidget.h文件添加类前置声明:

class QErrorMessage;

然后添加私有对象:

QErrorMessage *errordlg;

下面到mywidget.cpp添加头文件#include <QErrorMessage>,并在构造函数中添加如下代码:

errordlg = new QErrorMessage(this);

然后从设计模式转到“错误消息对话框”按钮的单击信号槽添加代码:

void MyWidget::on_pushButton_7_clicked()

{

    errordlg->setWindowTitle(tr("错误信息对话框"));

    errordlg->showMessage(tr("这里是出错信息!"));

}

这里首先新建了一个QErrorMessage对话框,并且调用它的showMessage()函数来显示错误信息,调用这个函数时对话框会以非模态的形式显示出来。

Qt-窗口部件

向导对话框:

向导对话框QWizard类提供了一个设计向导界面的框架。

打开mywidget.h文件,然后添加头文件#include<QWizard>,在MyWidget类的声明中添加private类型函数声明:

private:
    Ui::MyWidget *ui;
    QWizardPage *createPage1();        // 新添加
    QWizardPage *createPage2();        // 新添加
    QWizardPage *createPage3();        // 新添加
这里声明了3个返回值为QWizardPage类对象的指针函数,用来生成3个向导页面,然后在mywidget.cpp文件中对这3个函数进行定义:
QWizardPage * MyWidget::createPage1()  // 向导页面1
{
    QWizardPage *page = new QWizardPage;
    page->setTitle(tr("介绍"));
    return page;
}
QWizardPage * MyWidget::createPage2()  // 向导页面2
{
    QWizardPage *page = new QWizardPage;
    page->setTitle(tr("用户选择信息"));
    return page;
}
QWizardPage * MyWidget::createPage3()  // 向导页面3
{
    QWizardPage *page = new QWizardPage;
    page->setTitle(tr("结束"));
    return page;
}

在各个函数中分别新建了向导页面,并且设置了它们的标题。 下面转到“向导对话框”按钮的单击信号槽中,更改如下:

void MyWidget::on_pushButton_8_clicked()
{
    QWizard wizard(this);
    wizard.setWindowTitle(tr("向导对话框"));
    wizard.addPage(createPage1());     // 添加向导页面
    wizard.addPage(createPage2());
    wizard.addPage(createPage3());
    wizard.exec();
}

这里新建了QWizard类对象,然后使用addPage()函数为其添加了3个页面。 这里的参数是QWizardPage类型的指针,可以直接调用生成向导页面函数。

Qt-窗口部件

Qt-窗口部件

Qt-窗口部件

  1. 其他窗口部件
  1. QFrame类族

QFrame类是带有边框的部件的基类。

QLabel:

标签QLabel部件用来显示文本或者图片。 在设计器中向界面拖入一个Label,然后将其拖大点,并在属性栏中设置对其方式alignment的属性,水平的改为AlignHCenter,垂直的改为AlignVCenter,这样QLabel中的文本就会在正中间显示。 font属性可以对字体进行设置,也可以通过代码进行设置,下面打开mywidget.cpp文件,在构造函数中添加如下代码:

    QFont font;

    font.setFamily("华文行楷");

    font.setPointSize(20);

    font.setBold(true);

    font.setItalic(true);

ui->label->setFont(font);

首先在mywidget.cpp文件中添加头文件#include<QPixmap>,然后在构造函数中添加:

ui->label->setPixmap(QPixmap("logo.png"));

这样就可以在标签中显示logo.png图片了。

在mywidget.cpp中添加头文件#include<QMovie>,然后在myWidget的构造函数中继续添加:

    QMovie *movie = new QMovie("donghua.gif");

    ui->label->setMovie(movie);                  // 在标签中添加动画

movie->start();

 

QLCDNumber:

QLCDNumber部件可以让数码字符显示类似液晶数字一样的效果。

 

  1. 按钮部件

QAbstractButton类是按钮部件的抽象基类,提供了按钮的通用功能。 它的子类包括复选框QCheckBox、标准按钮QPushButton、单选框按钮QRadioButton和工具按钮QToolButton。

 

 

 

相关标签: Qt 窗口部件