第11課 Qt中的字符串類

1. 歷史遺留問題和解決方案正則表達式

(1)歷史遺留問題算法

  ①C語言不支持真正意義上的字符串編程

  ②C語言用字符數組和一組函數實現字符串操做數組

  ③C語言不支持自定義類型,所以沒法得到字符串類型數據結構

(2)解決方案app

  ①從C到C++的進化過程當中引入了自定義類型ide

  ②在C++中能夠經過類完成字符串類型的定義函數

2. 標準庫STLthis

(1)STL庫編碼

  ①STL是意義上須要與C++一同發佈的標準庫

  ②STL是一套以模板技術完成的C++類庫

  ③STL中包含了經常使用的算法和數據結構

  ④STL中包含了字符串類

(2)Qt VS STL

  ①STL的具體實現依賴於編譯器生產廠商

  ②STL的「標準」只是其接口是標準(即相同的全局函數、相同的算法類和數據結構、相同的類成員函數)

  ②不一樣廠商的編譯器所帶的STL,其實現存在差別(依賴於STL開發的C++程序在不一樣平臺上的行爲可能出現差別!!!)

(3)開發前的選擇

  ①項目是否須要使用現有庫的支持?(STL、Qt、MFC、私有庫?)

  ②項目是否須要在不一樣平臺間移植?(Linux、Windows、Andriod?)

  ③項目是否須要圖形用戶界面?(GUI、命令行、後臺服務程序?)

3. Qt中的字符串類

(1)特色

  ①採用Unicode編碼

  ②使用隱式共享技術(Copy On Write)來節省內存和沒必要要的數據拷貝

  ③跨平臺使用,沒必要考慮字符串的平臺兼容性

(2)QString VS string

  ①QString直接支持字符串和數字的相互轉換

  ②QString直接支持字符串的大小比較

  ③QString直接支持字符編碼間的相互轉換

  ④QString直接支持std::string和std::wstring的相互轉換

  ⑤QString直接支持正則表達式的應用

  ⑥……

【實例分析】QString基本操做示例

#include <QApplication>
#include <QDebug>
#include <QString>

void Sample_1()
{
    QString s = "and";
    
    s.append(" ");   //"and "
    s.append("Qt");  //"and Qt"
    s.prepend(" ");  //" and Qt"
    s.prepend("C++");//"C++ and Qt"
    
    qDebug() << s;
    
    s.replace("and", "&"); //"C++ & Qt"
    
    qDebug() << s;
}

void Sample_2()
{
    QString s = "";
    int index = 0;
    
    s.sprintf("%d. I'm %s, thank you!", 1, "SantaClaus"); //"1. I'm SantaClaus, thank you!"
    qDebug() << s;

    index = s.indexOf(",");
    //從索引0到index之間的字符子串
    s = s.mid(0, index);  //"1. I'm SantaClaus"
    qDebug() << s;
    
    index = s.indexOf(".");
    s = s.mid(index + 1,s.length()); //" I'm SantaClaus";
    s = s.trimmed();                 //"I'm SantaClaus";
    qDebug() << s;
    
    index = s.indexOf(" ");
    s = s.mid(index + 1, s.length()); //"SantaClaus"
    
    qDebug() << s;
}

void Sample_3(QString* a, int len)
{
    for(int i=0;i<len;i++)
    {
        for(int j=i+1; j<len; j++)
        {
            if( a[j] < a[i])
            {
                QString tmp = a[i];
                a[i] = a[j];
                a[j] = tmp;
            }
        }
    }
}

int main(int,char**)
{
    qDebug() << "Sample_1:";   
    Sample_1();  
    qDebug() << endl;
    
    qDebug() << "Sample_2:";  
    Sample_2(); 
    qDebug() << endl;
    
    qDebug() << "Sample_3:";  
    QString company[5] =
    {
        QString("Oracle"),
        QString("Borland"),
        QString("Microsoft"),
        QString("IBM"),
        QString("Horizon Studio")      
    };
    
    Sample_3(company, 5);
    
    for(int i=0; i<5; i++)
    {
        qDebug() << company[i];
    }  

    return 0;
}

(3)Qt中的QString

  ①QString在Qt庫中幾乎是無所不在

  ②全部的Qt圖形用戶組件都依賴於QString

【編程實驗】爲計算器實例添加消息響應

//QCalculatorUI.h

#ifndef _QCALCULATORUI_H_
#define _QCALCULATORUI_H_

#include <QWidget>
#include <QLineEdit>
#include <QPushButton>

class QCalculatorUI : public QWidget
{
    //要自定義信號和槽,必須在最開始的這裏添加Q_OBJECT
    Q_OBJECT
private:
    QLineEdit* m_edit;
    QPushButton* m_buttons[20];

    //二階構造法:當new一個QLineEdit和一些按鈕時可能會失敗,因此採用二階構造
    QCalculatorUI(); //第1階——先隱藏構造函數
    bool construct();//第2階

private slots: //聲明槽時得加slots
    void onButtonClicked();

public:
    static QCalculatorUI* NewInstance();
    void show();
    ~QCalculatorUI();
};

#endif  //_QCALCULATORUI_H_
View Code

//QCalculatorUI.cpp

#include "QCalculatorUI.h"
#include <QDebug>

QCalculatorUI::QCalculatorUI(): QWidget(NULL, Qt::WindowCloseButtonHint)
{

}

bool QCalculatorUI::construct()
{
    bool ret = true;

    const char* btnText[20] =
    {
        "7", "8", "9", "+", "(",
        "4", "5", "6", "-", ")",
        "1", "2", "3", "*", "",
        "0", ".", "=", "/", "C",
    };

    m_edit = new QLineEdit(this);//le的生命期由父組件來管理
    if( m_edit != NULL)
    {
        m_edit->move(10, 10);
        m_edit->resize(240, 30);
        m_edit->setReadOnly(true); //設置編輯框的只讀屬性
    }
    else
    {
        ret = false;
        return ret;
    }

    for(int i = 0; (i < 4) && ret; i++)
    {
        for(int j = 0; (j< 5) && ret; j++)
        {

            m_buttons[i * 5 + j] = new QPushButton(this);//按鈕的生命期由父組件來管理
            if (m_buttons[i * 5 + j] != NULL)
            {
                m_buttons[i * 5 + j]->resize(40, 40);
                m_buttons[i * 5 + j]->move(10 + j * 50, 50 + i * 50);
                m_buttons[i * 5 + j]->setText(btnText[i * 5 + j]);

                //消息映射
                //1.消息名(信號)要加SIGNAL關鍵字,消息處理函數(槽):用SLOT關鍵字
                //2.信號和槽的函數簽名必須一致,即都是無參的函數,返回值void
                connect(m_buttons[i*5+j], SIGNAL(clicked()), this, SLOT(onButtonClicked()));
            }
            else
            {
                ret = false;
            }
        }
    }

    return ret;
}

QCalculatorUI* QCalculatorUI::NewInstance()
{
    QCalculatorUI* ret = new QCalculatorUI();

    if((ret == NULL) || !ret->construct())
    {
        delete ret;//刪除半成品
        ret = NULL;
    }

    return ret;
}

void  QCalculatorUI::show()
{
    QWidget::show();
    setFixedSize(width(), height());
}

void QCalculatorUI::onButtonClicked()
{
    //sender是QObject類的,用於表示消息的發送者
    QPushButton* btn = (QPushButton*)sender();
    QString clickText = btn->text();

    if(clickText == "")
    {
        QString text = m_edit->text();
        if(text.length() > 0)
        {
            text.remove(text.length()-1, 1);
            m_edit->setText(text);
        }
    }else if( clickText == "C")
    {
        m_edit->setText("");

    }else if( clickText == "=")
    {

    }
    else
    {
        m_edit->setText(m_edit->text() + clickText);
    }
}

 QCalculatorUI::~QCalculatorUI()
 {

 }

//main.cpp

#include <QApplication>
#include "QCalculatorUI.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QCalculatorUI* cal = QCalculatorUI::NewInstance();
    int ret = -1;

    if(cal != NULL)
    {
        cal->show();
        ret = a.exec();

        delete cal;
    }

    return ret;
}
View Code

4. 小結

(1)應用開發中大多數的狀況都在進行字符串處理

(2)Qt比STL更適合於跨平臺開發的場景

(3)Qt中的QString比STL中的string更強大易用

(4)Qt圖形用戶組件都依賴於QString

(5)項目開發時須要綜合各類因素,選擇須要使用的庫

相關文章
相關標籤/搜索