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