python - 移动光标线位置 QTextEdit

标签 python python-3.x pyqt pyqt5 python-3.6

  • 文本编辑器:Sublime Text 3
  • Python 版本:3.6
  • UTF-8
  • PyQt5

我正在 PyQt5 中制作一个记事本,并且我正在制作一个能够在行之间导航的选项,当然,我需要移动文本编辑器光标,以便它位于用户想要的行中,并且问题是, Nose 如何移动TextEdit的光标。我使用了多种方法,但没有一个有效。简单的或者不移动光标或者错误跳转。

这是完整的代码:https://github.com/MasPot4/Bloc-de-Notas

这是错误的部分

import sys
from PyQt5 import QtGui
from PyQt5.QtGui import QTextCursor
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QMainWindow, QApplication, QTextEdit, QMessageBox, QLabel, QPushButton
from PyQt5.QtWidgets import QHBoxLayout, QWidget, QMenu, QAction, QFileDialog, QLineEdit
import tkinter

root = tkinter.Tk()
width = root.winfo_screenwidth()
height = root.winfo_screenheight()

class textEdit(QTextEdit):
    def __init__(self):
        super(textEdit, self).__init__()

        self.cursor = self.textCursor()

class gotolineWin(QMainWindow):
    def __init__(self):
        super(gotolineWin, self).__init__()
        self.main = textEdit()
        self.label = QLabel(self)
        self.go_line = QLineEdit(self)
        self.buttonGoto = QPushButton("Go to...", self)
        self.buttonCancel = QPushButton("Cancel", self)

        self.initUi()

    def initUi(self):
        self.label.setText("Go to...")
        self.label.move(20, 0)

        self.go_line.move(20, 25)
        self.go_line.resize(260, 20)

        self.buttonGoto.move(20, 60)
        self.buttonGoto.resize(100, 30)
        self.buttonGoto.clicked.connect(lambda: self.GoToLine(int(self.go_line.text())))

        self.buttonCancel.clicked.connect(self.cancel)
        self.buttonCancel.move(180, 60)

        self.setGeometry((width / 2) - 150, (height / 2) - 50, 300, 100)
        self.setWindowTitle("Go to...")

    def GoToLine(self, line):
        # self.main.cursor = self.main.textCursor()
        # self.main.cursor.movePosition(self.main.cursor.Left, self.main.cursor.KeepAnchor, 3)
        # self.main.setTextCursor(self.main.cursor)

        ln = int(line)
        linecursor = QTextCursor(self.main.document().findBlockByLineNumber(ln - 1))
        self.main.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
        self.main.setTextCursor(linecursor)

        self.close()

    def cancel(self):
        self.close()

class writter(QMainWindow):
    def __init__(self):
        super().__init__()

        self.textEdit = textEdit()
        self.lineWin = gotolineWin()
        self.setCentralWidget(self.textEdit)

        self.file_name = None

        self.initUi()

    def initUi(self):
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('File')
        editMenu = menubar.addMenu('Edit')
        formatMenu = menubar.addMenu('Format')
        viewMenu = menubar.addMenu("View")

        # File Menu     
        new_file = QAction('New', self)
        new_file.setShortcut("Ctrl+N")
        new_file.triggered.connect(self.newfile)

        open_file = QAction('Open...', self)
        open_file.setShortcut("Ctrl+O")
        open_file.triggered.connect(self.openfile)

        save_file = QAction('Save', self)
        save_file.setShortcut("Ctrl+S")
        save_file.triggered.connect(self.savefile)

        save_as_file = QAction('Save As...', self)
        save_as_file.setShortcut("Ctrl+Shift+S")
        save_as_file.triggered.connect(self.saveasfile)

        exit = QAction("Exit", self)
        exit.triggered.connect(self.quit)

        # Edit Menu
        undo_edit = QAction("Undo", self)
        undo_edit.setShortcut("Ctrl+Z")
        undo_edit.triggered.connect(self.undo)

        cut_edit = QAction("Cut", self)
        cut_edit.setShortcut("Ctrl+X")
        cut_edit.triggered.connect(self.cut)

        copy_edit = QAction("Copy", self)
        copy_edit.setShortcut("Ctrl+C")
        copy_edit.triggered.connect(self.copy)

        paste_edit = QAction("Paste", self)
        paste_edit.setShortcut("Ctrl+V")
        paste_edit.triggered.connect(self.paste)

        delete_edit = QAction("Delete", self)
        delete_edit.setShortcut("Supr")
        delete_edit.triggered.connect(self.delete)

        goto_edit = QAction("Go To...", self)
        goto_edit.setShortcut("Ctrl+T")
        goto_edit.triggered.connect(self.gotoline)

        find_editor = QAction("Find", self)
        find_editor.setShortcut("Ctrl+F")

        select_all_edit = QAction("Select All", self)
        select_all_edit.setShortcut("Ctrl+E")

        time_edit = QAction("Date and Time", self)
        time_edit.setShortcut("F5")

        # Format Menu
        font_format = QAction("Font", self)

        # View Menu
        zoom_view = QMenu("Zoom", self)
        zoom_mas_view = QAction("Zoom In", self)
        zoom_mas_view.setShortcut("Ctrl++")
        zoom_menos_view = QAction("Ward Off", self)
        zoom_menos_view.setShortcut("Ctrl+-")
        zoom_pre_view = QAction("Restore Default Zoom", self)
        zoom_pre_view.setShortcut("Ctrl+0")
        zoom_view.addAction(zoom_mas_view)
        zoom_view.addAction(zoom_menos_view)
        zoom_view.addAction(zoom_pre_view)

        statusbar_view = QAction("Status Bar", self)

        fileMenu.addAction(new_file)
        fileMenu.addAction(open_file)
        fileMenu.addAction(save_file)
        fileMenu.addAction(save_as_file)
        fileMenu.addSeparator()
        fileMenu.addAction(exit)

        editMenu.addAction(undo_edit)
        editMenu.addSeparator()
        editMenu.addAction(cut_edit)
        editMenu.addAction(copy_edit)
        editMenu.addAction(paste_edit)
        editMenu.addAction(delete_edit)
        editMenu.addSeparator()
        editMenu.addAction(goto_edit)
        editMenu.addAction(find_editor)
        editMenu.addSeparator()
        editMenu.addAction(select_all_edit)
        editMenu.addAction(time_edit)

        viewMenu.addMenu(zoom_view)
        viewMenu.addAction(statusbar_view)

        self.setGeometry((width / 2) - 300, (height / 2) - 250, 600, 500)
        self.setWindowTitle("NotePad 2.0")
        self.show()

    def newfile(self):
        if self.textEdit.toPlainText() != "":
            buttonReply = QMessageBox.question(self, 'Bloc de Notas 2.0', f"You want to save changes to Sin Titulo?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if buttonReply == QMessageBox.Yes:
                self.saveasfile()
            else:
                try:
                    name, _ = QFileDialog.getSaveFileName(self, "New File", "New File.txt", "All Files (*.*)")
                    url = QUrl.fromLocalFile(name)
                    name = url.fileName()
                    with open(name, "w") as f:
                        f.write("")
                    self.textEdit.clear()
                    self.file_name = name
                except FileNotFoundError:
                    pass
        else:
            try:
                name, _ = QFileDialog.getSaveFileName(self, "New File", "New File.txt", "All Files (*.*)")
                url = QUrl.fromLocalFile(name)
                name = url.fileName()
                with open(name, "w") as f:
                    f.write("")
                self.textEdit.clear()
                self.file_name = name
            except FileNotFoundError:
                pass

    def openfile(self):
        if self.textEdit.toPlainText() != "":
            buttonReply = QMessageBox.question(self, 'Bloc de Notas 2.0', f"You want to save changes to Sin Titulo?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if buttonReply == QMessageBox.Yes:
                self.saveasfile()               
            else:
                try:
                    name, _ = QFileDialog.getOpenFileName(self, "New File", "New File.txt", "All Files (*.*)")
                    url = QUrl.fromLocalFile(name)
                    name = url.fileName()
                    with open(name, "r") as f:
                        content = f.read()
                    self.textEdit.setText(content)
                except FileNotFoundError:
                    pass
        else:
            try:
                name, _ = QFileDialog.getOpenFileName(self, "New File", "New File.txt", "All Files (*.*)")
                url = QUrl.fromLocalFile(name)
                name = url.fileName()
                with open(name, "r") as f:
                    content = f.read()
                self.textEdit.setText(content)
            except FileNotFoundError:
                pass

    def savefile(self):
        if self.textEdit.toPlainText() == "":
            self.newfile()
        elif self.textEdit.toPlainText() != "":
            if self.file_name == None:
                self.saveasfile()
            else:
                with open(self.file_name, "w") as f:
                    f.write(self.textEdit.toPlainText())
        elif self.file_name == None:
            self.saveasfile()

    def saveasfile(self):
        try:
            name, _ = QFileDialog.getSaveFileName(self,'Save File', "New File.txt", "All Files (*.*)")
            with open(name, "w") as f:
                f.write(self.textEdit.toPlainText())
            self.file_name = name
        except FileNotFoundError:
            pass

    def quit(self):
        sys.exit()

    def undo(self):
        self.textEdit.undo()

    def cut(self):
        self.textEdit.copy()
        self.textEdit.insertPlainText("")

    def copy(self):
        self.textEdit.copy()

    def paste(self):
        text = QApplication.clipboard().text()
        self.textEdit.insertPlainText(text)

    def delete(self):
        self.textEdit.insertPlainText("")

    def gotoline(self):
        self.lineWin.show()

app = QApplication(sys.argv)
Window = writter()
sys.exit(app.exec_())

最佳答案

您正在 gotolineWin 小部件中创建另一个 QTextEdit,这是不必要的,而且您正在移动 QTextEdit 的光标,该光标不是 QMainWindow 中显示的 QTextEdit。考虑到这一点,我创建了一个 QDialog,它应该只接收添加您想要的功能的 QTextEdit。

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


class GoToDialog(QtWidgets.QDialog):
    gotoSignal = QtCore.pyqtSignal(int)

    def __init__(self, text_edit, parent=None):
        super().__init__(parent)

        self.m_text_edit = text_edit

        self.spinbox = QtWidgets.QSpinBox(minimum=1)
        self.m_text_edit.document().blockCountChanged.connect(self.spinbox.setMaximum)
        self.spinbox.setMaximum(self.m_text_edit.document().blockCount())

        self.buttonGoto = QtWidgets.QPushButton("Go to...")
        self.buttonGoto.clicked.connect(self.onAccepted)
        self.buttonCancel = QtWidgets.QPushButton("Cancel")
        self.buttonCancel.clicked.connect(self.reject)

        vlay = QtWidgets.QVBoxLayout(self)
        hlay = QtWidgets.QHBoxLayout()
        hlay.addWidget(self.buttonGoto)
        hlay.addWidget(self.buttonCancel)
        vlay.addWidget(QtWidgets.QLabel("Go to..."))
        vlay.addWidget(self.spinbox)
        vlay.addLayout(hlay)
        self.setFixedSize(300, 100)

    def onAccepted(self):
        n = self.spinbox.value() - 1
        if 0 <= n < self.m_text_edit.document().blockCount():
            cursor = QtGui.QTextCursor(
                self.m_text_edit.document().findBlockByLineNumber(n)
            )
            self.m_text_edit.setTextCursor(cursor)
        self.reject()


class Writter(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.text_edit = QtWidgets.QTextEdit()
        self.setCentralWidget(self.text_edit)

        self.goto_dialog = GoToDialog(self.text_edit, self)

        menubar = self.menuBar()
        editMenu = menubar.addMenu("Edit")

        goto_edit = QtWidgets.QAction("Go To...", self)
        goto_edit.setShortcut("Ctrl+T")
        goto_edit.triggered.connect(self.goto_dialog.show)
        editMenu.addAction(goto_edit)

        self.resize(600, 500)
        self.center()

    def center(self):
        self.setGeometry(
            QtWidgets.QStyle.alignedRect(
                QtCore.Qt.LeftToRight,
                QtCore.Qt.AlignCenter,
                self.size(),
                QtWidgets.qApp.desktop().availableGeometry(),
            )
        )


def main():
    app = QtWidgets.QApplication(sys.argv)
    w = Writter()
    w.show()
    return app.exec_()


if __name__ == "__main__":
    sys.exit(main())

关于python - 移动光标线位置 QTextEdit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57263368/

相关文章:

javascript - Python 版本的 JavaScript ES6 符号

python - 使用 QSortFilterProxyModel 自定义 QCompleter

python - Pandas:在一次操作中从单个系列创建两个列表

Python 和 Selenium : Check which of two images loaded on a given page

python - 对整个句子应用 NLP WordNetLemmatizer 显示错误且位置未知

python - 从 ubuntu 上的 python eclipse 项目导出可运行程序

python-3.x - pytest 在导入时找不到模块,但代码运行得很好

Python Numpy.matrix 乘法错误

python - PYQT5 中的布局大小

python - 如何使 QListWidgetItem 不是三态?