4、文本文件写入:使用QFile和QTextStream,将QTextEdit中的内容保存到新的文本文件中。
好,咱们接着聊。上一节我们把文件读进来了,这节自然就是写出去。说白了,就是把用户在QTextEdit里敲的那些字,存成一个文本文件。
我个人习惯,写文件比读文件要更小心一点。为什么?因为读文件顶多读不出来,程序崩一下;写文件要是写错了,用户辛苦打的内容可就丢了。我在项目中就遇到过这种事,测试同学点保存,结果文件是空的,差点被骂死。所以,写文件的逻辑,咱们得稳一点。
4.1 核心思路:三步走
写文本文件,其实就三步:
- 创建QFile对象,指定文件路径
- 以只写模式打开(WriteOnly 或 Append)
- 用QTextStream写入内容
你想想看,这和读文件是不是对称的?读的时候用ReadOnly,写的时候用WriteOnly。Qt的设计就是这么工整。
4.2 代码实现:从QTextEdit保存内容
假设界面上有一个QTextEdit,名字叫textEdit。用户编辑完了,点个「保存」按钮,我们就执行下面的代码:
def save_file(self):
# 1. 获取文件保存路径
file_path, _ = QFileDialog.getSaveFileName(
self,
"保存文件",
"",
"文本文件 (*.txt);;所有文件 (*)"
)
if not file_path:
return # 用户取消了,啥也不干
# 2. 创建QFile对象
file = QFile(file_path)
# 3. 以只写模式打开
if not file.open(QFile.WriteOnly | QFile.Text):
QMessageBox.warning(self, "错误", f"无法打开文件:{file.errorString()}")
return
# 4. 创建QTextStream,写入内容
stream = QTextStream(file)
content = self.textEdit.toPlainText()
stream << content
# 5. 关闭文件
file.close()
QMessageBox.information(self, "成功", "文件保存成功!")
关键点:
QFile.WriteOnly表示只写模式,会覆盖原有内容QFile.Text标志告诉Qt按文本模式处理换行符(Windows下是\r\n,Linux下是\n)toPlainText()获取纯文本内容,如果你用的是QTextEdit的富文本模式,记得用toHtml()
4.3 避坑指南:我踩过的几个坑
嗯,这里要注意几个地方,都是我曾经掉进去过的:
- 文件路径为空:用户点了取消,
getSaveFileName返回空字符串。一定要判断,不然程序会崩。 - 打开失败:比如磁盘满了、权限不够。别假设一定能打开,检查返回值是基本素养。
- 编码问题:默认是系统编码(Windows下是GBK,Linux下是UTF-8)。如果你要跨平台,建议显式设置:
stream.setCodec("UTF-8")
警告:千万不要在打开文件失败后直接往下写。我曾经这么干过,结果文件没创建成功,程序也没报错,用户以为保存了,其实啥都没写。血的教训。
4.4 追加模式:不覆盖,只追加
有时候我们不想覆盖原有文件,只想在末尾追加内容。比如写日志文件。这时候用QFile.Append:
file.open(QFile.Append | QFile.Text)
stream << "新的一行内容\n"
说白了,就是把WriteOnly换成Append。其他都一样。
4.5 知识体系:文本文件写入的核心逻辑
下面这张图,是我画的一个流程图,帮你理清整个保存文件的逻辑:
小技巧:如果你要保存的是大文件(比如几十MB),建议用stream.flush()强制刷新缓冲区,或者分段写入。不然用户等半天,还以为程序卡死了。
4.6 完整示例:带错误处理的保存函数
最后,给你一个我项目里实际用的保存函数,带上了完整的错误处理:
def save_text_to_file(self, file_path=None):
"""保存QTextEdit内容到文件"""
# 如果没有指定路径,弹出对话框让用户选择
if not file_path:
file_path, _ = QFileDialog.getSaveFileName(
self, "保存文件", "", "文本文件 (*.txt)"
)
if not file_path:
return False
file = QFile(file_path)
# 尝试打开文件
if not file.open(QFile.WriteOnly | QFile.Text):
QMessageBox.critical(
self,
"保存失败",
f"无法打开文件:\n{file.errorString()}"
)
return False
# 写入内容
stream = QTextStream(file)
stream.setCodec("UTF-8") # 统一用UTF-8,避免乱码
stream << self.textEdit.toPlainText()
# 关闭文件
file.close()
return True
你看,这个函数返回了布尔值。调用方可以根据返回值判断是否保存成功,然后决定要不要更新界面上的「已修改」状态。嗯,这就是工程化的写法。
好了,文本文件写入就这些。说白了就是三步:选路径、打开文件、写内容。但每一步都有坑,我帮你都踩过了,你照着写就行。
可可精品资料库