当 QPlainTextEdit 在一定长度时运行方法

Posted

技术标签:

【中文标题】当 QPlainTextEdit 在一定长度时运行方法【英文标题】:run method when QPlainTextEdit at a certain length 【发布时间】:2019-02-24 03:32:23 【问题描述】:

我有一个 pyqt 对话框,它接收以返回结尾的数据列表(来自具有自动返回的条形码扫描仪。)

列表长度为 5 项,目前我必须在输入 5 项时单击“添加数据”才能运行 populate_row 方法。

我使用\n 将字符串拆分为一个列表,并根据需要处理每个项目。

QPlainTextEdit 框中的行数或\n 的数量达到5 时,我是否可以自动按下add data 按钮?

import sys

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class Status(QDialog):
    def __init__(self, parent=None):
        super(Status, self).__init__(parent)

        self.label = QLabel()

        self.btn = QPushButton("Input Data")
        self.btn.clicked.connect(self.populate_row)

        self.layout = QVBoxLayout()

        self.layout.addWidget(self.btn)
        self.layout.addWidget(self.label)

        self.resize(660, 260)
        self.setLayout(self.layout)

    def populate_row(self, letter):
        self.dialog = QDialog()

        self.dialog.resize(660, 260)

        self.textBox = QPlainTextEdit(self.dialog)

        Rbtn = QPushButton("Add Data")
        Rbtn.clicked.connect(
            lambda: self.enter_data(self.textBox.toPlainText()))

        layout = QVBoxLayout(self.dialog)
        layout.addWidget(self.textBox)
        layout.addWidget(Rbtn)

        self.dialog.exec_()

    def enter_data(self, text):
        self.label.setText(text)

        lst = text.split("\n")
        try:
            for  x in lst:
                if x != "":
                    print(x)
                    self.do_something_with_x()
        except IndexError:
            pass

        self.update_data()

        self.dialog.close()

    def do_something_with_x(self):
        print('Something done with x..')

    def update_data(self):
        print('Data updated..')

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = Status()
    ex.show()
    sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

要计算换行符,请使用blockCountChanged() 信号,如果要单击按钮,则必须使用click() 方法。还要验证一个字符串是否为空,使用 if x: 就足够了,因为字符串是可迭代的,如果它是空的,if iterable 返回 False,在其他情况下返回 True。

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


class Status(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(Status, self).__init__(parent)
        self.label = QtWidgets.QLabel()
        self.btn = QtWidgets.QPushButton("Input Data")
        self.btn.clicked.connect(self.populate_row)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.btn)
        layout.addWidget(self.label)
        self.resize(660, 260)


    def populate_row(self, letter):
        self.dialog = QtWidgets.QDialog()
        self.dialog.resize(660, 260)
        self.textBox = QtWidgets.QPlainTextEdit()
        self.textBox.blockCountChanged.connect(self.blockCount)
        self.Rbtn = QtWidgets.QPushButton("Add Data")
        self.Rbtn.clicked.connect(self.runcode)
        layout = QtWidgets.QVBoxLayout(self.dialog)
        layout.addWidget(self.textBox)
        layout.addWidget(self.Rbtn)
        self.dialog.exec_()

    @QtCore.pyqtSlot(int)
    def blockCount(self, num):
        if num > 5: self.Rbtn.click()

    def runcode(self):
        self.enter_data(self.textBox.toPlainText())

    def enter_data(self, text):
        self.label.setText(text)
        for  x in text.split("\n"):
            if x:
                print(x)
                self.do_something_with_x()
        self.update_data()
        self.dialog.close()

    def do_something_with_x(self):
        print('Something done with x..')

    def update_data(self):
        print('Data updated..')

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ex = Status()
    ex.show()
    sys.exit(app.exec_())

【讨论】:

【参考方案2】:

void QPlainTextEdit::blockCountChanged(int newBlockCount)

只要块数发生变化,就会发出这个信号。新的块计数在 newBlockCount 中传递。

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui     import *
from PyQt5.QtCore    import *

class Status(QDialog):
    def __init__(self, parent=None):
        super(Status, self).__init__(parent)

        self.label = QLabel()

        self.btn = QPushButton("Input Data")
        self.btn.clicked.connect(self.populate_row)

        self.layout = QVBoxLayout()

        self.layout.addWidget(self.btn)
        self.layout.addWidget(self.label)

        self.resize(660, 260)
        self.setLayout(self.layout)

    def populate_row(self, letter):
        self.dialog = QDialog()

        self.dialog.resize(660, 260)

        self.textBox = QPlainTextEdit(self.dialog)
        #
        self.textBox.blockCountChanged[int].connect(self.blockCount)  # +++
        
        

        Rbtn = QPushButton("Add Data")
        Rbtn.clicked.connect(
            lambda: self.enter_data(self.textBox.toPlainText()))

        layout = QVBoxLayout(self.dialog)
        layout.addWidget(self.textBox)
        #layout.addWidget(Rbtn)                                       # ---

        self.dialog.exec_()
## +++
    def blockCount(self, num):
        if num > 5:
            self.enter_data(self.textBox.toPlainText())
##

    def enter_data(self, text):
        self.label.setText(text)
        lst = text.split("\n")
        try:
            for  x in lst:
                if x != "":
                    print(x)
                    self.do_something_with_x()
        except IndexError:
            pass

        self.update_data()

        self.dialog.close()

    def do_something_with_x(self):
        print('Something done with x..')

    def update_data(self):
        print('Data updated..')

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = Status()
    ex.show()
    sys.exit(app.exec_())

【讨论】:

以上是关于当 QPlainTextEdit 在一定长度时运行方法的主要内容,如果未能解决你的问题,请参考以下文章

不能通过 keyPressEvent 使用 QPlainTextEdit 中的其他键

使用自定义格式并且不要在 qplaintextedit 中选择完整的文本

在 QPlainTextEdit 中获取指向 QTextBlock 的指针

在 QTableView 中设置 QPlainTextEdit 委托的高度

Python PyCharm利用PyQt5使QPlainTextEdit支持拖放文件,类提升,重写QPlainTextEdit类

使用 QPlainTextEdit 绘制 QGraphicsProxyWidget 的工件