面向对象的Qt编程

0.面向对象的Qt编程

完全不适用任何面向对象技术,而只是利用Qt所提供的类创建对象,并调用对象的接口以满足用户的需求是可能的,但这样构建的应用程序其功能必然是十分有限的。
首先,Qt类保护成员中的诸多实现无法在类的外部被复用,Qt试图通过多态实现的很多机制,如事件处理,完全无法使用。
再次,Qt提供的信号和槽不可能满足用户所有的需求,自定义信号和槽需要面向对象技术。
最后,Qt设计师,Qt创造器等工具链都在以面向对象的方式使用Qt,反其道而行之不会有好结果。

1.通过面向对象的编程思想实现加法计算器

  • 输入两个数字,按"="按钮显示计算结果
  • 两个操作数必须都是合法的数字,拒绝结构任何非法字符
  • 两个操作数必须全部合法,“=”按钮才被激活,否则禁用(不可以点击)
  • 显示结果的空间只可查看不可修改,但支持复制到粘贴板
  • 所有子窗口的大小和位置随主窗口的缩放自动调整至最佳

dialog.h:

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 
#include 
#include  // 行编辑控件
#include  // 水平布局器
#include  // 验证器

#pragma execution_character_set("utf-8")


QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public slots:
    // 使能等号按钮的槽操作数
    void enableButton(void);
    // 计算结果和显示的槽函数
    void calcClicked(void);

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

private:
    Ui::Dialog *ui;
    QLineEdit* m_editX; // 左操作数
    QLineEdit* m_editY; // 右操作数
    QLineEdit* m_editZ; // 显示结果
    QLabel* m_label; // "+"
    QPushButton* m_button; // "="等号按钮
};
#endif // DIALOG_H

dialog.cpp:

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);

    // 界面初始化
    setWindowTitle("计算器");
    // 左操作数,this即为当前父窗口指针
    m_editX=new QLineEdit(this);
    // 设置文本对齐方式:右对齐
    m_editX->setAlignment(Qt::AlignRight);
    // 设置数字验证器,只能输入数字形式内容
    m_editX->setValidator(new QDoubleValidator(this));
    // 右操作数
    m_editY=new QLineEdit(this);
    m_editY->setAlignment(Qt::AlignRight);
    m_editY->setValidator(new QDoubleValidator(this));
    // 显示结果控件
    m_editZ=new QLineEdit(this);
    m_editZ->setAlignment(Qt::AlignRight);
    m_editZ->setReadOnly(true); // 设置只读
    // "+"
    m_label=new QLabel("+",this);
    // "="
    m_button=new QPushButton("=",this);
    m_button->setEnabled(false);//设置禁用

    // 创建布局器:自动调用每个控件的大小和位置
    QHBoxLayout* layout = new QHBoxLayout(this);
    // 按水平方向,依次将控件添加到布局器中
    layout->addWidget(m_editX);
    layout->addWidget(m_label);
    layout->addWidget(m_editY);
    layout->addWidget(m_button);
    layout->addWidget(m_editZ);
    // 设置布局器
    setLayout(layout);

    // 信号和槽函数连接
    // 左右操作数文本改变时,发送信号textChanged()
    connect(m_editX,SIGNAL(textChanged(QString)),
            this,SLOT(enableButton(void)));
    connect(m_editY,SIGNAL(textChanged(QString)),
            this,SLOT(enableButton(void)));
    // 点击按钮,发送信号clicked
    connect(m_button,SIGNAL(clicked(void)),
            this,SLOT(calcClicked(void)));
}

Dialog::~Dialog()
{
    delete ui;
}

// 使能等号按钮的槽操作数
void Dialog::enableButton(void)
{
    bool bXOk,bYOk;
    // text():获取输入文本(QString)
    // toDouble():QString转换为double,参数保存转换是否成功结果
    m_editX->text().toDouble(&bXOk);
    m_editY->text().toDouble(&bYOk);
    // 当左右操作数都输入了有效数据,则使能等号按钮,否则设置禁用
    m_button->setEnabled(bXOk && bYOk);
}

// 计算结果和显示的槽函数
void Dialog::calcClicked(void)
{
    double res = m_editX->text().toDouble() +
            m_editY->text().toDouble();
    // number():将double转换为QString
    QString str = QString::number(res);
    // 显示字符串形式结果
    m_editZ->setText(str);
}

2.案例:获取系统时间

要求:

  • 使用面向对象的Qt编程技术创建获取时间窗口
  • 点击按钮,通过自定义的槽函数获取时间并显示到标签
    dialog.h:
#ifndef DIALOG_H
#define DIALOG_H

#include 
#include 
#include 
#include  // 垂直布局器
#include  // 获取时间
#include  // 打印调试

#pragma execution_character_set("utf-8")

QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

public slots:
    void getTime(void); // 获取时间的槽函数

signals:
    // 自定义信号函数,只需声明,不能写定义
    void mySignal(const QString&);

private:
    Ui::Dialog *ui;
    QLabel* m_label; // 显示时间label
    QPushButton* m_button; // 获取时间button

};
#endif // DIALOG_H

dialog.cpp:

#include "dialog.h"
#include "ui_dialog.h"
#include 

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
    // 初始化界面
    // 显示时间标签控件
    m_label = new QLabel(this);
    // 设置label边框消息,凹陷面板
    m_label->setFrameStyle(QFrame::Panel|QFrame::Sunken);
    // 设置label文本对齐方式:水平/垂直居中
    m_label->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    // 设置label的字体大小
    QFont font;
    font.setPointSize(20);
    m_label->setFont(font);

    // 获取系统时间的按钮
    m_button = new QPushButton("获取当前时间",this);
    m_button->setFont(font);

    // 创建垂直布局器
    QVBoxLayout* layout=new QVBoxLayout(this);
    layout->addWidget(m_label);
    layout->addWidget(m_button);
    // 设置布局器
    setLayout(layout);

    // 信号和槽函数连接
    connect(m_button,SIGNAL(clicked()),
            this,SLOT(getTime(void)));

    // 通过自定义信号,触发label的setText函数执行
    connect(this,SIGNAL(mySignal(QString)),
            m_label,SLOT(setText(QString)));

}

Dialog::~Dialog()
{
    delete ui;
}

// 获取系统时间的槽函数
void Dialog::getTime(void)
{
    qDebug("getTime");
    qDebug()<<"getTime";
    // 获取当前系统时间
    QTime time = QTime::currentTime();
    // 将时间对象转换为字符串
    QString str = time.toString("hh:mm:ss");
    // 显示时间
    //m_label->setText(str);

    // emit:是Qt关键字,标记当前是发射信号
    emit mySignal(str); // 发射信号
}

你可能感兴趣的:(QT笔记)