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(); // 自动添加 QString str = QString::fromLocal8Bit(line); // 从字节数组转换为字符串 str.truncate(str.length() - 1); // 截断给定索引处的字符串, 去除结尾处的 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(); // 转换为文本, 末尾无 aStream << strLine << QChar::fromLatin1(' '); // 写入一行内容到文本流中, 即写入文件中. 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