Search code examples
python-3.xpyqt5qlistwidgetqplaintexteditqlistwidgetitem

How to remove matched string ( text ) in QPlainTextEdit from Qlistwidget unchecked item?


Below is my example code:

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(691, 327)
        self.listWidget = QtWidgets.QListWidget(Form)
        self.listWidget.setGeometry(QtCore.QRect(70, 40, 256, 192))
        self.listWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.listWidget.setObjectName("listWidget")
        self.plainTextEdit = QtWidgets.QPlainTextEdit(Form)
        self.plainTextEdit.setGeometry(QtCore.QRect(360, 40, 261, 191))
        self.plainTextEdit.setTabChangesFocus(True)
        self.plainTextEdit.setReadOnly(True)
        self.plainTextEdit.setObjectName("plainTextEdit")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

        lists = ["one","two","Three"]
        for i in lists:
            item = QtWidgets.QListWidgetItem(i)
            item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
            item.setCheckState(QtCore.Qt.Unchecked)
            self.listWidget.addItem(item)

        self.listWidget.itemClicked.connect(self.on_listWidget_itemClicked)

    def on_listWidget_itemClicked(self, item):
        lines = self.plainTextEdit.toPlainText()
        line_list = []
        #if item.listWidget().itemWidget(item) != None: 
        if item.checkState() == QtCore.Qt.Checked:
            self.plainTextEdit.appendPlainText(item.text())
        elif item.checkState() == QtCore.Qt.Unchecked:
            print(item.text())
            
    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

in this example i am using QListWidget with ItemIsUserCheckable and QPlainTextEdit. I able to getting items from Qlistwidget to QPlainTextEdit using with Checkboxes. If i check the item in Qlistwidget it is able to setting the text in to QPlaintextEdit. But i want to remove or delete the same text in QplainTextEdit when i uncheck the item box. For example if i check the item in Qlistwidget "one", it is setting "one" into the QplainTextEdit and the same item should be deleted when i uncheck the item. Is it possible if it is possible How to do?


Solution

  • Do not modify the code generated by Qt Designer but create another class that inherits from the appropriate widget and use the initial class to fill it.

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName("Form")
            Form.resize(691, 327)
            self.listWidget = QtWidgets.QListWidget(Form)
            self.listWidget.setGeometry(QtCore.QRect(70, 40, 256, 192))
            self.listWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
            self.listWidget.setObjectName("listWidget")
            self.plainTextEdit = QtWidgets.QPlainTextEdit(Form)
            self.plainTextEdit.setGeometry(QtCore.QRect(360, 40, 261, 191))
            self.plainTextEdit.setTabChangesFocus(True)
            self.plainTextEdit.setReadOnly(True)
            self.plainTextEdit.setObjectName("plainTextEdit")
    
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
              
        def retranslateUi(self, Form):
            _translate = QtCore.QCoreApplication.translate
            Form.setWindowTitle(_translate("Form", "Form"))
    
    
    class MainWindow(QtWidgets.QWidget, Ui_Form):                             
        def __init__(self):
            super().__init__()
            self.setupUi(self)
    
            lists = ["one","two","Three"]
            for i in lists:
                item = QtWidgets.QListWidgetItem(i)
                item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
                item.setCheckState(QtCore.Qt.Unchecked)
                self.listWidget.addItem(item)
                
    #        self.listWidget.itemClicked.connect(self.on_listWidget_itemClicked)
    
        def on_listWidget_itemClicked(self, item):
            if item.checkState() == QtCore.Qt.Checked:
                self.plainTextEdit.appendPlainText(item.text())
            elif item.checkState() == QtCore.Qt.Unchecked:
                text = self.plainTextEdit.toPlainText()            # 1
                text = text.replace(item.text(), '')               # 2 
                _list = text.split()                               # 3
                text = '\n'.join(_list)                            # 4
                self.plainTextEdit.setPlainText(text)              # 5  
    
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        Form = MainWindow() #QtWidgets.QWidget()
    #    ui = Ui_Form()
    #    ui.setupUi(Form)
        Form.show()
        sys.exit(app.exec_())
    

    enter image description here

    enter image description here


    Update

    And Can we do it when checkbox checked only , I mean the text should appended into Plaintextedit when checkbox checked. But it appends it even when selected the item.

    Sorry, I forgot to add One more thing in the question. Some times the list has not only single words but also two two words like First name and last names also like lists = ["Fname1 Lname1", "Fname2 Lname2", "Fname3 LName3"] . Can we do it like this?

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Ui_Form(object):
        def setupUi(self, Form):
            Form.setObjectName("Form")
            Form.resize(691, 327)
            self.listWidget = QtWidgets.QListWidget(Form)
            self.listWidget.setGeometry(QtCore.QRect(70, 40, 256, 192))
            self.listWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
            self.listWidget.setObjectName("listWidget")
            self.plainTextEdit = QtWidgets.QPlainTextEdit(Form)
            self.plainTextEdit.setGeometry(QtCore.QRect(360, 40, 261, 191))
            self.plainTextEdit.setTabChangesFocus(True)
            self.plainTextEdit.setReadOnly(True)
            self.plainTextEdit.setObjectName("plainTextEdit")
    
            self.retranslateUi(Form)
            QtCore.QMetaObject.connectSlotsByName(Form)
              
        def retranslateUi(self, Form):
            _translate = QtCore.QCoreApplication.translate
            Form.setWindowTitle(_translate("Form", "Form"))
    
    
    class MainWindow(QtWidgets.QWidget, Ui_Form):                             
        def __init__(self):
            super().__init__()
            self.setupUi(self)
            
            self.lists = {                                                   # !!! self.lists = {...}
                "Fname1 Lname1": 0, 
                "Fname2 Lname2": 0, 
                "Fname3 LName3": 0
            }  
    #        lists = ["one", "two", "Three"]
            for i in self.lists.keys():                                       # + .keys()
                item = QtWidgets.QListWidgetItem(i)
                item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
                item.setCheckState(QtCore.Qt.Unchecked)
                self.listWidget.addItem(item)
               
    #        self.listWidget.itemClicked.connect(self.on_listWidget_itemClicked)
    
        def on_listWidget_itemClicked(self, item):    
            #                                         +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvv
            if item.checkState() == QtCore.Qt.Checked and self.lists[item.text()] == 0:
                self.plainTextEdit.appendPlainText(item.text())
                self.lists[item.text()] = 1                                   # +
            elif item.checkState() == QtCore.Qt.Unchecked:
                text = self.plainTextEdit.toPlainText()
                text = text.replace(item.text(), '')
    #            _list = text.split()              
                _list = text.split('\n')                                      # + '\n'
                _list = [ i for i in _list if i ]                             # +
                text = '\n'.join(_list)              
                self.plainTextEdit.setPlainText(text)   
                self.lists[item.text()] = 0                                   # +
    
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        Form = MainWindow() 
        Form.show()
        sys.exit(app.exec_())
    

    enter image description here