18、登录对话框示例分析25计时器

18、登录对话框示例分析

登录对话框是应用程序中常用部件。

思考:如何开发一个可以在不同项目间复用的登录对话框?

登录对话框需求分析:可复用软件部件。获取用户名和密码。附加需求:随机验证码。

如何获取用户输入的用户名和密码?

如何在两个不同的对话框间传递数据?

通过附加的成员变量和成员函数完成不同对话框间的数据传递。

检查用户名和密码是否为空:提示错误

随机验证码:当验证码输入错误时进行提示,验证码随机刷新。

小结:登录对话框作为可复用的软件部件进行开发。对话框之间通过成员变量和成员函数传递数据。

将用户数据保存在私有成员变量中,通过公有成员函数进行数据传递。

#include <QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
#ifndef _WIDGET_H_
#define _WIDGET_H_
#include <QWidget>
#include <QPushButton>
class Widget : public QWidget
{
    Q_OBJECT
private:
    QPushButton TestBtn;
private slots:
    void TestBtn_Clicked();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};
#endif
#include "Widget.h"
#include "QLoginDialog.h"
#include <QDebug>
Widget::Widget(QWidget *parent) : QWidget(parent), TestBtn(this)
{
    TestBtn.setText("Test Login Dialog");

    setFixedSize(200, 50);

    connect(&TestBtn, SIGNAL(clicked()), this, SLOT(TestBtn_Clicked()));
}
void Widget::TestBtn_Clicked()
{
    QLoginDialog dlg;
    if( dlg.exec() == QDialog::Accepted )
    {
        qDebug() << "User: " + dlg.getUser();
        qDebug() << "Pwd: " + dlg.getPwd();
    }
}
Widget::~Widget()
{

}
#ifndef _QLOGINDIALOG_H_
#define _QLOGINDIALOG_H_

#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>

class QLoginDialog : public QDialog
{
    Q_OBJECT
private:
    QLabel UserLabel;
    QLabel PwdLabel;
    QLineEdit UserEdit;
    QLineEdit PwdEdit;
    QPushButton LoginBtn;
    QPushButton CancelBtn;
    QString m_user;  //保存用户名和密码
    QString m_pwd;
private slots:
    void LoginBtn_Clicked();
    void CancelBtn_Clicked();
public:
    QLoginDialog(QWidget *parent = 0);
    QString getUser();
    QString getPwd();
    ~QLoginDialog();
};
#endif
#include "QLoginDialog.h"

#include <QDebug>

QLoginDialog::QLoginDialog(QWidget* parent) : QDialog(parent, Qt::WindowCloseButtonHint),
    UserLabel(this), PwdLabel(this), UserEdit(this), PwdEdit(this), LoginBtn(this), CancelBtn(this)
{
    UserLabel.setText("User ID:");
    UserLabel.move(20, 30);
    UserLabel.resize(60, 25);

    UserEdit.move(85, 30);
    UserEdit.resize(180, 25);
    PwdLabel.setText("Password:");
    PwdLabel.move(20, 65);
    PwdLabel.resize(60,25);
    PwdEdit.move(85, 65);
    PwdEdit.resize(180, 25);
    PwdEdit.setEchoMode(QLineEdit::Password); //设置不显示
    CancelBtn.setText("Cancel");
    CancelBtn.move(85, 110);
    CancelBtn.resize(85, 30);
    LoginBtn.setText("Login");
    LoginBtn.move(180, 110);
    LoginBtn.resize(85, 30);
    setWindowTitle("Login");
    setFixedSize(285, 170); //固定大小
    connect(&LoginBtn, SIGNAL(clicked()), this, SLOT(LoginBtn_Clicked()));
    connect(&CancelBtn, SIGNAL(clicked()), this, SLOT(CancelBtn_Clicked()));
}
void QLoginDialog::LoginBtn_Clicked()
{
    qDebug() << "LoginBtn_Clicked() Begin";
    m_user = UserEdit.text().trimmed(); //取得用户输入
    m_pwd = PwdEdit.text();
    done(Accepted); //点击登录,返回
    qDebug() << "LoginBtn_Clicked() End";
}
void QLoginDialog::CancelBtn_Clicked()
{
    qDebug() << "CancelBtn_Clicked() Begin";
    done(Rejected); //点击取消,返回
    qDebug() << "CancelBtn_Clicked() End";
}
QString QLoginDialog::getUser()
{
    return m_user;
}
QString QLoginDialog::getPwd()
{
    return m_pwd;
}
QLoginDialog::~QLoginDialog()
{
}

19、qt中的标准对话框

qt为开发者提供了一些可复用的对话框类型。

qt提供的可复用对话框全部继承自QDialog类。

qt中的标准对话框遵循相同的使用方式:

定义对话框对象

DialogType dlg(this);

设置对话框属性

dlg.setPropertyxxx(value);

if(dlg.exec())==DialogTyupe::value)

{ //获取对话框数据

Type v=dlg.getDialogValue();

//处理对话框数据 }

1消息对话框:消息对话框是应用程序中最常见的界面元素:

消息对话框主要用于:为用户提示重要信息,强制用户进行操作选择。

消息对话框的使用方式:

//构造消息对话框对象

QMessageBox msg(this);

//设置消息对话框的相关属性。

msg.setText("this is a "); //标题

msg.setWindowTitle("title");  //提示消息

msg.setIcon(QMessageBox::Information): //设置图标

msg.setStandardBuuttons( QMessageBox::OK|QMessageBox::Cancel |QMessageBox::YesToALL); );  //设置按钮

if( msg.exec()==QMwssageBox::Ok)  {  qDebug()<<"ok button is clicked!"; }  

QMessageBox中的实用函数:

QMessageBox::qustion

QMessageBox::information

QMessageBox::warning

QMessageBox::critical

QMessageBox::about

练习。

2文件对话框:常用于以下情形

Open Mode:应用程序中需要用户打开一个外部的文件

Save Mode:应用程序中需要将当前内容存储于用户指定的外部文件中。

使用方式:

QFileDialog fd(this);

// save mode:QFileDialog::AcceptSave //保存模式

fd.setAcceptMode(QFileDialog::AcceptOpen); //设置属性,打开模式

fd.setFileMode(QFileDialog::ExistingFile); //一次只打开一个存在的文件。多个文件,多个加s

//fd.setFileMode(QFileDialog::ExistingFiles); //打开多个文件,多加个s

if( fd.exec()==QFileDialog::Accepted ) //调用exec,文件对话框在屏幕上显示

{  QStringList fs=fd.selectedFiles(); } //得到用户选择的文件

文件类型过滤器:setFilter("Text(*.*)")

在文件对话框中可以通过文件后缀定义过滤器

过滤器定义规则:显示名(*.后缀1 *.后缀2...*.后缀N)

例:“Image(*.png *.xpm *.jpg)”//显示 .png *.xpm *.jpg三个,空格隔开

"Text(*.txt)"  //仅仅是txt文本文件,Text代表了这些文件

“All(*.*)”

小结:

Qt中提供了多个可复用的对话框类型:继承于QDialog类型,遵循相同的使用方式。QMessageBox用于提示重要的程序信息,QFileDialog用于获取系统中的文件路径。

 //dlg.setFilter( "Text(*.txt)" );

QFileDialog中的实用函数:

QFileDialog::getOpenFileName

QFileDialog::getOpenFileNames

QFileDialog::getSaveFileName

20、标准对话框(中)

qt中提供了预定义的颜色对话框QColorDialog类

QColorDialog类用于提供指定颜色的对话框部件。

颜色对话框的使用方式:

//构造颜色对话框对象

QColorDialog dlg(this);

//设置颜色对话框的相关属性

dlg.setWindowTetle("Color Editor");

dlg.setCurrentColor(Qt::red);//初始颜色

if(dlg.exec()==QColorDialog::Accepted)

{

qDebug()<<dlg.selectedColor();

}

Qt中的QColor类用于在程序中表示颜色的概念,QColor类同时支持多种颜色表示方式:

RGB:以红、绿、蓝为基准的三色模型。

HSV:以色调,饱和度、明度为基准的六角椎体模型。

CMYK:以天蓝,品红,黄色,黑为基准的全彩印刷色彩模型。

QColorDialog中的实用函数:

QColorDialog::getColor

输入对话框:qt中提供了预定义的输入对话框QInputDialog类

QInputDialog类用于需要临时进行数据输入的场合。使用方式:

//构造输入对话框对象

QInputDialog dlg(this);

//设置输入对话框的相关属性

dlg.setWindowTitle("Input...")'

dlg.setLabelTest("please enter a interger:");

dlg.setInputMode(QInputDialog::IntInput);//输入的是什么,这里输入整型数

if(dlg.exec()==QInputDialog::Accepted)

{ qDebug<<dlg.intValue();  }

输入对话框的输入模式:

QInputDialog::TextInput -输入文本字符串

QInputDialog::IntInput-输入整型数

QInputDialog::Double Inout-输入浮点数

#ifndef _WIDGET_H_
#define _WIDGET_H_
#include <QtGui/QWidget>
#include <QPushButton>
class Widget : public QWidget
{
    Q_OBJECT
private:
    QPushButton ColorDialogBtn;
    QPushButton InputDialogBtn;
private slots:
    void ColorDialogBtn_Clicked();
    void InputDialogBtn_Clicked();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif

#include "Widget.h"
#include <QDebug>
#include <QColorDialog>
#include <QInputDialog>
Widget::Widget(QWidget *parent) : QWidget(parent),
    ColorDialogBtn(this), InputDialogBtn(this)
{
    ColorDialogBtn.setText("Color Dialog");
    ColorDialogBtn.move(20, 20);
    ColorDialogBtn.resize(160, 30);
    InputDialogBtn.setText("Input Dialog");
    InputDialogBtn.move(20, 70);
    InputDialogBtn.resize(160, 30);
    resize(200, 120);
    setFixedSize(200, 120);
    connect(&ColorDialogBtn, SIGNAL(clicked()), this, SLOT(ColorDialogBtn_Clicked()));
    connect(&InputDialogBtn, SIGNAL(clicked()), this, SLOT(InputDialogBtn_Clicked()));
}

void Widget::ColorDialogBtn_Clicked()
{
    QColorDialog dlg(this);
    dlg.setWindowTitle("Color Editor");
    dlg.setCurrentColor(QColor(100, 111, 222));//直接调用构造函数生成临时对象
    if( dlg.exec() == QColorDialog::Accepted )
    {
        QColor color = dlg.selectedColor();
        qDebug() << color;
        qDebug() << color.red();
        qDebug() << color.green();
        qDebug() << color.blue();
        qDebug() << color.hue();
        qDebug() << color.saturation();
        qDebug() << color.value();
    }
}

void Widget::InputDialogBtn_Clicked()
{
    QInputDialog dlg(this);
    dlg.setWindowTitle("Input Test");
    dlg.setLabelText("Please input an integer:");

    dlg.setInputMode(QInputDialog::TextInput);

    //dlg.setIntMinimum(0); //最小最大

    //dlg.setIntMaximum(255);

    if( dlg.exec() == QInputDialog::Accepted )
    {
        qDebug() << dlg.textValue();//intValue
    }
}

Widget::~Widget()
{
  

}

#include <QtGui/QApplication>
#include "Widget.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();

}

QInputDialog中的实用函数:

QInputDialog::getDouble   //输入浮点

QInputDialog::getInt

QInputDialog::getItem  //自己练习

QInputDialog::getText  //输入字符串

小结:

QColorDialog类用于提供指定颜色的对话框部件。

QColor类用来在程序中表示颜色的概念。

QInputDialog类用于需要临时进行数据输入的场合。

21、标准对话框(下)

qt中提供了预定义的字体对话框QFontDialog类。

QFontDialog类用于提供选择字体的对话框部件。

字体对话框的使用方式:

//构造字体对话框对象

QFontDialog dlg(this);

//设置字体对话框的相关属性

dlg.setWindowTitle("Font Editor");

dlg.setCurrentFont(QFont("Coutier New",10,QFont::Bold));//初始字体

if(dlg.exec()==QFontDialog::Accepted)

{  qDebug()<<dlg.selectedFont();  }

QFontDialog中的实用函数:

QFontDialog::getFont

2进度对话框

Qt中提供了预定义的进度对话框QProgressDialog类

QProgressDialog类用于显示进度信息

QProgressDialog类用于需要用户等待的场合。使用方式:

//构造进度对话框对象

QProgressDialog dlg(this);

//设置进度对话框的相关属性

dlg.setWindowTitle("Updating...");

dlg.setLabelText("Downloading from server..");

dlg.setMinimum(0);//设置最小进度值

dlg.setMaximum(1000);//设置最大进度值

dlg.exec();  //这里是差异,需要用户等待,用户不能操作

3打印对话框:

Qt中提供了预定义的打印对话框QPringtDialog类,QPrintDialog类用于设置打印相关的参数信息。

使用方式:

//构造打印对话框对象

QPrintDialog dlg(this);

//设置打印对话框的相关属性

dlg.setWindowTitle("print Dialog");

if(dlg.exec()==QprintDialog::Accepted)

{  Qprinter* p=dlg.printer();

//use printer object to print data  }

打印对话框会产生一个数据对象,数据对象的类型是QPrinter:

qt中的QPrinter类是打印设备及其参数的封装,QPrinter类封装了系统中打印设备的驱动接口,QPrinter以相同方式使用系统中的不同打印设备。

#ifndef _WIDGET_H_
#define _WIDGET_H_
#include <QtGui/QWidget>
#include <QPushButton>
class Widget : public QWidget
{
    Q_OBJECT
private:
    QPushButton FontDialogBtn;
    QPushButton ProgressDialogBtn;
    QPushButton PrintDialogBtn;
private slots:
    void FontDialogBtn_Clicked();
    void PrintDialogBtn_Clicked();
    void ProgressDialogBtn_Clicked();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif

#include "Widget.h"
#include <QDebug>
#include <QPrinter>
#include <QTextDocument>
#include <QPrintDialog>
#include <QProgressDialog>
#include <QFontDialog>
Widget::Widget(QWidget *parent) : QWidget(parent),
    FontDialogBtn(this), ProgressDialogBtn(this), PrintDialogBtn(this)
{
    FontDialogBtn.setText("Font Dialog");
    FontDialogBtn.move(20, 20);
    FontDialogBtn.resize(160, 30);
    ProgressDialogBtn.setText("Progress Dialog");
    ProgressDialogBtn.move(20, 70);
    ProgressDialogBtn.resize(160, 30);
    PrintDialogBtn.setText("Print Dialog");
    PrintDialogBtn.move(20, 120);
    PrintDialogBtn.resize(160, 30);
    resize(200, 170);
    setFixedSize(200, 170);
    connect(&FontDialogBtn, SIGNAL(clicked()), this, SLOT(FontDialogBtn_Clicked()));
    connect(&ProgressDialogBtn, SIGNAL(clicked()), this, SLOT(ProgressDialogBtn_Clicked()));
    connect(&PrintDialogBtn, SIGNAL(clicked()), this, SLOT(PrintDialogBtn_Clicked()));
}

void Widget::FontDialogBtn_Clicked()
{
    QFontDialog dlg(this);
    dlg.setWindowTitle("Font Dialog Test");
    dlg.setCurrentFont(QFont("Courier New", 10, QFont::Bold));
    if( dlg.exec() == QFontDialog::Accepted )
    {
        qDebug() << dlg.selectedFont();
    }
}

void Widget::ProgressDialogBtn_Clicked()
{
    QProgressDialog dlg(this);
    dlg.setWindowTitle("Updating...");
    dlg.setLabelText("Downloading update from server...");
    dlg.setMinimum(0);
    dlg.setMaximum(100);
    dlg.setValue(35);//进度
    // create a new thread //启动后台工作线程,从服务器下载更新,下载就调用上一个函数
    dlg.exec();
}

void Widget::PrintDialogBtn_Clicked()
{
    QPrintDialog dlg(this);
    dlg.setWindowTitle("Print Dialog Test");
    if( dlg.exec() == QPrintDialog::Accepted )
    {
        QPrinter* p = dlg.printer();//封装了打印机及打印参数
        QTextDocument td;//定义被打印对象
        //td.setPlainText("Printer object test!");
        td.setHtml("<h1>Print html object test</hl>");
        p->setOutputFileName("D:\\test.xps"); //打印到d盘
        td.print(p);
    }
}

Widget::~Widget()
{
    
}

#include <QtGui/QApplication>
#include "Widget.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();

}

小结:qt中标准对话框的设计模式:

GUI界面部件产生数据对象,

业务逻辑中的其他对象使用数据对象,

GUI界面与业务逻辑通过数据对象连接。

用户->操作标准对话框对象->产生数据对象  <-  其他qt对象使用(真实业务逻辑)

 

22、布局管理器计时器:

目前的GUI开发方式:绝对定位

直接在像素级指定各个组件的位置和大小。

void QWidget::move(int x,int y)

void QWidget::resize(int w,int h)

问题:组件的位置和大小无法自适应父窗口的变化

解决方案:布局管理器

提供相关的类对界面组件进行布局管理:

能够自动排列窗口中的界面组件,窗口变化后自动更新界面组件的大小。

QLayout是Qt中布局管理器的抽象基类,通过继承QLayout实现功能各异且互补的布局管理器,qt中可以根据需要自定义布局管理器,布局管理器不是界面部件,而是界面部件的定位策略。

QLayout <----QBoxLayout, QGridLayout , QformLayout, QStackedLayout

QBoxLayout布局管理器:以水平或者垂直的方式管理界面组件(一个格子格子的)。

子类:QVBoxLayout, QHBoxLayout

布局管理器可以相互嵌套,形成更加复杂的布局方式:

布局嵌套几乎可以完成所有常用的界面布局。

自定义布局类可以达到个性化界面布局的效果。不推荐

嵌套实例:

#ifndef _WIDGET_H_
#define _WIDGET_H_
#include <QtGui/QWidget>
#include <QPushButton>
class Widget : public QWidget
{
    Q_OBJECT
private:
    QPushButton TestBtn1;
    QPushButton TestBtn2;
    QPushButton TestBtn3;
    QPushButton TestBtn4;
    void initControl();
    void testVBoxLayout();
    void testHBoxLayout();
    void testVHBoxLayout();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif

#include "Widget.h"
#include <QVBoxLayout>
Widget::Widget(QWidget *parent) : QWidget(parent),
    TestBtn1(this), TestBtn2(this), TestBtn3(this), TestBtn4(this)
{
    //initControl();
    //testVBoxLayout();
    //testHBoxLayout();
    //testVHBoxLayout();
}

void Widget::testVHBoxLayout()
{
    QHBoxLayout* hLayout1 = new QHBoxLayout();
    QHBoxLayout* hLayout2 = new QHBoxLayout();
    QVBoxLayout* vLayout = new QVBoxLayout();
    TestBtn1.setText("Test Button 1");
    TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn1.setMinimumSize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn2.setMinimumSize(160, 30);
    hLayout1->setSpacing(10);
    hLayout1->addWidget(&TestBtn1);
    hLayout1->addWidget(&TestBtn2);
    TestBtn3.setText("Test Button 3");
    TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn3.setMinimumSize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn4.setMinimumSize(160, 30);
    hLayout2->setSpacing(10);
    hLayout2->addWidget(&TestBtn3);
    hLayout2->addWidget(&TestBtn4);
    vLayout->setSpacing(10);
    vLayout->addLayout(hLayout1);
    vLayout->addLayout(hLayout2);
    setLayout(vLayout);//窗口直接是垂直管理器
}

void Widget::testHBoxLayout()
{
    QHBoxLayout* layout = new QHBoxLayout();
    TestBtn1.setText("Test Button 1");
    TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn1.setMinimumSize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn2.setMinimumSize(160, 30);
    TestBtn3.setText("Test Button 3");
    TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn3.setMinimumSize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn4.setMinimumSize(160, 30);
    layout->setSpacing(30);
    layout->addWidget(&TestBtn1);
    layout->addWidget(&TestBtn2);
    layout->addWidget(&TestBtn3);
    layout->addWidget(&TestBtn4);
    setLayout(layout);
}

void Widget::testVBoxLayout()
{
    QVBoxLayout* layout = new QVBoxLayout();
    TestBtn1.setText("Test Button 1");
    TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);//能变宽变长
    TestBtn1.setMinimumSize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn2.setMinimumSize(160, 30);
    TestBtn3.setText("Test Button 3");
    TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn3.setMinimumSize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn4.setMinimumSize(160, 30);
    layout->setSpacing(30);//设置按钮距离
    layout->addWidget(&TestBtn1);
    layout->addWidget(&TestBtn2);
    layout->addWidget(&TestBtn3);
    layout->addWidget(&TestBtn4);
    setLayout(layout);
}

void Widget::initControl()
{
    TestBtn1.setText("Test Button 1");
    TestBtn1.move(20, 20);
    TestBtn1.resize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.move(20, 70);
    TestBtn2.resize(160, 30);
    TestBtn3.setText("Test Button 3");
    TestBtn3.move(20, 120);
    TestBtn3.resize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.move(20, 170);
    TestBtn4.resize(160, 30);
}
Widget::~Widget()
{

}

小结:绝对定位的布局方位无法自适应窗口的变化,qt提供了相关的类对界面组件进行布局管理,qt预定义了功能各异且互补的布局管理器,布局管理器能够相互嵌套形成复杂的布局。

23、布局管理器2

布局管理器中的比例系数:

默认情况下以等比例的方式更新组件的大小。

可以自定义组件大小更新时的比例系数。

QBoxLayout中的比例系数设置

void setStretch(int index,int stretch) //格子下标,比例系数

bool setStretchFactor(QWidget* widget, int stretch) //某个具体组件的比例系数

bool set Stretch Factor(QLayout* layout, int stretch) //嵌套的布局管理器的比例系数

组件的初始大小是独立于布局管理器设置的,因此不能保证组件的大小始终符合比例系数的设置。

 

一开始运行是手工设置的,在变化的过程中逐渐符合我们设置的比例。所以一开始的比例是初始设置的。

#ifndef _WIDGET_H_

#define _WIDGET_H_
#include <QtGui/QWidget>
#include <QPushButton>
class Widget : public QWidget
{
    Q_OBJECT
private:
    QPushButton TestBtn1;
    QPushButton TestBtn2;
    QPushButton TestBtn3;
    QPushButton TestBtn4;
    void initControl();
    void testVBoxLayout();
    void testHBoxLayout();
    void testVHBoxLayout();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif

#include "Widget.h"
#include <QVBoxLayout>
Widget::Widget(QWidget *parent) : QWidget(parent),
    TestBtn1(this), TestBtn2(this), TestBtn3(this), TestBtn4(this)
{
    //initControl();
    //testVBoxLayout();
    //testHBoxLayout();
    //testVHBoxLayout();
}
void Widget::testVHBoxLayout()
{
    QHBoxLayout* hLayout1 = new QHBoxLayout();
    QHBoxLayout* hLayout2 = new QHBoxLayout();
    QVBoxLayout* vLayout = new QVBoxLayout();
    TestBtn1.setText("Test Button 1");
    TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn1.setMinimumSize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn2.setMinimumSize(160, 30);
    hLayout1->setSpacing(10);
    hLayout1->addWidget(&TestBtn1);
    hLayout1->addWidget(&TestBtn2);
    TestBtn3.setText("Test Button 3");
    TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn3.setMinimumSize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn4.setMinimumSize(160, 30);
    hLayout2->setSpacing(10);
    hLayout2->addWidget(&TestBtn3);
    hLayout2->addWidget(&TestBtn4);
    vLayout->setSpacing(10);
    vLayout->addLayout(hLayout1);
    vLayout->addLayout(hLayout2);
    vLayout->setStretchFactor(hLayout1, 1);
    vLayout->setStretchFactor(hLayout2, 3);
    setLayout(vLayout);
}
void Widget::testHBoxLayout()
{
    QHBoxLayout* layout = new QHBoxLayout();
    TestBtn1.setText("Test Button 1");
    TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn1.setMinimumSize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn2.setMinimumSize(160, 30);
    TestBtn3.setText("Test Button 3");
    TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn3.setMinimumSize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn4.setMinimumSize(160, 30);
    layout->setSpacing(30);
    layout->addWidget(&TestBtn1);
    layout->addWidget(&TestBtn2);
    layout->addWidget(&TestBtn3);
    layout->addWidget(&TestBtn4);
    layout->setStretchFactor(&TestBtn1, 1);
    layout->setStretchFactor(&TestBtn2, 2);
    layout->setStretchFactor(&TestBtn3, 1);
    layout->setStretchFactor(&TestBtn4, 3);//比例系数
    setLayout(layout);
}
void Widget::testVBoxLayout()
{
    QVBoxLayout* layout = new QVBoxLayout();
    TestBtn1.setText("Test Button 1");
    TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn1.setMinimumSize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn2.setMinimumSize(160, 30);
    TestBtn3.setText("Test Button 3");
    TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn3.setMinimumSize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn4.setMinimumSize(160, 30);
    layout->setSpacing(30);
    layout->addWidget(&TestBtn1);
    layout->addWidget(&TestBtn2);
    layout->addWidget(&TestBtn3);
    layout->addWidget(&TestBtn4);
    layout->setStretch(0, 1);
    layout->setStretch(1, 1);
    layout->setStretch(2, 2);
    layout->setStretch(3, 2);
    setLayout(layout);
}
void Widget::initControl()
{
    TestBtn1.setText("Test Button 1");
    TestBtn1.move(20, 20);
    TestBtn1.resize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.move(20, 70);
    TestBtn2.resize(160, 30);
    TestBtn3.setText("Test Button 3");
    TestBtn3.move(20, 120);
    TestBtn3.resize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.move(20, 170);
    TestBtn4.resize(160, 30);
}
Widget::~Widget()
{

}

#include <QtGui/QApplication>
#include "Widget.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();

}

QGridLayout布局管理器

以网格(二维)的方式管理界面组件。

QGridLayout中的比例系数设置:

void setColumnStretch(int column,int stretch)

void setRowStretch(int row,int stretch)

#ifndef _WIDGET_H_
#define _WIDGET_H_
#include <QtGui/QWidget>
#include <QPushButton>
class Widget : public QWidget
{
    Q_OBJECT
private:
    QPushButton TestBtn1;
    QPushButton TestBtn2;
    QPushButton TestBtn3;
    QPushButton TestBtn4;
    void testGridLayout1();
    void testGridLayout2();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};

#endif

#include "Widget.h"
#include <QGridLayout>
Widget::Widget(QWidget *parent) : QWidget(parent),
    TestBtn1(this), TestBtn2(this), TestBtn3(this), TestBtn4(this)
{
    //testGridLayout1();
    //testGridLayout2();
}
void Widget::testGridLayout1()
{
    QGridLayout* layout = new QGridLayout();
    TestBtn1.setText("Test Button 1");
    TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn1.setMinimumSize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn2.setMinimumSize(160, 30);
    TestBtn3.setText("Test Button 3");
    TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn3.setMinimumSize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn4.setMinimumSize(160, 30);
    layout->setSpacing(10);
    layout->addWidget(&TestBtn1, 0, 0);//放在00位置
    layout->addWidget(&TestBtn2, 0, 1);
    layout->addWidget(&TestBtn3, 1, 0);
    layout->addWidget(&TestBtn4, 1, 1);
    layout->setRowStretch(0, 1);
    layout->setRowStretch(1, 3);
    layout->setColumnStretch(0, 1);
    layout->setColumnStretch(1, 3);
    setLayout(layout);
}
void Widget::testGridLayout2()
{
    QGridLayout* layout = new QGridLayout();
    TestBtn1.setText("Test Button 1");
    TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn1.setMinimumSize(160, 30);
    TestBtn2.setText("Test Button 2");
    TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn2.setMinimumSize(160, 30);
    TestBtn3.setText("Test Button 3");
    TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn3.setMinimumSize(160, 30);
    TestBtn4.setText("Test Button 4");
    TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    TestBtn4.setMinimumSize(160, 30);
    layout->setSpacing(10);
    layout->addWidget(&TestBtn1, 0, 0, 2, 1);//在00位置占用2行一列
    layout->addWidget(&TestBtn2, 0, 1, 2, 1);
    layout->addWidget(&TestBtn3, 2, 0, 1, 2);
    layout->addWidget(&TestBtn4, 3, 0, 1, 2);
    setLayout(layout);
}
Widget::~Widget()
{

}

#include <QtGui/QApplication>
#include "Widget.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();

}

布局管理器的嵌套:

QGridLayout支持嵌套其他布局管理器成为其管理对象。

小结: QGridLayout以网格的方式对组件 进行管理,QGridLayout中的组件可以根据需要跨越多个网络,QBoxLayout和QGridLayout支持比例系数的概念。比例系数决定了组件大小的相对变化。

24、布局管理器3

绝对定位组件的坐标和大小

嵌套QBoxLayout 线性布局管理器

创建3*2的QGridLayout 网格布局管理器

为了美观,提出表单管理器:

layout->Widget(nameedit,0,0);

QFormLayout布局管理器:

以表单(Form)的方式管理界面组件。

表单布局中的标签和组件是相互对应的关系。

标签:组件

用法:

void addRow(QWidget* label,QWidget*field)  //以行的方式管理

void addRow(QWidget* label,QLayout* field)

void addRow(const QString& labelText,QWidget* field)

void addRow(const QString& labelTest,QLayout* field)

表单布局支持嵌套,其他布局管理器可以作为子布局被其管理。

QFormLayout的样式函数:

void setRowWrapPolicy(RowWrapPolicy policy)//设置每一行排布,一行标示一行组件

void setLabelAlignment(Qt::Alignment alignment)//对齐

小结:

QFormLayout以表单的方式管理界面组件

QFormLayout的样式设置简洁明了

QFormLayout支持布局管理器的嵌套

QFormLayout是嵌入式产品中最常用的布局方式。

    QLineEdit* nameEdit = new QLineEdit();
    QLineEdit* mailEdit = new QLineEdit();
    QLineEdit* addrEdit = new QLineEdit();
    QFormLayout* layout = new QFormLayout();

    layout->addRow("Name:", nameEdit);
    layout->addRow("Email:", mailEdit);
    layout->addRow("Address:", addrEdit);
    layout->setRowWrapPolicy(QFormLayout::WrapLongRows);

//标识,组件如果在同一行放不下,组件会自动到下一行,其它的标识,组件还是在同一行

    //layout->setLabelAlignment(Qt::AlignRight);

//标签向右对齐

    layout->setSpacing(10);

    setLayout(layout);

 //将layout设置到窗口中,告诉主窗口现在由布局管理器管理上面组件

    setWindowTitle("FTP");

25、布局管理器4

栈式布局管理器(QStackedLayout)

所有组件再垂直于频幕的方向上被管理

每次只有一个组件会显示再频幕上,

只有最顶层的组件会被最终显示

特点:组件大小一致且充满父组件的显示区,不能直接嵌套其他布局管理器,能够自由切换需要显示的组件,每次能且仅能显示一个组件。

用法概要:

int addWidget(QWidget* widget)  //加入需要管理的组件,不能addlayout

QWidget* currentWidget()  //得到当前显示在屏幕的组件,得到最顶层的组件

void setCurrentIndex(int index)  //通过编号即下标来设置当前显示

int currentIndex()

间接布局管理器的嵌套。

计时器:

计时器是工程开发中非常重要的角色。

计时器用于每隔一定的时间触发一个消息。

计时器消息最终会被转化为函数调用。

宏观上:计时器再每个间隔会调用指定的函数。

计时器(QTimer)使用方法:

1编写计时器消息处理函数

2再程序中创建计时器对象

3连接计时器消息和消息处理函数

4设置计时器时间间隔并启动计时

应用:上一步下一步,左划右划

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QPushButton>
class Widget : public QWidget
{
    Q_OBJECT
private:
    QPushButton TestBtn1;
    QPushButton TestBtn2;
    QPushButton TestBtn3;
    QPushButton TestBtn4;
    void initControl();
private slots:
    void timerTimeout();
public:
    Widget(QWidget *parent = 0);
    ~Widget();
};
#endif

#include "Widget.h"
#include "Widget.h"
#include <QStackedLayout>
#include <QHBoxLayout> //水平布局管理器
#include <QtCore>
#include <QDebug>
#include <QtCore>
Widget::Widget(QWidget *parent) : QWidget(parent),
    TestBtn1(this), TestBtn2(this), TestBtn3(this), TestBtn4(this)
{
    initControl();
}
void Widget::initControl()
{
    QStackedLayout* sayout=new QStackedLayout();
    QHBoxLayout* hlayout=new QHBoxLayout();
    QWidget* widget=new QWidget();
    QTimer* timer=new QTimer(this); //创建Qttimer对象,计时器对象
    TestBtn1.setText("1st Button");
    TestBtn2.setText("2rd Button");
    TestBtn3.setText("3th Button");
    TestBtn4.setText("Test Button 4: D.T.Software");
    TestBtn2.setParent(widget); //父组件为widget对象
    TestBtn3.setParent(widget);
    hlayout->addWidget(&TestBtn2);//水平布局管理器管理两个
    hlayout->addWidget(&TestBtn3);
    widget->setLayout(hlayout); //将水平布局管理器设置到刚刚创建出来的widget对象上面去
    sayout->addWidget(&TestBtn1);
    //sayout->addWidget(&TestBtn2);
    //sayout->addWidget(&TestBtn3);
    sayout->addWidget(widget);  //完成嵌套
    sayout->addWidget(&TestBtn4);
    sayout->setCurrentIndex(1); //初始显示哪个组件
    setLayout(sayout);//将栈式管理布局器显示到当前窗口
    connect(timer,SIGNAL(timeout()),this,SLOT(timerTimeout()));//timer对象的timeout信号,链接计时器消息,和消息处理函数(槽)
    timer->start(2000); //每隔2秒启动一次
}
void Widget::timerTimeout()
{
    QStackedLayout* slayout=dynamic_cast<QStackedLayout*>(layout()); //直接按F1,帮助文档会调用出来,得到QLayout指针类型,所以要强制类型转换
//获取栈布局管理器对象,调用layout成员函数将当前组件拥有的布局管理器直接返回
    if(slayout != NULL)
    {
        int index=((slayout->currentIndex()+1) % slayout->count());
//currentIndex()当前显示的组件下标,下一个--+1,可能溢出--取余,循环得到下标,count函数获取当前这个对象所管理的组件数目
        slayout->setCurrentIndex(index); //重新设置要显示的组件下标
        qDebug()<<index;
    }
}
Widget::~Widget()
{

}
小结:

QStackedLayout以栈的方式管理界面组件。

QStackedLayout中的组件最多只有一个显示。

QStackedLayout可以自由切换需要显示的组件。

QTimer是Qt中的计时器组件。

QTimer能够在指定的之间间隔触发消息。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页