0

I have a sample code and I want to reload the text inside the QTextEdit by pushing a Find and Replace button. QTextEdit text is already loaded from the dictionary and I want to change one of dictionary old key with dictionary new key and show new key in QTextEdit after changing the dictionary old key!

my means is new details of QTextEdit not shown and old information stays.

how did I do it?

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class Window(QtWidgets.QMainWindow):
    my_dict = {'key1': 'value1', 'key2': 'value2'}
    def __init__(self):
        super(Window, self).__init__()
        V = QtWidgets.QApplication.desktop().screenGeometry()
        h, w, x, y = V.height(), V.width(), 1000, 600
        self.setGeometry(h/4, w/20, x, y)
        self.setFixedSize(x, y)
        self.setWindowTitle('Main Window')
        centralWidget = QtWidgets.QWidget()
        self.setCentralWidget(centralWidget)
        self.grid = QtWidgets.QGridLayout(centralWidget)
        self.home()

    def home(self):
        self.tools_in_home()
        self.show()

    def tools_in_home(self):
        global find_entry
        global replace_entry
        global textBox
        self.groupBox0 = QtWidgets.QGroupBox('Test') 
        self.groupBox0.setFixedSize(400, 150)
        hBoxLayout = QtWidgets.QHBoxLayout()
        textBox = QtWidgets.QTextEdit()
        textBox.resize(400, 200)
        textBox.setReadOnly(True)
        list_keys = list(Window.my_dict.keys())
        list_values = list(Window.my_dict.values())
        if len(list_keys) == 0:
            textBox.append('--EMPTY--')
        else:
            for num, dict_key in enumerate(list_keys):
                res = '{:50s} | {:50s}'.format(dict_key, list_values[num])
                textBox.append(res)

        hBoxLayout.addWidget(textBox)
        self.groupBox0.setLayout(hBoxLayout)

        find_entry = QtWidgets.QLineEdit('Enter the value you want to find...')
        find_entry.setFixedSize(380,25)

        replace_entry = QtWidgets.QLineEdit('Enter the value you want to replace...')
        replace_entry.setFixedSize(380,25)

        replace_btn = QtWidgets.QPushButton('Find and Replace')
        replace_btn.setFixedSize(125, 25)
        replace_btn.clicked.connect(self.replace_in_dict)

        self.grid.addWidget(self.groupBox0, 0, 0)
        self.grid.addWidget(find_entry, 1, 0)
        self.grid.addWidget(replace_entry, 2, 0)
        self.grid.addWidget(replace_btn, 3, 0)

    def replace_in_dict(self):
        findwt = find_entry.text()
        ans_of_findwt = Window.my_dict.get(findwt, 'Not Exist')
        if ans_of_findwt == 'Not Exist':
            QtWidgets.QMessageBox.warning(self, ans_of_findwt, 'There is no result', QtWidgets.QMessageBox.Ok)

        else:
            old_key, old_value = findwt, Window.my_dict.pop(findwt)
            new_key = replace_entry.text()
            Window.my_dict.update({new_key: old_value})
            QtWidgets.QMessageBox.information(self, 'Success','[{0}] has replaced successfully with [{1}]\n\nResult:\n\t{1} : {2}'.format(old_key, new_key, old_value), QtWidgets.QMessageBox.Ok)

def run():
    app = QtWidgets.QApplication(sys.argv)
    GUI = Window()
    sys.exit(app.exec_())

if __name__ == '__main__':
    run()
Nima
  • 21
  • 1
  • 4

1 Answers1

0

Your code has the following errors:

  • You are assuming that when you change the dictionary the text will be reloaded but it is not, so you must implement a function that replaces the text.
  • Assuming that you want to preserve the order you must use OrderedDict since the default dictionary does not keep the order.
  • To verify that there is a key in a dictionary, do not use get since the word you use by default ("Not Exist") may belong to the dictionary so it is better to use in.

Considering the above, the solution is:

import sys
from collections import OrderedDict
from PyQt5 import QtCore, QtGui, QtWidgets


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

        groupBox = QtWidgets.QGroupBox("Test")
        self._textBox = QtWidgets.QTextEdit(readOnly=True)
        hBoxLayout = QtWidgets.QHBoxLayout()
        hBoxLayout.addWidget(self._textBox)
        groupBox.setLayout(hBoxLayout)

        self._find_entry = QtWidgets.QLineEdit(
            placeholderText="Enter the value you want to find..."
        )
        self._replace_entry = QtWidgets.QLineEdit(
            placeholderText="Enter the value you want to replace..."
        )
        replace_btn = QtWidgets.QPushButton(
            text="Find and Replace", clicked=self.on_clicked
        )

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QVBoxLayout(central_widget)
        lay.addWidget(groupBox)
        lay.addWidget(self._find_entry)
        lay.addWidget(self._replace_entry)
        lay.addWidget(replace_btn)
        self.resize(640, 480)

        self._my_dict = OrderedDict({"key1": "value1", "key2": "value2"})
        self.load_dictionary(self._my_dict)

    @QtCore.pyqtSlot()
    def on_clicked(self):
        old_key = self._find_entry.text()
        new_key = self._replace_entry.text()
        self.replace_key(old_key, new_key)

    def load_dictionary(self, d):
        self._textBox.clear()
        for key, value in d.items():
            res = "{:50s} | {:50s}".format(key, value)
            self._textBox.append(res)

    def replace_key(self, old_key, new_key):
        # https://stackoverflow.com/a/1602964/6622587
        if old_key in self._my_dict:
            # https://stackoverflow.com/a/12150917/6622587
            self._my_dict = OrderedDict(
                [
                    (new_key, v) if k == old_key else (k, v)
                    for k, v in self._my_dict.items()
                ]
            )
            self.load_dictionary(self._my_dict)
        else:
            QtWidgets.QMessageBox.warning(
                self,
                "Not Exist",
                "There is no result",
                QtWidgets.QMessageBox.Ok,
            )


def run():
    app = QtWidgets.QApplication(sys.argv)
    gui = MainWindow()
    gui.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    run()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241