diff --git a/electrum/gui/qt/contact_list.py b/electrum/gui/qt/contact_list.py
index e1915b1b6..5c167f3ec 100644
--- a/electrum/gui/qt/contact_list.py
+++ b/electrum/gui/qt/contact_list.py
@@ -49,12 +49,8 @@ class ContactList(MyTreeView):
 
     def on_edited(self, idx, user_role, text):
         _type, prior_name = self.parent.contacts.pop(user_role)
-
-        # TODO when min Qt >= 5.11, use siblingAtColumn
-        col_1_sibling = idx.sibling(idx.row(), 1)
-        col_1_item = self.model().itemFromIndex(col_1_sibling)
-
-        self.parent.set_contact(text, col_1_item.text())
+        self.parent.set_contact(text, user_role)
+        self.update()
 
     def import_contacts(self):
         import_meta_gui(self.parent, _('contacts'), self.parent.contacts.import_file, self.update)
diff --git a/electrum/gui/qt/history_list.py b/electrum/gui/qt/history_list.py
index 1a2fb30af..b50aaa7d9 100644
--- a/electrum/gui/qt/history_list.py
+++ b/electrum/gui/qt/history_list.py
@@ -67,9 +67,6 @@ class HistorySortModel(QSortFilterProxyModel):
             return False
         return item1.value() < item2.value()
 
-# requires PyQt5 5.11
-indexIsValid = QAbstractItemModel.CheckIndexOptions(QAbstractItemModel.CheckIndexOption.IndexIsValid.value)
-
 class HistoryModel(QAbstractItemModel):
     def __init__(self, parent):
         super().__init__(parent)
@@ -80,14 +77,15 @@ class HistoryModel(QAbstractItemModel):
         return 8
 
     def rowCount(self, parent: QModelIndex):
-        l = len(self.transactions)
-        return l
+        return len(self.transactions)
 
     def index(self, row: int, column: int, parent : QModelIndex):
         return self.createIndex(row,column)
 
     def data(self, index: QModelIndex, role: Qt.ItemDataRole):
-        assert self.checkIndex(index, indexIsValid)
+        # requires PyQt5 5.11
+        # indexIsValid = QAbstractItemModel.CheckIndexOptions(QAbstractItemModel.CheckIndexOption.IndexIsValid.value)
+        # assert self.checkIndex(index, indexIsValid)
         assert index.isValid()
         tx_item = self.transactions[index.row()]
         tx_hash = tx_item['txid']
@@ -169,6 +167,10 @@ class HistoryModel(QAbstractItemModel):
         return self.parent.wallet.get_addresses()
 
     def refresh(self, reason: str):
+        selected = self.parent.history_list.selectionModel().currentIndex()
+        selected_row = None
+        if selected:
+            selected_row = selected.row()
         fx = self.parent.fx
         if fx: fx.history_used_spot = False
         r = self.parent.wallet.get_full_history(domain=self.get_domain(), from_timestamp=None, to_timestamp=None, fx=fx)
@@ -182,6 +184,8 @@ class HistoryModel(QAbstractItemModel):
         self.beginInsertRows(QModelIndex(), 0, len(r['transactions'])-1)
         self.transactions = r['transactions']
         self.endInsertRows()
+        if selected_row:
+            self.parent.history_list.selectionModel().select(self.createIndex(selected_row, 0), QItemSelectionModel.Rows | QItemSelectionModel.SelectCurrent)
         f = self.parent.history_list.current_filter
         if f:
             self.parent.history_list.filter(f)
@@ -279,7 +283,6 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
         self.proxy.setSourceModel(model)
         self.setModel(self.proxy)
 
-        self.summary = {}
         self.config = parent.config
         AcceptFileDragDrop.__init__(self, ".txn")
         self.setSortingEnabled(True)
@@ -374,7 +377,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
             return datetime.datetime(date.year, date.month, date.day)
 
     def show_summary(self):
-        h = self.summary
+        h = self.model().sourceModel().summary
         if not h:
             self.parent.show_message(_("Nothing to summarize."))
             return
@@ -425,7 +428,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
             self.parent.show_message(str(e))
 
     def on_edited(self, index, user_role, text):
-        print("on_edited")
+        index = self.model().mapToSource(index)
         row, column = index.row(), index.column()
         tx_item = self.hm.transactions[row]
         key = tx_item['txid']
@@ -438,7 +441,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
             self.wallet.set_fiat_value(key, self.parent.fx.ccy, text, self.parent.fx, tx_item['value'].value)
             value = tx_item['value'].value
             if value is not None:
-                self.hm.update_fiat(row, self.model().mapToSource(index))
+                self.hm.update_fiat(row, index)
         else:
             assert False
 
@@ -472,7 +475,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
             column_data = tx_item['txid']
         else:
             column_title = self.hm.headerData(column, Qt.Horizontal, Qt.DisplayRole)
-            column_data = str(self.hm.data(idx, Qt.DisplayRole))
+            column_data = self.hm.data(idx, Qt.DisplayRole).value()
         tx_hash = tx_item['txid']
         tx = self.wallet.transactions[tx_hash]
         tx_URL = block_explorer_URL(self.config, 'tx', tx_hash)
@@ -595,4 +598,4 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
     def text_txid_from_coordinate(self, row, col):
         idx = self.model().mapToSource(self.model().index(row, col))
         tx_item = self.hm.transactions[idx.row()]
-        return str(self.hm.data(idx, Qt.DisplayRole)), tx_item['txid']
+        return self.hm.data(idx, Qt.DisplayRole).value(), tx_item['txid']
diff --git a/electrum/gui/qt/util.py b/electrum/gui/qt/util.py
index 7fba7ce67..c88b9e333 100644
--- a/electrum/gui/qt/util.py
+++ b/electrum/gui/qt/util.py
@@ -398,8 +398,23 @@ def filename_field(parent, config, defaultname, select_msg):
     return vbox, filename_e, b1
 
 class ElectrumItemDelegate(QStyledItemDelegate):
-    def createEditor(self, parent, option, index):
-        return self.parent().createEditor(parent, option, index)
+    def __init__(self, tv):
+        super().__init__(tv)
+        self.tv = tv
+        self.opened = None
+        def on_closeEditor(editor: QLineEdit, hint):
+            self.opened = None
+        def on_commitData(editor: QLineEdit):
+            new_text = editor.text()
+            idx = QModelIndex(self.opened)
+            _prior_text, user_role = self.tv.text_txid_from_coordinate(idx.row(), idx.column())
+            self.tv.on_edited(idx, user_role, new_text)
+        self.closeEditor.connect(on_closeEditor)
+        self.commitData.connect(on_commitData)
+
+    def createEditor(self, parent, option, idx):
+        self.opened = QPersistentModelIndex(idx)
+        return super().createEditor(parent, option, idx)
 
 class MyTreeView(QTreeView):
 
@@ -415,8 +430,6 @@ class MyTreeView(QTreeView):
         self.icon_cache = IconCache()
 
         # Control which columns are editable
-        self.editor = None
-        self.pending_update = False
         if editable_columns is None:
             editable_columns = {stretch_column}
         else:
@@ -458,7 +471,9 @@ class MyTreeView(QTreeView):
             self.header().setSectionResizeMode(col, sm)
 
     def keyPressEvent(self, event):
-        if event.key() in [ Qt.Key_F2, Qt.Key_Return ] and self.editor is None:
+        if self.itemDelegate().opened:
+            return
+        if event.key() in [ Qt.Key_F2, Qt.Key_Return ]:
             self.on_activated(self.selectionModel().currentIndex())
             return
         super().keyPressEvent(event)
@@ -469,36 +484,6 @@ class MyTreeView(QTreeView):
         pt.setX(50)
         self.customContextMenuRequested.emit(pt)
 
-    def createEditor(self, parent, option, idx):
-        self.editor = QStyledItemDelegate.createEditor(self.itemDelegate(),
-                                                       parent, option, idx)
-        prior_text, user_role = self.text_txid_from_coordinate(idx.row(), idx.column())
-        def editing_finished():
-            print("editing finished")
-            # Long-time QT bug - pressing Enter to finish editing signals
-            # editingFinished twice.  If the item changed the sequence is
-            # Enter key:  editingFinished, on_change, editingFinished
-            # Mouse: on_change, editingFinished
-            # This mess is the cleanest way to ensure we make the
-            # on_edited callback with the updated item
-            if self.editor is None:
-                return
-            if self.editor.text() == prior_text:
-                print("unchanged ignore any 2nd call")
-                self.editor = None # Unchanged - ignore any 2nd call
-                return
-            if not idx.isValid():
-                print("idx not valid")
-                return
-            new_text, _ = self.text_txid_from_coordinate(idx.row(), idx.column())
-            if new_text == prior_text:
-                print("buggy first call", new_text, prior_text)
-                return # Buggy first call on Enter key, item not yet updated
-            self.on_edited(idx, user_role, self.editor.text())
-            self.editor = None
-        self.editor.editingFinished.connect(editing_finished)
-        return self.editor
-
     def edit(self, idx, trigger=QAbstractItemView.AllEditTriggers, event=None):
         """
         this is to prevent:
@@ -509,7 +494,7 @@ class MyTreeView(QTreeView):
 
     def on_edited(self, idx: QModelIndex, user_role, text):
         self.parent.wallet.set_label(user_role, text)
-        self.parent.history_list.update_labels()
+        self.parent.history_model.refresh('on_edited in MyTreeView')
         self.parent.update_completions()
 
     def should_hide(self, row):
@@ -523,7 +508,10 @@ class MyTreeView(QTreeView):
         assert not isinstance(self.model(), QSortFilterProxyModel)
         idx = self.model().index(row_num, column)
         item = self.model().itemFromIndex(idx)
-        return item.text(), item.data(Qt.UserRole)
+        user_role = item.data(Qt.UserRole)
+        # check that we didn't forget to set UserRole on an editable field
+        assert user_role is not None, (row_num, column)
+        return item.text(), user_role
 
     def hide_row(self, row_num):
         """
diff --git a/electrum/gui/qt/utxo_list.py b/electrum/gui/qt/utxo_list.py
index 0b9d85508..046f30fc4 100644
--- a/electrum/gui/qt/utxo_list.py
+++ b/electrum/gui/qt/utxo_list.py
@@ -33,7 +33,7 @@ class UTXOList(MyTreeView):
     filter_columns = [0, 1]  # Address, Label
 
     def __init__(self, parent=None):
-        super().__init__(parent, self.create_menu, 1)
+        super().__init__(parent, self.create_menu, 1, editable_columns=[])
         self.setModel(QStandardItemModel(self))
         self.setSelectionMode(QAbstractItemView.ExtendedSelection)
         self.setSortingEnabled(True)
diff --git a/electrum/wallet.py b/electrum/wallet.py
index a32888cf2..746f25cac 100644
--- a/electrum/wallet.py
+++ b/electrum/wallet.py
@@ -239,7 +239,7 @@ class Abstract_Wallet(AddressSynchronizer):
                 self.labels[name] = text
                 changed = True
         else:
-            if old_text:
+            if old_text is not None:
                 self.labels.pop(name)
                 changed = True
         if changed: