Làm 1 cái Text Editor ở trên mạng thì khi thử save lại ra lỗi

Hello mọi người!

Hiện tại mình đang làm 1 cái text editor nhỏ gọn có tên là Krystal và mình làm trên mạng. Link tutorial ở đây nếu như bạn cần.

Krystal về cơ bản đã khá hoàn thiện rồi. Nhưng chỉ có 1 vấn đề duy nhất, đó là ở tính năng SaveSave As của nó. Khi mình thử save 1 file có tên là test.txt thông qua Krystal thì nó báo lỗi như sau:

expected str, bytes or os.PathLike object, not NoneType

Screenshot:

Mình gặp cái lỗi này không chỉ 1, mà là bất kì lần nào mình follow theo tutorial của trang web trên. Mà khi thử chạy code của nó (trang web có tính năng tải project bằng file zip) thì lại không sao cả. Mình không biết phải fix lỗi như thế nào. Nhờ ai đó giúp mình với.

Note: Project này sử dụng PyQt5 để tạo GUI. Nếu muốn run project thì nên tải lib PyQt5 thông qua pip để chạy project.

Toàn bộ code:

# Import thư viện PyQt5 và thư viện sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

import sys

# class MainWindow, window chính của program
class MainWindow(QMainWindow):

    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)

        # Resize cửa sổ
        self.resize(700, 500)

        # Thêm phần editor để edit file vào trong window
        self.editor = QPlainTextEdit()
        self.setCentralWidget(self.editor)

        # path của file
        self.path = None

        # Thêm menu 'File' và 'Path' vào trong
        FileMenu = self.menuBar().addMenu("&File")
        EditMenu = self.menuBar().addMenu("&Edit")

        # Declare các commands nằm trong 2 menu

        Undo = QAction("Undo", self)
        Undo.triggered.connect(self.editor.undo)

        Redo = QAction("Redo", self)
        Redo.triggered.connect(self.editor.redo)

        Cut = QAction("Cut", self)
        Cut.triggered.connect(self.editor.cut)

        Copy = QAction("Copy", self)
        Copy.triggered.connect(self.editor.copy)

        Paste = QAction("Paste", self)
        Paste.triggered.connect(self.editor.paste)

        SelectAll = QAction("Select All", self)
        SelectAll.triggered.connect(self.editor.selectAll)

        Open = QAction("Open File...", self)
        Open.triggered.connect(self.openFile)

        Save = QAction("Save", self)
        Save.triggered.connect(self.saveFile)

        SaveAs = QAction("Save As...", self)
        SaveAs.triggered.connect(self.saveAsFile)

        # Thêm các edit commands vào 'Edit' menu
        EditMenu.addAction(Undo)
        EditMenu.addAction(Redo)
        EditMenu.addSeparator()
        EditMenu.addAction(Cut)
        EditMenu.addAction(Copy)
        EditMenu.addAction(Paste)
        EditMenu.addAction(SelectAll)

        # Thêm các file commands vào 'File' menu
        FileMenu.addAction(Open)
        FileMenu.addAction(Save)
        FileMenu.addAction(SaveAs)

        #Show window
        self.show()

    # Ném vào user 1 cửa sổ báo error
    def Critical(self, message):
        mb = QMessageBox()
        mb.setWindowTitle("Error")
        mb.setText(message)
        mb.exec_()

   # Function dùng để mở file
    def openFile(self):
        path, _ = QFileDialog.getOpenFileName(self, "Open File", "",
                                              "All files (*.*)")

        if path:
            try:
                with open(path, "rU") as f:
                    text = f.read()

            except Exception as e:
                self.Critical(str(e))

            else:
                self.path = path
                self.editor.setPlainText(text)

    # Function dùng để save file
    def saveFile(self):
        if self.path is None:
            return self.saveAsFile()

        self.saveToPath(self.path)

   # Function save file nhưng dưới dạng save as
    def saveAsFile(self):
        path, _ = QFileDialog.getSaveFileName(self, "Save", "", "All files(*.*)")

        if not path:
            return

        self.saveToPath(self.path)

    # Dùng để thực hiện quá trình file
    def saveToPath(self, path):
        text = self.editor.toPlainText()
        try:
            with open(path, 'w') as f:
                f.write(text)

        except Exception as e:
            self.Critical(str(e))

        else:
            self.path = path
# biến app, đóng vai trò kích hoạt chương trình
app = QApplication(sys.argv)
app.setApplicationName("Krystal") # Set name cho app

# Window chính
window = MainWindow()

# Khởi động app
app.exec_()

Trước tiên là code của bạn khác code trên trang tut nhiều lắm bạn, code của bạn lúc run lên còn ko có menu save luôn, trong khi code trên trang tut thì có.

6 Likes

Đúng là mình làm nó khác hơn rất nhiều so với tut nên có thể gây khó đối với những người hỗ trợ mình, nhưng về cách hoạt động của các tính năng thì gần như y chang so với cái trên tut. Còn về cái menu save thì mình không để nó thành menu riêng mà để nó trong menu File, mình lấy cảm hứng cái này từ các Text editor khác. Tính năng save, save as và open file thì bê nguyên xi code trên tut (chỉ thêm phần hàm Critical thay thế hàm dialog_critical trên tut vì mình không thấy hàm này được declare trong code mà khi dùng lại bị báo lỗi).
Nếu bạn muốn giúp mình mà cần thêm thông tin thì bạn có thể hỏi mình, mình sẽ trả lời bất kì lúc nào có thể.

Hope this helps!

pathself.path là khác nhau đấy.

5 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?