为跨平台文本编辑器应用程序更改 QTextStream 的 QT End of Line Style

Posted

技术标签:

【中文标题】为跨平台文本编辑器应用程序更改 QTextStream 的 QT End of Line Style【英文标题】:Change QT End of Line Style of QTextStream for cross platform Text Editor application 【发布时间】:2018-04-11 01:19:52 【问题描述】:

所以我正在构建一个跨平台的 QT 文本编辑器。我正在 Linux 上开发,目标是 Windows。我让用户尽可能轻松地使用他们希望的任何编码保存文本文件。

我通过他们网站上的教程使用M Cross Environment "MXE" 编译了该项目。

在 Linux 上,到目前为止,一切都如我所愿。

但是,在 Windows 上,如果我使用文本编辑器创建一个文件(无论我选择什么编码),然后在记事本中打开它,整个文件都在一行中。

我相当肯定我找到了问题所在。如果我打开我的 QT 文本编辑器创建的文件,Emacs 会说它具有“Unix”“行尾样式”。

我假设 Windows 不能识别换行符,因为它们是 Unix 风格的。但是,我不确定如何更改QTextStream 中的“行尾样式”。该文档似乎没有任何帮助,我无法在堆栈溢出或其他有相同问题的情况下找到其他任何人。

以下是我保存文件的代码。 encodeString 变量控制保存文件的编码方式。

void mainwindow::on_actionSave_triggered()

    if (!saveFile.isEmpty())
    
      //"saveFile" is populated with the file name when the file is first opened.
        QFile file(saveFile); 
        if (!file.open(QIODevice::WriteOnly))
        
            qDebug() << "Could not find file."

        
        else
        
      //The following if statements will save the file in the proper encoding dependant on the value of "encodeString."
            QTextStream stream(&file)
            if (encodeString == "Plain Text")
            
                stream << ui->textEdit->toPlainText();
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-8")
            
                stream.setCodec("UTF-8");
                stream.setGenerateByteOrderMark(true);
                stream << ui->textEdit->toPlainText();
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-16")
            
                stream.setCodec("UTF-16");
                stream.setGenerateByteOrderMark(true);
                stream << ui->textEdit->toPlainText();
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-16BE")
            
                stream.setCodec("UTF-16BE");
                stream.setGenerateByteOrderMark(true);
                stream << ui->textEdit->toPlainText();
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-32")
            
                stream.setCodec("UTF-32");
                stream.setGenerateByteOrderMark(true);
                stream << ui->textEdit->toPlainText();
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-32BE")
            
                stream.setCodec("UTF-32BE");
                stream.setGenerateByteOrderMark(true);
                stream << ui->textEdit->toPlainText();
                stream.flush();
                file.close();
            


        
    



以下是打开文件的代码。它只是流式传输到ui-&gt;textEdit 作为第二个问题,我希望能够将正在打开的文件的编码记录为encodeString 的值。

void MainWindow::on_actionOpen_triggered()

  QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QString(), tr("All Files (*.*);;Text Files (*.txt);;C++ Files (*.cpp *.h)"));  //Opens the QDialog for opening files.
  saveFile =fileName;       //Sets the value of "saveFile" to the value of "fileName." This insures that any time a "Save" function is performed, the file that the text is saved to, is the one that is intended.
    MainWindow::setWindowTitle(saveFile);
    if(!fileName.isEmpty()) // As long as the file name variable is not empty, this will trigger.
    
        QFile file(fileName);
        if(!file.open(QIODevice::ReadOnly)) // If the file could not be opened, it will trigger this error message.
        
            QMessageBox::critical(this, tr("Error"), tr("Could not open file"));
                        return;
        
        QTextStream in(&file);      //This sets the variable "in" to be the contents of the file.
    ui->textEdit->setText(in.readAll());    //This sets the text that is in the text edit field to be the contents of the file.
    file.close();       //This closes the file so that no memory errors are caused by having too many files open.
    

【问题讨论】:

如果以文本模式打开文件,即file.open(QIODevice::WriteOnly | QIODevice::Text),如何? 好点,我将编辑问题以包括文件打开过程。 我实际上能够在这里找到一个也有我的问题的人。 ***.com/questions/38777334/… 我将根据这个答案研究一个解决方案。但与此同时,我认为有一个明显的临时解决方案。也就是在我的Windows机器上安装QT,用Windows构建项目。 【参考方案1】:

老实说,我讨厌在这里回答我自己的问题,但实际上我能够在 QT 论坛上找到遇到同样问题的其他人。就是这里https://forum.qt.io/topic/42464/qplaintextedit-eats-line-endings。使用这篇文章中的信息和一些调整,我不仅能够使用正确的 Windows“行尾”保存文件,而且还能够使用正确的编码保存文件。 QTextEdit 中的文本保存到 Qstring。然后使用Qstring.replace 函数将以\n 结尾的行更改为\r\n。然后设置QTextStream 编码(如果是纯文本则不设置),Qstring 流式传输到QTextStream。然后将QTextStream 发送到文件。 Qstring 的保存和操作在编码 if 语句之前完成,以减少所需的代码量。

这是完整的保存功能。

void MainWindow::on_actionSave_triggered()  // Saves the file

    if (!saveFile.isEmpty())
    
        QString wSave;
        QFile file(saveFile);
        wSave = ui->textEdit->toPlainText();
        wSave.replace("\n", "\r\n");
        wSave.replace("\r\r\n", "\r\n");
        if (!file.open(QIODevice::WriteOnly))   // This if statement makes sure that the file can be written to.
        
            // error message

        
        else
        
      QTextStream stream(&file);        // Prepares the file to receive the QTextStream
      if (encodeString == "Plain Text")     //The next set of "if" statements set the encoding that the file will be saved in. This is set by the combo box in the text editor.
            

                qDebug() << wSave;
                stream << wSave;
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-8")
            

                stream.setCodec("UTF-8");
                stream.setGenerateByteOrderMark(true);
                stream << wSave;
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-16")
            
                stream.setCodec("UTF-16");
                stream.setGenerateByteOrderMark(true);
                stream << wSave;
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-16BE")
            
                stream.setCodec("UTF-16BE");
                stream.setGenerateByteOrderMark(true);
                stream << wSave;
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-32")
            
                stream.setCodec("UTF-32");
                stream.setGenerateByteOrderMark(true);
                stream << wSave;
                stream.flush();
                file.close();
            

            if (encodeString == "UTF-32BE")
            
                stream.setCodec("UTF-32BE");
                stream.setGenerateByteOrderMark(true);
                stream << wSave;
                stream.flush();
                file.close();
            


        
    



【讨论】:

以上是关于为跨平台文本编辑器应用程序更改 QTextStream 的 QT End of Line Style的主要内容,如果未能解决你的问题,请参考以下文章

如何通过动态应用主题来更改textview,按钮,编辑文本的角落形状?

Visual Studio MFC 在键入/动态时更改编辑控件中的文本

如果在编辑中更改文本更改 UITextField 崩溃

Android 自定义编辑文本值被另一个自定义编辑文本更改

sap gui中Smartforms的文本编辑器如何改成是word的。我现在是sap默认的。网上找I8n这种方法不能更改。

微信小程序富文本编辑器怎么解析标签