QTextCodec::codecForLocale


QTextCodec::codecForLocale

 

#include "qwmainwindow.h"

#include <QApplication>
#include <QTextCodec>
#include <QDebug>

int main(int argc, char *argv[])
{
    /*
     * QTextCodec::codecForLocale()->name() 默認名為 "System"
     * 在 Windows 系統上將基於本地區域使用對應的編碼
     * 中文 Windows 系統一般是 GBK 編碼, 中文 Linux 系統一般是 UTF-8 編碼
     * 為了更好的跨平台,建議在代碼中指明 codecForLocale 的編碼
     * QTextCodec::codecForLocale 的作用有兩個
     * 1. 指明與外部文件讀寫的時候使用的默認編碼
     * 2. 向命令行輸出信息(qDebug)使用的編碼
     *
     * const char * 隱式轉換為 QString 的過程中, 使用 QTextCodec::codecForCStrings 指定的編碼
     * 使用 QObject::tr 將 const char * 隱式轉換為 QString 的過程中, 使用 QTextCodec::codecForTr 指定的編碼
     * Qt4.x 默認源文件的編碼是 Latin-1
     * Qt5.x 默認源文件的編碼是 UTF-8
     * Qt5.x 已經刪除了 QTextCodec::codecForCStrings 和 QTextCodec::codecForTr 函數
     *
     * // 讀取一個UTF-8字符串
     * QString utf8_s = QString::fromUtf8("這是一個UTF-8的字符串");
     * // 將QString轉換為GBK格式的QByteArray字符數組
     * // QByteArray::data() 可以返回 const char *
     * QByteArray gbk_s = QTextCodec::codecForName("gbk")->fromUnicode(utf8_s);
     * // 然后再從GBK字符數組轉換回QString
     * QString utf8_s2 = QTextCodec::codecForName("gbk")->toUnicode(gbk_s);
     *
     */
    QTextCodec * codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForLocale(codec);
    qDebug() << QString::fromUtf8("設置本地系統編碼為: %1").arg(QString::fromLatin1(QTextCodec::codecForLocale()->name()));
    qDebug() << QString::fromUtf8("提示: 在本地系統編碼為 UTF-8 時, QString::fromLocal8Bit 等價於 QString::fromUtf8");

    QApplication a(argc, argv);
    QWMainWindow w;
    w.show();
    return a.exec();
}

 

#ifndef QWMAINWINDOW_H
#define QWMAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class QWMainWindow; }
QT_END_NAMESPACE

class QWMainWindow : public QMainWindow
{
    Q_OBJECT

private:
    bool openTextByIODevice(const QString & fileName);
    bool saveTextByIODevice(const QString & fileName);

    bool openTextByStream(const QString & fileName);
    bool saveTextByStream(const QString & fileName);

public:
    explicit QWMainWindow(QWidget *parent = nullptr);

    virtual ~QWMainWindow();

    QWMainWindow * operator &();
    QWMainWindow const * operator &() const;

private:
    explicit QWMainWindow(const QWMainWindow &) = delete;
    explicit QWMainWindow(QWMainWindow &&) = delete;

    QWMainWindow & operator =(const QWMainWindow &) = delete;
    QWMainWindow & operator =(QWMainWindow &&) = delete;

private slots:
    void on_actOpen_IODevice_triggered();

    void on_actOpen_TextStream_triggered();

    void on_actSave_IODevice_triggered();

    void on_actSave_TextStream_triggered();

private:
    Ui::QWMainWindow * ui;
};

#endif // QWMAINWINDOW_H

 

#include "qwmainwindow.h"
#include "ui_qwmainwindow.h"

#include <QDir>
#include <QFileDialog>
#include <QTextStream>
#include <QTextDocument>
#include <QTextBlock>
#include <QDebug>

bool QWMainWindow::openTextByIODevice(const QString &fileName)
{ // 用 IODevice 方式打開文本文件
    QFile aFile(fileName);
    if ( ! aFile.exists() ) { // 文件不存在
        return false;
    }

    if ( ! aFile.open(QIODevice::ReadOnly | QIODevice::Text) ) { // 文件打開失敗
        return false;
    }

    ui->textEditDevice->clear();
    aFile.seek(0);
    // 無法正常打開多字節(ANSI)的中文編碼(GBK)文件
    // 無法正常打開UTF-16編碼的文件
    // 只能正常打開UTF-8編碼的文件
    ui->textEditDevice->setPlainText(QString::fromLocal8Bit(aFile.readAll()));
    /*
    ui->textEditDevice->clear();
    aFile.seek(0);
    while ( ! aFile.atEnd() ) {
        QByteArray line = aFile.readLine(); // 自動添加 \n
        QString str = QString::fromLocal8Bit(line); // 從字節數組轉換為字符串
        str.truncate(str.length() - 1); // 截斷給定索引處的字符串, 去除結尾處的 \n
        ui->textEditDevice->appendPlainText(str);
    }
    */
    aFile.close();

    ui->tabWidget->setCurrentIndex(0);
    return true;
}

bool QWMainWindow::saveTextByIODevice(const QString &fileName)
{ // 用IODevice方式保存文本文件
    QFile aFile(fileName);
    if ( ! aFile.open(QIODevice::WriteOnly | QIODevice::Text) ) { // 文件打開失敗
        return false;
    }

    QString str = ui->textEditDevice->toPlainText(); // 整個文本內容作為字符串

    QByteArray strBytes = str.toLocal8Bit(); // 轉換為字節數組

    // 保存的文本格式為 UTF-8 without bom 格式
    aFile.write(strBytes);

    aFile.close();

    ui->tabWidget->setCurrentIndex(0);
    return true;
}

bool QWMainWindow::openTextByStream(const QString &fileName)
{ // 用 QTextStream 打開文本文件
    QFile aFile(fileName);
    if ( ! aFile.exists() ) { // 文件不存在
        return false;
    }

    if ( ! aFile.open(QIODevice::ReadOnly | QIODevice::Text) ) { // 文件打開失敗
        return false;
    }

    QTextStream aStream(&aFile); // 用文本流讀寫文件內容
    // 自動檢測文件的編碼是否存在 UTF-8, UTF-16, or UTF-32 Byte Order Mark (BOM) 並根據檢測到的信息選擇對應的編碼
    aStream.setAutoDetectUnicode(true); // 無法正常讀寫多字節(ANSI)的中文編碼(GBK)文件

    ui->textEditStream->clear();
    aFile.seek(0);
    ui->textEditStream->setPlainText(aStream.readAll());
    /*
    ui->textEditStream->clear();
    aFile.seek(0);
    while ( ! aStream.atEnd() ) {
        QString str = aStream.readLine();
        ui->textEditStream->appendPlainText(str);
    }
    */
    aFile.close();

    ui->tabWidget->setCurrentIndex(1);
    return true;
}

bool QWMainWindow::saveTextByStream(const QString &fileName)
{ // 用 QTextStream 保存文本文件
    QFile aFile(fileName);
    if ( ! aFile.open(QIODevice::WriteOnly | QIODevice::Text) ) { // 打開文件失敗
        return false;
    }

    QTextStream aStream(&aFile); // 用文本流讀寫文件
    // 自動檢測文件的編碼是否存在 UTF-8, UTF-16, or UTF-32 Byte Order Mark (BOM) 並根據檢測到的信息選擇對應的編碼
    aStream.setAutoDetectUnicode(true); // 無法正常讀寫多字節(ANSI)的中文編碼(GBK)文件

    QString str = ui->textEditStream->toPlainText();

    // 保存的文本格式為 UTF-8 without bom 格式
    aStream << str; // 寫入文本流
    /*
    QTextDocument * doc; // 文本對象, 包含字符格式信息, 不是純文本信息
    QTextBlock textLine; // 文本中的一段
    doc = ui->textEditStream->document(); // QPlainTextEdit 的內容保存在 QTextDocument 中
    int cnt = doc->blockCount(); // QTextBlock 分塊保存內容, 文本內容的硬回車符就是一個 Block 截至標記

    // 保存的文本格式為 UTF-8 without bom 格式
    QString strLine;
    for (int i = 0; i < cnt; ++i) { // 逐個處理所有塊內容
        textLine = doc->findBlockByNumber(i); // 用 Block 編碼獲取塊內容, 即獲取一行內容
        strLine = textLine.text(); // 轉換為文本, 末尾無 \n
        aStream << strLine << QChar::fromLatin1('\n'); // 寫入一行內容到文本流中, 即寫入文件中.
        aStream.flush(); // 因為文本流帶緩沖, 執行 flush 函數, 會將緩沖區的內容立即寫入文件中。
    }
    */
    aFile.close();

    ui->tabWidget->setCurrentIndex(1);
    return true;
}

QWMainWindow::QWMainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::QWMainWindow)
{
    ui->setupUi(this);
}

QWMainWindow::~QWMainWindow()
{
    if (ui)
    {
        delete ui;
        ui = nullptr;
    }
}

QWMainWindow *QWMainWindow::operator &()
{
    return this;
}

const QWMainWindow *QWMainWindow::operator &() const
{
    return this;
}

void QWMainWindow::on_actOpen_IODevice_triggered()
{
    QString curPath = QDir::currentPath(); // 獲取系統當前目錄
    QString dlgTitle = QString::fromUtf8("打開一個文件");
    QString filter = QString::fromUtf8("文本文件(*.txt);;程序文件(*.h *.cpp);;所有文件(*.*)");
    QString aFileName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, filter);

    if ( aFileName.isEmpty() ) {
        return;
    }

    openTextByIODevice(aFileName);
}

void QWMainWindow::on_actOpen_TextStream_triggered()
{
    QString curPath = QDir::currentPath(); // 獲取系統當前目錄
    QString dlgTitle = QString::fromUtf8("打開一個文件");
    QString filter = QString::fromUtf8("文本文件(*.txt);;程序文件(*.h *.cpp);;所有文件(*.*)");
    QString aFileName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, filter);

    if ( aFileName.isEmpty() ) {
        return;
    }

    openTextByStream(aFileName);
}

void QWMainWindow::on_actSave_IODevice_triggered()
{
    QString curPath = QDir::currentPath(); // 獲取系統當前目錄
    QString dlgTitle = QString::fromUtf8("另存為一個文件");
    QString filter = QString::fromUtf8("文本文件(*.txt);;程序文件(*.h *.cpp);;所有文件(*.*)");
    QString aFileName = QFileDialog::getSaveFileName(this, dlgTitle, curPath, filter);

    if ( aFileName.isEmpty() ) {
        return;
    }

    saveTextByIODevice(aFileName);
}

void QWMainWindow::on_actSave_TextStream_triggered()
{
    QString curPath = QDir::currentPath(); // 獲取系統當前目錄
    QString dlgTitle = QString::fromUtf8("另存為一個文件");
    QString filter = QString::fromUtf8("文本文件(*.txt);;程序文件(*.h *.cpp);;所有文件(*.*)");
    QString aFileName = QFileDialog::getSaveFileName(this, dlgTitle, curPath, filter);

    if ( aFileName.isEmpty() ) {
        return;
    }

    saveTextByStream(aFileName);
}

 

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>QWMainWindow</class>
 <widget class="QMainWindow" name="QWMainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>560</width>
    <height>360</height>
   </rect>
  </property>
  <property name="font">
   <font>
    <pointsize>10</pointsize>
   </font>
  </property>
  <property name="windowTitle">
   <string>文本文件讀寫</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout_3">
    <item>
     <widget class="QTabWidget" name="tabWidget">
      <property name="currentIndex">
       <number>0</number>
      </property>
      <widget class="QWidget" name="tab1">
       <attribute name="title">
        <string>QFile  直接操作</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout">
        <item>
         <widget class="QPlainTextEdit" name="textEditDevice"/>
        </item>
       </layout>
      </widget>
      <widget class="QWidget" name="tab2">
       <attribute name="title">
        <string> QTextStream  操作</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_2">
        <item>
         <widget class="QPlainTextEdit" name="textEditStream">
          <property name="palette">
           <palette>
            <active>
             <colorrole role="WindowText">
              <brush brushstyle="SolidPattern">
               <color alpha="255">
                <red>0</red>
                <green>0</green>
                <blue>0</blue>
               </color>
              </brush>
             </colorrole>
             <colorrole role="Text">
              <brush brushstyle="SolidPattern">
               <color alpha="255">
                <red>0</red>
                <green>0</green>
                <blue>255</blue>
               </color>
              </brush>
             </colorrole>
             <colorrole role="PlaceholderText">
              <brush brushstyle="SolidPattern">
               <color alpha="128">
                <red>0</red>
                <green>0</green>
                <blue>255</blue>
               </color>
              </brush>
             </colorrole>
            </active>
            <inactive>
             <colorrole role="WindowText">
              <brush brushstyle="SolidPattern">
               <color alpha="255">
                <red>0</red>
                <green>0</green>
                <blue>0</blue>
               </color>
              </brush>
             </colorrole>
             <colorrole role="Text">
              <brush brushstyle="SolidPattern">
               <color alpha="255">
                <red>0</red>
                <green>0</green>
                <blue>255</blue>
               </color>
              </brush>
             </colorrole>
             <colorrole role="PlaceholderText">
              <brush brushstyle="SolidPattern">
               <color alpha="128">
                <red>0</red>
                <green>0</green>
                <blue>255</blue>
               </color>
              </brush>
             </colorrole>
            </inactive>
            <disabled>
             <colorrole role="WindowText">
              <brush brushstyle="SolidPattern">
               <color alpha="96">
                <red>120</red>
                <green>120</green>
                <blue>120</blue>
               </color>
              </brush>
             </colorrole>
             <colorrole role="Text">
              <brush brushstyle="SolidPattern">
               <color alpha="255">
                <red>120</red>
                <green>120</green>
                <blue>120</blue>
               </color>
              </brush>
             </colorrole>
             <colorrole role="PlaceholderText">
              <brush brushstyle="SolidPattern">
               <color alpha="128">
                <red>0</red>
                <green>0</green>
                <blue>255</blue>
               </color>
              </brush>
             </colorrole>
            </disabled>
           </palette>
          </property>
          <property name="font">
           <font>
            <pointsize>12</pointsize>
           </font>
          </property>
         </widget>
        </item>
       </layout>
      </widget>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>560</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <widget class="QToolBar" name="mainToolBar">
   <property name="windowTitle">
    <string>mainToolBar</string>
   </property>
   <property name="toolButtonStyle">
    <enum>Qt::ToolButtonTextUnderIcon</enum>
   </property>
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
   <addaction name="actOpen_IODevice"/>
   <addaction name="actSave_IODevice"/>
   <addaction name="separator"/>
   <addaction name="actOpen_TextStream"/>
   <addaction name="actSave_TextStream"/>
   <addaction name="separator"/>
   <addaction name="actQuit"/>
  </widget>
  <action name="actOpen_IODevice">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/images/804.bmp</normaloff>:/images/images/804.bmp</iconset>
   </property>
   <property name="text">
    <string>QFile 直接打開</string>
   </property>
   <property name="toolTip">
    <string>用 QFile 直接打開文本文件</string>
   </property>
  </action>
  <action name="actOpen_TextStream">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/images/122.bmp</normaloff>:/images/images/122.bmp</iconset>
   </property>
   <property name="text">
    <string>QTextStream 打開</string>
   </property>
   <property name="toolTip">
    <string>用 QTextStream 打開文本文件</string>
   </property>
  </action>
  <action name="actQuit">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/images/132.bmp</normaloff>:/images/images/132.bmp</iconset>
   </property>
   <property name="text">
    <string>退出</string>
   </property>
   <property name="toolTip">
    <string>退出</string>
   </property>
  </action>
  <action name="actSave_IODevice">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/images/104.bmp</normaloff>:/images/images/104.bmp</iconset>
   </property>
   <property name="text">
    <string>QFile 另存</string>
   </property>
   <property name="toolTip">
    <string>用 QFile 直接另存文件</string>
   </property>
  </action>
  <action name="actSave_TextStream">
   <property name="icon">
    <iconset resource="res.qrc">
     <normaloff>:/images/images/066.GIF</normaloff>:/images/images/066.GIF</iconset>
   </property>
   <property name="text">
    <string>QTextStream 另存</string>
   </property>
   <property name="toolTip">
    <string>用 QTextStream 另存文件</string>
   </property>
  </action>
 </widget>
 <resources>
  <include location="res.qrc"/>
 </resources>
 <connections>
  <connection>
   <sender>actQuit</sender>
   <signal>triggered()</signal>
   <receiver>QWMainWindow</receiver>
   <slot>close()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>-1</x>
     <y>-1</y>
    </hint>
    <hint type="destinationlabel">
     <x>399</x>
     <y>299</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

 

 

 

============= End

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM