diff --git a/src/sakia/gui/dialogs/connection_cfg/controller.py b/src/sakia/gui/dialogs/connection_cfg/controller.py
index d90c6dfac40431e018eb13799c1c5d025a17de99..ebfbb033303d08efcae06a841716d09507ce5167 100644
--- a/src/sakia/gui/dialogs/connection_cfg/controller.py
+++ b/src/sakia/gui/dialogs/connection_cfg/controller.py
@@ -1,7 +1,7 @@
 import asyncio
 import logging
 
-from PyQt5.QtCore import QObject, Qt
+from PyQt5.QtCore import QObject, Qt, QCoreApplication
 from aiohttp import ClientError
 from asyncio import TimeoutError
 
@@ -100,7 +100,7 @@ class ConnectionConfigController(QObject):
 
         self.view.set_nodes_model(model)
         self.view.button_previous.setEnabled(False)
-        self.view.button_next.setText(self.config_dialog.tr("Ok"))
+        self.view.button_next.setText(QCoreApplication.translate("ConnectionConfigController", "Ok"))
 
     def init_name_page(self):
         """
@@ -135,7 +135,7 @@ class ConnectionConfigController(QObject):
                 ) as e:
                     self._logger.debug(str(e))
                     self.view.display_info(
-                        self.tr(
+                        QCoreApplication.translate("ConnectionConfigController",
                             "Could not connect. Check hostname, IP address or port: <br/>"
                             + str(e)
                         )
@@ -164,14 +164,14 @@ class ConnectionConfigController(QObject):
             connection_identity = await self.step_key
         elif self.mode == ConnectionConfigController.CONNECT:
             self._logger.debug("Connect mode")
-            self.view.button_next.setText(self.tr("Next"))
+            self.view.button_next.setText(QCoreApplication.translate("ConnectionConfigController", "Next"))
             self.view.groupbox_pubkey.hide()
             self.view.button_next.clicked.connect(self.check_connect)
             self.view.stacked_pages.setCurrentWidget(self.view.page_connection)
             connection_identity = await self.step_key
         elif self.mode == ConnectionConfigController.WALLET:
             self._logger.debug("Wallet mode")
-            self.view.button_next.setText(self.tr("Next"))
+            self.view.button_next.setText(QCoreApplication.translate("ConnectionConfigController", "Next"))
             self.view.button_next.clicked.connect(self.check_wallet)
             self.view.edit_uid.hide()
             self.view.label_action.hide()
@@ -180,11 +180,11 @@ class ConnectionConfigController(QObject):
             connection_identity = await self.step_key
         elif self.mode == ConnectionConfigController.PUBKEY:
             self._logger.debug("Pubkey mode")
-            self.view.button_next.setText(self.tr("Next"))
+            self.view.button_next.setText(QCoreApplication.translate("ConnectionConfigController", "Next"))
             self.view.button_next.clicked.connect(self.check_pubkey)
-            if not self.view.label_action.text().endswith(self.tr(" (Optional)")):
+            if not self.view.label_action.text().endswith(QCoreApplication.translate("ConnectionConfigController", " (Optional)")):
                 self.view.label_action.setText(
-                    self.view.label_action.text() + self.tr(" (Optional)")
+                    self.view.label_action.text() + QCoreApplication.translate("ConnectionConfigController", " (Optional)")
                 )
             self.view.groupbox_key.hide()
             self.view.stacked_pages.setCurrentWidget(self.view.page_connection)
@@ -194,7 +194,7 @@ class ConnectionConfigController(QObject):
         self.view.set_progress_steps(6)
         try:
             if self.mode == ConnectionConfigController.REGISTER:
-                self.view.display_info(self.tr("Broadcasting identity..."))
+                self.view.display_info(QCoreApplication.translate("ConnectionConfigController", "Broadcasting identity..."))
                 self.view.stream_log("Broadcasting identity...")
                 result = await self.model.publish_selfcert(connection_identity)
                 if result[0]:
@@ -279,45 +279,45 @@ class ConnectionConfigController(QObject):
     def check_key(self):
         if self.mode == ConnectionConfigController.PUBKEY:
             if len(self.view.edit_pubkey.text()) < 42:
-                self.view.label_info.setText(self.tr("Forbidden: pubkey is too short"))
+                self.view.label_info.setText(QCoreApplication.translate("ConnectionConfigController", "Forbidden: pubkey is too short"))
                 return False
             if len(self.view.edit_pubkey.text()) > 45:
-                self.view.label_info.setText(self.tr("Forbidden: pubkey is too long"))
+                self.view.label_info.setText(QCoreApplication.translate("ConnectionConfigController", "Forbidden: pubkey is too long"))
                 return False
         else:
             if self.view.edit_password.text() != self.view.edit_password_repeat.text():
-                self.view.label_info.setText(self.tr("Error: passwords are different"))
+                self.view.label_info.setText(QCoreApplication.translate("ConnectionConfigController", "Error: passwords are different"))
                 return False
 
             if self.view.edit_salt.text() != self.view.edit_salt_bis.text():
                 self.view.label_info.setText(
-                    self.tr("Error: salts are different")
+                    QCoreApplication.translate("ConnectionConfigController", "Error: salts are different")
                 )
                 return False
 
             if detect_non_printable(self.view.edit_salt.text()):
                 self.view.label_info.setText(
-                    self.tr("Forbidden: invalid characters in salt")
+                    QCoreApplication.translate("ConnectionConfigController", "Forbidden: invalid characters in salt")
                 )
                 return False
 
             if detect_non_printable(self.view.edit_password.text()):
                 self.view.label_info.setText(
-                    self.tr("Forbidden: invalid characters in password")
+                    QCoreApplication.translate("ConnectionConfigController", "Forbidden: invalid characters in password")
                 )
                 return False
 
             if self.model.app.parameters.expert_mode:
-                self.view.label_info.setText(self.tr(""))
+                self.view.label_info.setText(QCoreApplication.translate("ConnectionConfigController", ""))
                 return True
 
             if len(self.view.edit_salt.text()) < 6:
-                self.view.label_info.setText(self.tr("Forbidden: salt is too short"))
+                self.view.label_info.setText(QCoreApplication.translate("ConnectionConfigController", "Forbidden: salt is too short"))
                 return False
 
             if len(self.view.edit_password.text()) < 6:
                 self.view.label_info.setText(
-                    self.tr("Forbidden: password is too short")
+                    QCoreApplication.translate("ConnectionConfigController", "Forbidden: password is too short")
                 )
                 return False
 
@@ -329,10 +329,10 @@ class ConnectionConfigController(QObject):
         # Testable way of using a QFileDialog
         selected_files = await QAsyncFileDialog.get_save_filename(
             self.view,
-            self.tr("Save a revocation document"),
+            QCoreApplication.translate("ConnectionConfigController", "Save a revocation document"),
             "revocation-{uid}-{pubkey}-{currency}.txt".format(uid=identity.uid, pubkey=identity.pubkey[:8],
                                                               currency=identity.currency),
-            self.tr("All text files (*.txt)"),
+            QCoreApplication.translate("ConnectionConfigController", "All text files (*.txt)"),
         )
         if selected_files:
             path = selected_files[0]
@@ -343,8 +343,8 @@ class ConnectionConfigController(QObject):
 
             dialog = QMessageBox(
                 QMessageBox.Information,
-                self.tr("Revocation file"),
-                self.tr(
+                QCoreApplication.translate("ConnectionConfigController", "Revocation file"),
+                QCoreApplication.translate("ConnectionConfigController",
                     """<div>Your revocation document has been saved.</div>
 <div><b>Please keep it in a safe place.</b></div>
 The publication of this document will revoke your identity on the network.</p>"""
@@ -358,7 +358,7 @@ The publication of this document will revoke your identity on the network.</p>""
     @asyncify
     async def check_pubkey(self, checked=False):
         self._logger.debug("Is valid ? ")
-        self.view.display_info(self.tr("connecting..."))
+        self.view.display_info(QCoreApplication.translate("ConnectionConfigController", "connecting..."))
         self.view.button_next.setDisabled(True)
         try:
             self.model.set_pubkey(self.view.edit_pubkey.text(), self.view.scrypt_params)
@@ -371,11 +371,11 @@ The publication of this document will revoke your identity on the network.</p>""
                     if self.view.edit_uid.text():
                         if registered[0] is False and registered[2] is None:
                             self.view.display_info(
-                                self.tr("Could not find your identity on the network.")
+                                QCoreApplication.translate("ConnectionConfigController", "Could not find your identity on the network.")
                             )
                         elif registered[0] is False and registered[2]:
                             self.view.display_info(
-                                self.tr(
+                                QCoreApplication.translate("ConnectionConfigController",
                                     """Your pubkey or UID is different on the network.
 Yours: {0}, the network: {1}""".format(
                                         registered[1], registered[2]
@@ -395,18 +395,18 @@ Yours: {0}, the network: {1}""".format(
                     self.step_key.set_result(None)
             else:
                 self.view.display_info(
-                    self.tr("An account already exists using this key.")
+                    QCoreApplication.translate("ConnectionConfigController", "An account already exists using this key.")
                 )
 
         except NoPeerAvailable:
             self.config_dialog.label_error.setText(
-                self.tr("Could not connect. Check node peering entry")
+                QCoreApplication.translate("ConnectionConfigController", "Could not connect. Check node peering entry")
             )
 
     @asyncify
     async def check_wallet(self, checked=False):
         self._logger.debug("Is valid ? ")
-        self.view.display_info(self.tr("connecting..."))
+        self.view.display_info(QCoreApplication.translate("ConnectionConfigController", "connecting..."))
         try:
             salt = self.view.edit_salt.text()
             password = self.view.edit_password.text()
@@ -421,7 +421,7 @@ Yours: {0}, the network: {1}""".format(
                         self.step_key.set_result(None)
                     elif registered[2]:
                         self.view.display_info(
-                            self.tr(
+                            QCoreApplication.translate("ConnectionConfigController",
                                 """Your pubkey is associated to an identity.
 Yours: {0}, the network: {1}""".format(
                                     registered[1], registered[2]
@@ -434,18 +434,18 @@ Yours: {0}, the network: {1}""".format(
                     self.view.display_info(str(e))
             else:
                 self.view.display_info(
-                    self.tr("An account already exists using this key.")
+                    QCoreApplication.translate("ConnectionConfigController", "An account already exists using this key.")
                 )
 
         except NoPeerAvailable:
             self.config_dialog.label_error.setText(
-                self.tr("Could not connect. Check node peering entry")
+                QCoreApplication.translate("ConnectionConfigController", "Could not connect. Check node peering entry")
             )
 
     @asyncify
     async def check_connect(self, checked=False):
         self._logger.debug("Is valid ? ")
-        self.view.display_info(self.tr("connecting..."))
+        self.view.display_info(QCoreApplication.translate("ConnectionConfigController", "connecting..."))
         try:
             salt = self.view.edit_salt.text()
             password = self.view.edit_password.text()
@@ -458,11 +458,11 @@ Yours: {0}, the network: {1}""".format(
                     self.view.button_register.setEnabled(True)
                     if registered[0] is False and registered[2] is None:
                         self.view.display_info(
-                            self.tr("Could not find your identity on the network.")
+                            QCoreApplication.translate("ConnectionConfigController", "Could not find your identity on the network.")
                         )
                     elif registered[0] is False and registered[2]:
                         self.view.display_info(
-                            self.tr(
+                            QCoreApplication.translate("ConnectionConfigController",
                                 """Your pubkey or UID is different on the network.
         Yours: {0}, the network: {1}""".format(
                                     registered[1], registered[2]
@@ -477,18 +477,18 @@ Yours: {0}, the network: {1}""".format(
                     self.view.display_info(str(e))
             else:
                 self.view.display_info(
-                    self.tr("An account already exists using this key.")
+                    QCoreApplication.translate("ConnectionConfigController", "An account already exists using this key.")
                 )
 
         except NoPeerAvailable:
             self.config_dialog.label_error.setText(
-                self.tr("Could not connect. Check node peering entry")
+                QCoreApplication.translate("ConnectionConfigController", "Could not connect. Check node peering entry")
             )
 
     @asyncify
     async def check_register(self, checked=False):
         self._logger.debug("Is valid ? ")
-        self.view.display_info(self.tr("connecting..."))
+        self.view.display_info(QCoreApplication.translate("ConnectionConfigController", "connecting..."))
         try:
             salt = self.view.edit_salt.text()
             password = self.view.edit_password.text()
@@ -507,7 +507,7 @@ Yours: {0}, the network: {1}""".format(
                             )
                     elif registered[0] is False and registered[2]:
                         self.view.display_info(
-                            self.tr(
+                            QCoreApplication.translate("ConnectionConfigController",
                                 """Your pubkey or UID was already found on the network.
         Yours: {0}, the network: {1}""".format(
                                     registered[1], registered[2]
@@ -524,11 +524,11 @@ Yours: {0}, the network: {1}""".format(
                     self.view.display_info(str(e))
             else:
                 self.view.display_info(
-                    self.tr("An account already exists using this key.")
+                    QCoreApplication.translate("ConnectionConfigController", "An account already exists using this key.")
                 )
         except NoPeerAvailable:
             self.view.display_info(
-                self.tr("Could not connect. Check node peering entry")
+                QCoreApplication.translate("ConnectionConfigController", "Could not connect. Check node peering entry")
             )
 
     @asyncify
diff --git a/src/sakia/gui/dialogs/connection_cfg/view.py b/src/sakia/gui/dialogs/connection_cfg/view.py
index 710248a52e5055b55ea86a5021dcd10ed2e995e0..f4de8820cd228a0e2eb94340566b73ab9326bbb4 100644
--- a/src/sakia/gui/dialogs/connection_cfg/view.py
+++ b/src/sakia/gui/dialogs/connection_cfg/view.py
@@ -68,7 +68,7 @@ class ConnectionConfigView(QDialog, Ui_ConnectionConfigurationDialog):
         self.spin_p.blockSignals(False)
 
     def set_license(self, currency):
-        license_text = self.tr(G1_LICENSE)
+        license_text = QCoreApplication.translate("ConnectionConfigView", G1_LICENSE)
         self.text_license.setText(license_text)
 
     def handle_n_change(self, value):
@@ -120,19 +120,19 @@ class ConnectionConfigView(QDialog, Ui_ConnectionConfigurationDialog):
     async def show_success(self, notification):
         if notification:
             toast.display(
-                self.tr("UID broadcast"), self.tr("Identity broadcasted to the network")
+                QCoreApplication.translate("ConnectionConfigView", "UID broadcast"), QCoreApplication.translate("ConnectionConfigView", "Identity broadcasted to the network")
             )
         else:
             await QAsyncMessageBox.information(
                 self,
-                self.tr("UID broadcast"),
-                self.tr("Identity broadcasted to the network"),
+                QCoreApplication.translate("ConnectionConfigView", "UID broadcast"),
+                QCoreApplication.translate("ConnectionConfigView", "Identity broadcasted to the network"),
             )
 
     def show_error(self, notification, error_txt):
         if notification:
-            toast.display(self.tr("UID broadcast"), error_txt)
-        self.label_info.setText(self.tr("Error") + " " + error_txt)
+            toast.display(QCoreApplication.translate("ConnectionConfigView", "UID broadcast"), error_txt)
+        self.label_info.setText(QCoreApplication.translate("ConnectionConfigView", "Error") + " " + error_txt)
 
     def set_nodes_model(self, model):
         self.tree_peers.setModel(model)
@@ -142,7 +142,7 @@ class ConnectionConfigView(QDialog, Ui_ConnectionConfigurationDialog):
         Hide unecessary buttons and display correct title
         """
         self.setWindowTitle(
-            self.tr("New account on {0} network").format(
+            QCoreApplication.translate("ConnectionConfigView", "New account on {0} network").format(
                 ROOT_SERVERS[currency]["display"]
             )
         )
@@ -191,7 +191,7 @@ class ConnectionConfigView(QDialog, Ui_ConnectionConfigurationDialog):
                 QDateTime.fromTime_t(remaining).toUTC().toString("hh:mm:ss")
             )
             self.progress_bar.setFormat(
-                self.tr("{0} remaining...".format(displayed_remaining_time))
+                QCoreApplication.translate("ConnectionConfigView", "{0} remaining...".format(displayed_remaining_time))
             )
             self.progress_bar.setValue(next_value)
             self.timer.restart()
@@ -213,7 +213,7 @@ class ConnectionConfigView(QDialog, Ui_ConnectionConfigurationDialog):
         days, hours, minutes, seconds = timestamp_to_dhms(
             blockchain_parameters.idty_window
         )
-        expiration_time_str = self.tr("{days} days, {hours}h  and {min}min").format(
+        expiration_time_str = QCoreApplication.translate("ConnectionConfigView", "{days} days, {hours}h  and {min}min").format(
             days=days, hours=hours, min=minutes
         )
 
@@ -222,7 +222,7 @@ class ConnectionConfigView(QDialog, Ui_ConnectionConfigurationDialog):
         about_dialog.setupUi(dialog)
         dialog.setWindowTitle("Identity registration")
         about_dialog.label.setText(
-            self.tr(
+            QCoreApplication.translate("ConnectionConfigView",
                 """
 <p><b>Congratulations!</b><br>
 <br>
diff --git a/src/sakia/gui/dialogs/plugins_manager/controller.py b/src/sakia/gui/dialogs/plugins_manager/controller.py
index 3453fd7ccea8374b4079639dd63953293d1a8796..53bf26eb62e7d29de377f3f5843dab0fbd2a085e 100644
--- a/src/sakia/gui/dialogs/plugins_manager/controller.py
+++ b/src/sakia/gui/dialogs/plugins_manager/controller.py
@@ -1,7 +1,7 @@
 import asyncio
 
 from PyQt5.QtWidgets import QFileDialog
-from PyQt5.QtCore import QObject
+from PyQt5.QtCore import QObject, QCoreApplication
 from .model import PluginsManagerModel
 from .view import PluginsManagerView
 import attr
@@ -58,7 +58,7 @@ class PluginsManagerController(QObject):
     def install_plugin(self):
 
         filename = QFileDialog.getOpenFileName(
-            self.view, self.tr("Open File"), "", self.tr("Sakia module (*.zip)")
+            self.view, QCoreApplication.translate("PluginsManagerController", "Open File"), "", QCoreApplication.translate("PluginsManagerController", "Sakia module (*.zip)")
         )
         if filename[0]:
             self.model.install_plugin(filename[0])
diff --git a/src/sakia/gui/dialogs/plugins_manager/view.py b/src/sakia/gui/dialogs/plugins_manager/view.py
index 72febb801d787eb0057aa215da5a44e3b8ebdba0..acf7fac7b06978ee53115dcb937ae80c4ae6d387 100644
--- a/src/sakia/gui/dialogs/plugins_manager/view.py
+++ b/src/sakia/gui/dialogs/plugins_manager/view.py
@@ -1,5 +1,5 @@
 from PyQt5.QtWidgets import QDialog, QAbstractItemView, QHeaderView, QMessageBox
-from PyQt5.QtCore import QModelIndex
+from PyQt5.QtCore import QModelIndex, QCoreApplication
 from .plugins_manager_uic import Ui_PluginDialog
 
 
@@ -42,6 +42,6 @@ class PluginsManagerView(QDialog, Ui_PluginDialog):
     def show_error(self, error_txt):
         QMessageBox.critical(
             self,
-            self.tr("Plugin import"),
-            self.tr("Could not import plugin: {0}".format(error_txt)),
+            QCoreApplication.translate("PluginsManagerView", "Plugin import"),
+            QCoreApplication.translate("PluginsManagerView", "Could not import plugin: {0}".format(error_txt)),
         )
diff --git a/src/sakia/gui/dialogs/revocation/view.py b/src/sakia/gui/dialogs/revocation/view.py
index 20c800fb5fbe35a9d86998da98a507e5174bc2ea..c13116cc82b171e2b704950d921be8b0fc309f18 100644
--- a/src/sakia/gui/dialogs/revocation/view.py
+++ b/src/sakia/gui/dialogs/revocation/view.py
@@ -1,5 +1,6 @@
 from enum import Enum
 
+from PyQt5.QtCore import QCoreApplication
 from PyQt5.QtWidgets import QDialog, QFileDialog, QMessageBox
 
 from sakia.decorators import asyncify
@@ -45,13 +46,13 @@ class RevocationView(QDialog, Ui_RevocationDialog):
 
     def refresh_target(self):
         if self.radio_currency.isChecked():
-            target = self.tr(
+            target = QCoreApplication.translate("RevocationView",
                 "All nodes of currency {name}".format(
                     name=self.combo_currency.currentText()
                 )
             )
         elif self.radio_address.isChecked():
-            target = self.tr(
+            target = QCoreApplication.translate("RevocationView",
                 "Address {address}:{port}".format(
                     address=self.edit_address.text(), port=self.spinbox_port.value()
                 )
@@ -69,7 +70,7 @@ class RevocationView(QDialog, Ui_RevocationDialog):
 
     def refresh_revocation_label(self, revoked_identity):
         if revoked_identity:
-            text = self.tr(
+            text = QCoreApplication.translate("RevocationView",
                 """
 <div>Identity revoked: {uid} (public key: {pubkey}...)</div>
 <div>Identity signed on block: {timestamp}</div>
@@ -83,13 +84,13 @@ class RevocationView(QDialog, Ui_RevocationDialog):
             self.label_revocation_content.setText(text)
 
             if self.radio_currency.isChecked():
-                target = self.tr(
+                target = QCoreApplication.translate("RevocationView",
                     "All nodes of currency {name}".format(
                         name=self.combo_currency.currentText()
                     )
                 )
             elif self.radio_address.isChecked():
-                target = self.tr(
+                target = QCoreApplication.translate("RevocationView",
                     "Address {address}:{port}".format(
                         address=self.edit_address.text(), port=self.spinbox_port.value()
                     )
@@ -116,9 +117,9 @@ class RevocationView(QDialog, Ui_RevocationDialog):
         """
         selected_files = QFileDialog.getOpenFileName(
             self,
-            self.tr("Load a revocation file"),
+            QCoreApplication.translate("RevocationView", "Load a revocation file"),
             "",
-            self.tr("All text files (*.txt)"),
+            QCoreApplication.translate("RevocationView", "All text files (*.txt)"),
         )
         selected_file = selected_files[0]
         return selected_file
@@ -126,18 +127,18 @@ class RevocationView(QDialog, Ui_RevocationDialog):
     def malformed_file_error(self):
         QMessageBox.critical(
             self,
-            self.tr("Error loading document"),
-            self.tr("Loaded document is not a revocation document"),
+            QCoreApplication.translate("RevocationView", "Error loading document"),
+            QCoreApplication.translate("RevocationView", "Loaded document is not a revocation document"),
             buttons=QMessageBox.Ok,
         )
 
     async def revocation_broadcast_error(self, error):
         await QAsyncMessageBox.critical(
-            self, self.tr("Error broadcasting document"), error
+            self, QCoreApplication.translate("RevocationView", "Error broadcasting document"), error
         )
 
     def show_revoked_selfcert(self, selfcert):
-        text = self.tr(
+        text = QCoreApplication.translate("RevocationView",
             """
         <div>Identity revoked: {uid} (public key: {pubkey}...)</div>
         <div>Identity signed on block: {timestamp}</div>
@@ -158,8 +159,8 @@ class RevocationView(QDialog, Ui_RevocationDialog):
     def ask_for_confirmation(self):
         answer = QMessageBox.warning(
             self,
-            self.tr("Revocation"),
-            self.tr(
+            QCoreApplication.translate("RevocationView", "Revocation"),
+            QCoreApplication.translate("RevocationView",
                 """<h4>The publication of this document will revoke your identity on the network.</h4>
         <li>
             <li> <b>This identity won't be able to join the WoT anymore.</b> </li>
@@ -177,7 +178,7 @@ class RevocationView(QDialog, Ui_RevocationDialog):
     async def accept(self):
         await QAsyncMessageBox.information(
             self,
-            self.tr("Revocation broadcast"),
-            self.tr("The document was successfully broadcasted."),
+            QCoreApplication.translate("RevocationView", "Revocation broadcast"),
+            QCoreApplication.translate("RevocationView", "The document was successfully broadcasted."),
         )
         super().accept()
diff --git a/src/sakia/gui/main_window/controller.py b/src/sakia/gui/main_window/controller.py
index eed71422c76281940d6de6d43a8ccc0977c9cba1..4224c4910e15417e38341cb51944db0d1f6a38a9 100644
--- a/src/sakia/gui/main_window/controller.py
+++ b/src/sakia/gui/main_window/controller.py
@@ -1,6 +1,6 @@
 import logging
 
-from PyQt5.QtCore import QEvent, pyqtSlot, QObject
+from PyQt5.QtCore import QEvent, pyqtSlot, QObject, QCoreApplication
 from PyQt5.QtGui import QIcon
 from PyQt5.QtWidgets import QMessageBox, QApplication
 
@@ -108,7 +108,7 @@ class MainWindowController(QObject):
         latest = self.app.available_version
         logging.debug("Latest version requested")
         if not latest[0]:
-            version_info = self.tr("Please get the latest release {version}").format(
+            version_info = QCoreApplication.translate("MainWindowController", "Please get the latest release {version}").format(
                 version=latest[1]
             )
             version_url = latest[2]
@@ -130,7 +130,7 @@ class MainWindowController(QObject):
         self.status_bar.refresh()
         display_name = ROOT_SERVERS[currency]["display"]
         self.view.setWindowTitle(
-            self.tr("sakia {0} - {1}").format(__version__, display_name)
+            QCoreApplication.translate("MainWindowController", "sakia {0} - {1}").format(__version__, display_name)
         )
 
     def eventFilter(self, target, event):
diff --git a/src/sakia/gui/main_window/status_bar/controller.py b/src/sakia/gui/main_window/status_bar/controller.py
index 9edf30bd2d20e16af7d3a9011c1990402d45126c..80ab9ca8b2305177cf4d4bd15f4efab5bbfc8eb7 100644
--- a/src/sakia/gui/main_window/status_bar/controller.py
+++ b/src/sakia/gui/main_window/status_bar/controller.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import QLocale, pyqtSlot, QDateTime, QTimer, QObject
+from PyQt5.QtCore import QLocale, pyqtSlot, QDateTime, QTimer, QObject, QCoreApplication
 from .model import StatusBarModel
 from .view import StatusBarView
 from sakia.data.processors import BlockchainProcessor
@@ -74,7 +74,7 @@ class StatusBarController(QObject):
             QLocale.dateTimeFormat(QLocale(), QLocale.NarrowFormat),
         )
         self.view.status_label.setText(
-            self.tr("Blockchain sync: {0} BAT ({1})").format(
+            QCoreApplication.translate("StatusBarController", "Blockchain sync: {0} BAT ({1})").format(
                 str_time, str(current_block)[:15]
             )
         )
diff --git a/src/sakia/gui/main_window/toolbar/controller.py b/src/sakia/gui/main_window/toolbar/controller.py
index 0eb7f7b5cca3c6ce44d809e2a7819cf2c1903d65..c641d872ed2c96f0f388756e0c8756cd77a11166 100644
--- a/src/sakia/gui/main_window/toolbar/controller.py
+++ b/src/sakia/gui/main_window/toolbar/controller.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import QObject, pyqtSignal
+from PyQt5.QtCore import QObject, pyqtSignal, QCoreApplication
 from PyQt5.QtWidgets import QDialog
 from sakia.gui.dialogs.connection_cfg.controller import ConnectionConfigController
 from sakia.gui.dialogs.revocation.controller import RevocationController
@@ -111,10 +111,10 @@ class ToolbarController(QObject):
         :return:
         """
         self.action_publish_uid.setText(
-            self.tr(ToolbarController.action_publish_uid_text)
+            QCoreApplication.translate("ToolbarController", ToolbarController.action_publish_uid_text)
         )
         self.action_revoke_uid.setText(
-            self.tr(ToolbarController.action_revoke_uid_text)
+            QCoreApplication.translate("ToolbarController", ToolbarController.action_revoke_uid_text)
         )
-        self.action_showinfo.setText(self.tr(ToolbarController.action_showinfo_text))
+        self.action_showinfo.setText(QCoreApplication.translate("ToolbarController", ToolbarController.action_showinfo_text))
         super().retranslateUi(self)
diff --git a/src/sakia/gui/main_window/toolbar/view.py b/src/sakia/gui/main_window/toolbar/view.py
index 5f20fbc0b7b21d14a8709deff062b0e6c10cf5c9..71f737312d6ac1f517cd384e71ce9c2f5cd709a7 100644
--- a/src/sakia/gui/main_window/toolbar/view.py
+++ b/src/sakia/gui/main_window/toolbar/view.py
@@ -11,7 +11,7 @@ from PyQt5.QtWidgets import (
     QLabel,
 )
 from sakia.gui.widgets.dialogs import dialog_async_exec
-from PyQt5.QtCore import QObject, QT_TRANSLATE_NOOP, Qt, QLocale
+from PyQt5.QtCore import QObject, QT_TRANSLATE_NOOP, Qt, QLocale, QCoreApplication
 from .toolbar_uic import Ui_SakiaToolbar
 from .about_uic import Ui_AboutPopup
 from .about_money_uic import Ui_AboutMoney
@@ -32,43 +32,43 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
         super().__init__(parent)
         self.setupUi(self)
 
-        tool_menu = QMenu(self.tr("Tools"), self.toolbutton_menu)
+        tool_menu = QMenu(QCoreApplication.translate("ToolbarView", "Tools"), self.toolbutton_menu)
         self.toolbutton_menu.setMenu(tool_menu)
 
-        self.action_add_connection = QAction(self.tr("Add an Sakia account"), tool_menu)
+        self.action_add_connection = QAction(QCoreApplication.translate("ToolbarView", "Add an Sakia account"), tool_menu)
         tool_menu.addAction(self.action_add_connection)
 
         self.action_revoke_uid = QAction(
-            self.tr(ToolbarView._action_revoke_uid_text), self
+            QCoreApplication.translate("ToolbarView", ToolbarView._action_revoke_uid_text), self
         )
         tool_menu.addAction(self.action_revoke_uid)
 
-        self.action_parameters = QAction(self.tr("Settings"), tool_menu)
+        self.action_parameters = QAction(QCoreApplication.translate("ToolbarView", "Settings"), tool_menu)
         tool_menu.addAction(self.action_parameters)
 
-        self.action_plugins = QAction(self.tr("Plugins manager"), tool_menu)
+        self.action_plugins = QAction(QCoreApplication.translate("ToolbarView", "Plugins manager"), tool_menu)
         tool_menu.addAction(self.action_plugins)
 
         tool_menu.addSeparator()
 
-        about_menu = QMenu(self.tr("About"), tool_menu)
+        about_menu = QMenu(QCoreApplication.translate("ToolbarView", "About"), tool_menu)
         tool_menu.addMenu(about_menu)
 
-        self.action_about_money = QAction(self.tr("About Money"), about_menu)
+        self.action_about_money = QAction(QCoreApplication.translate("ToolbarView", "About Money"), about_menu)
         about_menu.addAction(self.action_about_money)
 
         self.action_about_referentials = QAction(
-            self.tr("About Referentials"), about_menu
+            QCoreApplication.translate("ToolbarView", "About Referentials"), about_menu
         )
         about_menu.addAction(self.action_about_referentials)
 
-        self.action_about_wot = QAction(self.tr("About Web of Trust"), about_menu)
+        self.action_about_wot = QAction(QCoreApplication.translate("ToolbarView", "About Web of Trust"), about_menu)
         about_menu.addAction(self.action_about_wot)
 
-        self.action_about = QAction(self.tr("About Sakia"), about_menu)
+        self.action_about = QAction(QCoreApplication.translate("ToolbarView", "About Sakia"), about_menu)
         about_menu.addAction(self.action_about)
 
-        self.action_exit = QAction(self.tr("Quit"), tool_menu)
+        self.action_exit = QAction(QCoreApplication.translate("ToolbarView", "Quit"), tool_menu)
         tool_menu.addAction(self.action_exit)
 
         self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Minimum)
@@ -98,8 +98,8 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
         connections_titles = [c.title() for c in connections]
         input_dialog = QInputDialog()
         input_dialog.setComboBoxItems(connections_titles)
-        input_dialog.setWindowTitle(self.tr("Membership"))
-        input_dialog.setLabelText(self.tr("Select an account"))
+        input_dialog.setWindowTitle(QCoreApplication.translate("ToolbarView", "Membership"))
+        input_dialog.setLabelText(QCoreApplication.translate("ToolbarView", "Select an account"))
         await dialog_async_exec(input_dialog)
         result = input_dialog.textValue()
 
@@ -120,7 +120,7 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
 
         # set infos in label
         about_dialog.label_wot.setText(
-            self.tr(
+            QCoreApplication.translate("ToolbarView",
                 """
             <table cellpadding="5">
 <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
@@ -135,28 +135,28 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
 """
             ).format(
                 QLocale().toString(params.sig_period / 86400, "f", 2),
-                self.tr("Minimum delay between 2 certifications (days)"),
+                QCoreApplication.translate("ToolbarView", "Minimum delay between 2 certifications (days)"),
                 QLocale().toString(params.sig_validity / 86400, "f", 2),
-                self.tr("Maximum validity time of a certification (days)"),
+                QCoreApplication.translate("ToolbarView", "Maximum validity time of a certification (days)"),
                 params.sig_qty,
-                self.tr("Minimum quantity of certifications to be part of the WoT"),
+                QCoreApplication.translate("ToolbarView", "Minimum quantity of certifications to be part of the WoT"),
                 params.sig_stock,
-                self.tr("Maximum quantity of active certifications per member"),
+                QCoreApplication.translate("ToolbarView", "Maximum quantity of active certifications per member"),
                 QLocale().toString(params.sig_window / 86400, "f", 2),
-                self.tr(
+                QCoreApplication.translate("ToolbarView",
                     "Maximum time a certification can wait before being in blockchain (days)"
                 ),
                 params.xpercent * 100,
-                self.tr(
+                QCoreApplication.translate("ToolbarView",
                     "Minimum percent of sentries to reach to match the distance rule"
                 ),
                 params.ms_validity / 86400,
-                self.tr("Maximum validity time of a membership (days)"),
+                QCoreApplication.translate("ToolbarView", "Maximum validity time of a membership (days)"),
                 params.step_max,
-                self.tr("Maximum distance between each WoT member and a newcomer"),
+                QCoreApplication.translate("ToolbarView", "Maximum distance between each WoT member and a newcomer"),
             )
         )
-        dialog.setWindowTitle(self.tr("Web of Trust rules"))
+        dialog.setWindowTitle(QCoreApplication.translate("ToolbarView", "Web of Trust rules"))
         dialog.exec()
 
     def show_about_money(self, params, currency, localized_data):
@@ -166,7 +166,7 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
         about_dialog.label_general.setText(self.general_text(localized_data))
         about_dialog.label_rules.setText(self.rules_text(localized_data))
         about_dialog.label_money.setText(self.money_text(params, currency))
-        dialog.setWindowTitle(self.tr("Money rules"))
+        dialog.setWindowTitle(QCoreApplication.translate("ToolbarView", "Money rules"))
         dialog.exec()
 
     def show_about_referentials(self, referentials):
@@ -181,7 +181,7 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
             label.setText(self.text_referential(ref))
             layout.addWidget(label)
             tabwidget.addTab(widget, ref.translated_name())
-        dialog.setWindowTitle(self.tr("Referentials"))
+        dialog.setWindowTitle(QCoreApplication.translate("ToolbarView", "Referentials"))
         dialog.exec()
 
     def general_text(self, localized_data):
@@ -190,7 +190,7 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
         :return:
         """
         # set infos in label
-        return self.tr(
+        return QCoreApplication.translate("ToolbarView",
             """
             <table cellpadding="5">
             <tr><td align="right"><b>{:}</b></div></td><td>{:} {:}</td></tr>
@@ -205,28 +205,28 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
             """
         ).format(
             localized_data.get("ud", "####"),
-            self.tr("Universal Dividend UD(t) in"),
+            QCoreApplication.translate("ToolbarView", "Universal Dividend UD(t) in"),
             localized_data["diff_units"],
             localized_data.get("mass", "###"),
-            self.tr("Monetary Mass M(t) in"),
+            QCoreApplication.translate("ToolbarView", "Monetary Mass M(t) in"),
             localized_data["units"],
             localized_data.get("members_count", "####"),
-            self.tr("Members N(t)"),
+            QCoreApplication.translate("ToolbarView", "Members N(t)"),
             localized_data.get("mass_per_member", "####"),
-            self.tr("Monetary Mass per member M(t)/N(t) in"),
+            QCoreApplication.translate("ToolbarView", "Monetary Mass per member M(t)/N(t) in"),
             localized_data["diff_units"],
             localized_data.get("actual_growth", 0),
-            self.tr("day"),
-            self.tr("Actual growth c = UD(t)/[M(t)/N(t)]"),
+            QCoreApplication.translate("ToolbarView", "day"),
+            QCoreApplication.translate("ToolbarView", "Actual growth c = UD(t)/[M(t)/N(t)]"),
             # todo: wait for accurate datetime of reevaluation
             # localized_data.get("ud_median_time_minus_1", "####"),
-            # self.tr("Penultimate UD date and time (t-1)"),
+            # QCoreApplication.translate("ToolbarView", "Penultimate UD date and time (t-1)"),
             localized_data.get("ud_median_time", "####") + " BAT",
-            self.tr("Last UD date and time (t)"),
+            QCoreApplication.translate("ToolbarView", "Last UD date and time (t)"),
             localized_data.get("next_ud_median_time", "####") + " BAT",
-            self.tr("Next UD date and time (t+1)"),
+            QCoreApplication.translate("ToolbarView", "Next UD date and time (t+1)"),
             localized_data.get("next_ud_reeval", "####") + " BAT",
-            self.tr("Next UD reevaluation (t+1)"),
+            QCoreApplication.translate("ToolbarView", "Next UD reevaluation (t+1)"),
         )
 
     def rules_text(self, localized_data):
@@ -236,7 +236,7 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
         :return:
         """
         # set infos in label
-        return self.tr(
+        return QCoreApplication.translate("ToolbarView",
             """
             <table cellpadding="5">
             <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
@@ -244,22 +244,22 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
             </table>
             """
         ).format(
-            self.tr("{:2.2%} / {:} days").format(
+            QCoreApplication.translate("ToolbarView", "{:2.2%} / {:} days").format(
                 localized_data["growth"], localized_data["dt_reeval_in_days"]
             ),
-            self.tr("Fundamental growth (c) / Reevaluation delta time (dt_reeval)"),
-            self.tr("UDĞ(t) = UDĞ(t-1) + c²*M(t-1)/N(t)"),
-            self.tr("Universal Dividend (formula)"),
+            QCoreApplication.translate("ToolbarView", "Fundamental growth (c) / Reevaluation delta time (dt_reeval)"),
+            QCoreApplication.translate("ToolbarView", "UDĞ(t) = UDĞ(t-1) + c²*M(t-1)/N(t)"),
+            QCoreApplication.translate("ToolbarView", "Universal Dividend (formula)"),
             # fixme: re-display when the computed dividend will be accurate (need accurate previous monetary mass,
             #  last mass just before reevaluation)
-            # self.tr("{:} = {:} + {:}² * {:} / {:}").format(
+            # QCoreApplication.translate("ToolbarView", "{:} = {:} + {:}² * {:} / {:}").format(
             #     localized_data.get("ud_plus_1", "####"),
             #     localized_data.get("ud", "####"),
             #     localized_data.get("growth_per_dt", "##########"),
             #     localized_data.get("mass", "####"),
             #     localized_data.get("members_count", "####"),
             # ),
-            # self.tr("Universal Dividend (computed)"),
+            # QCoreApplication.translate("ToolbarView", "Universal Dividend (computed)"),
         )
 
     def text_referential(self, ref):
@@ -276,13 +276,13 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
                 </table>
                 """
         return ref_template.format(
-            self.tr("Name"),
+            QCoreApplication.translate("ToolbarView", "Name"),
             ref.translated_name(),
-            self.tr("Units"),
+            QCoreApplication.translate("ToolbarView", "Units"),
             ref.units,
-            self.tr("Formula"),
+            QCoreApplication.translate("ToolbarView", "Formula"),
             ref.formula,
-            self.tr("Description"),
+            QCoreApplication.translate("ToolbarView", "Description"),
             ref.description,
         )
 
@@ -295,16 +295,16 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
 
         dt_dhms = timestamp_to_dhms(params.dt)
         if dt_dhms[0] > 0:
-            dt_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_dhms)
+            dt_as_str = QCoreApplication.translate("ToolbarView", "{:} day(s) {:} hour(s)").format(*dt_dhms)
         else:
-            dt_as_str = self.tr("{:} hour(s)").format(dt_dhms[1])
+            dt_as_str = QCoreApplication.translate("ToolbarView", "{:} hour(s)").format(dt_dhms[1])
         if dt_dhms[2] > 0 or dt_dhms[3] > 0:
             dt_dhms += ", {:} minute(s) and {:} second(s)".format(*dt_dhms[1:])
         dt_reeval_dhms = timestamp_to_dhms(params.dt_reeval)
-        dt_reeval_as_str = self.tr("{:} day(s) {:} hour(s)").format(*dt_reeval_dhms)
+        dt_reeval_as_str = QCoreApplication.translate("ToolbarView", "{:} day(s) {:} hour(s)").format(*dt_reeval_dhms)
 
         # set infos in label
-        return self.tr(
+        return QCoreApplication.translate("ToolbarView",
             """
             <table cellpadding="5">
             <tr><td align="right"><b>{:2.2%}</b></td><td>{:}</td></tr>
@@ -319,22 +319,22 @@ class ToolbarView(QFrame, Ui_SakiaToolbar):
             """
         ).format(
             params.c,
-            self.tr("Fundamental growth (c)"),
+            QCoreApplication.translate("ToolbarView", "Fundamental growth (c)"),
             params.ud0,
-            self.tr("Initial Universal Dividend UD(0) in"),
+            QCoreApplication.translate("ToolbarView", "Initial Universal Dividend UD(0) in"),
             currency,
             dt_as_str,
-            self.tr("Time period between two UD"),
+            QCoreApplication.translate("ToolbarView", "Time period between two UD"),
             dt_reeval_as_str,
-            self.tr("Time period between two UD reevaluation"),
+            QCoreApplication.translate("ToolbarView", "Time period between two UD reevaluation"),
             params.median_time_blocks,
-            self.tr("Number of blocks used for calculating median time"),
+            QCoreApplication.translate("ToolbarView", "Number of blocks used for calculating median time"),
             params.avg_gen_time,
-            self.tr("The average time in seconds for writing 1 block (wished time)"),
+            QCoreApplication.translate("ToolbarView", "The average time in seconds for writing 1 block (wished time)"),
             params.dt_diff_eval,
-            self.tr("The number of blocks required to evaluate again PoWMin value"),
+            QCoreApplication.translate("ToolbarView", "The number of blocks required to evaluate again PoWMin value"),
             params.percent_rot,
-            self.tr(
+            QCoreApplication.translate("ToolbarView",
                 "The percent of previous issuers to reach for personalized difficulty"
             ),
         )
diff --git a/src/sakia/gui/navigation/controller.py b/src/sakia/gui/navigation/controller.py
index 130c34aee656da2b51f1e3f50f3d379b5b8bec68..14e9475b1339e060be2967c5cd99fa77c69d4f9e 100644
--- a/src/sakia/gui/navigation/controller.py
+++ b/src/sakia/gui/navigation/controller.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import pyqtSignal, QObject, Qt
+from PyQt5.QtCore import pyqtSignal, QObject, Qt, QCoreApplication
 from PyQt5.QtGui import QCursor
 from PyQt5.QtWidgets import QMenu, QAction, QMessageBox
 
@@ -153,14 +153,14 @@ class NavigationController(QObject):
         if raw_data:
             menu = QMenu(self.view)
             if raw_data["misc"]["connection"].uid:
-                action_view_in_wot = QAction(self.tr("View in Web of Trust"), menu)
+                action_view_in_wot = QAction(QCoreApplication.translate("NavigationController", "View in Web of Trust"), menu)
                 menu.addAction(action_view_in_wot)
                 action_view_in_wot.triggered.connect(
                     lambda c: self.model.view_in_wot(raw_data["misc"]["connection"])
                 )
 
                 action_gen_revocation = QAction(
-                    self.tr("Save revocation document"), menu
+                    QCoreApplication.translate("NavigationController", "Save revocation document"), menu
                 )
                 menu.addAction(action_gen_revocation)
                 action_gen_revocation.triggered.connect(
@@ -169,7 +169,7 @@ class NavigationController(QObject):
                     )
                 )
 
-                action_publish_uid = QAction(self.tr("Publish UID"), menu)
+                action_publish_uid = QAction(QCoreApplication.translate("NavigationController", "Publish UID"), menu)
                 menu.addAction(action_publish_uid)
                 action_publish_uid.triggered.connect(
                     lambda c: self.publish_uid(raw_data["misc"]["connection"])
@@ -180,7 +180,7 @@ class NavigationController(QObject):
                 action_publish_uid.setEnabled(not identity_published)
 
                 action_export_identity = QAction(
-                    self.tr("Export identity document"), menu
+                    QCoreApplication.translate("NavigationController", "Export identity document"), menu
                 )
                 menu.addAction(action_export_identity)
                 action_export_identity.triggered.connect(
@@ -189,7 +189,7 @@ class NavigationController(QObject):
                     )
                 )
 
-                action_leave = QAction(self.tr("Leave the currency"), menu)
+                action_leave = QAction(QCoreApplication.translate("NavigationController", "Leave the currency"), menu)
                 menu.addAction(action_leave)
                 action_leave.triggered.connect(
                     lambda c: self.send_leave(raw_data["misc"]["connection"])
@@ -198,7 +198,7 @@ class NavigationController(QObject):
                     self.model.identity_is_member(raw_data["misc"]["connection"])
                 )
 
-            copy_pubkey = QAction(menu.tr("Copy pubkey to clipboard"), menu.parent())
+            copy_pubkey = QAction(QCoreApplication.translate("NavigationController", "Copy pubkey to clipboard"), menu.parent())
             copy_pubkey.triggered.connect(
                 lambda checked, c=raw_data["misc"][
                     "connection"
@@ -207,7 +207,7 @@ class NavigationController(QObject):
             menu.addAction(copy_pubkey)
 
             copy_pubkey_crc = QAction(
-                menu.tr("Copy pubkey to clipboard (with CRC)"), menu.parent()
+                QCoreApplication.translate("NavigationController", "Copy pubkey to clipboard (with CRC)"), menu.parent()
             )
             copy_pubkey_crc.triggered.connect(
                 lambda checked, c=raw_data["misc"][
@@ -216,7 +216,7 @@ class NavigationController(QObject):
             )
             menu.addAction(copy_pubkey_crc)
 
-            action_remove = QAction(self.tr("Remove the Sakia account"), menu)
+            action_remove = QAction(QCoreApplication.translate("NavigationController", "Remove the Sakia account"), menu)
             menu.addAction(action_remove)
             action_remove.triggered.connect(
                 lambda c: self.remove_connection(raw_data["misc"]["connection"])
@@ -243,23 +243,23 @@ class NavigationController(QObject):
         result = await self.model.send_identity(connection, identity_doc)
         if result[0]:
             if self.model.notifications():
-                toast.display(self.tr("UID"), self.tr("Success publishing your UID"))
+                toast.display(QCoreApplication.translate("NavigationController", "UID"), QCoreApplication.translate("NavigationController", "Success publishing your UID"))
             else:
                 await QAsyncMessageBox.information(
-                    self.view, self.tr("UID"), self.tr("Success publishing your UID")
+                    self.view, QCoreApplication.translate("NavigationController", "UID"), QCoreApplication.translate("NavigationController", "Success publishing your UID")
                 )
         else:
             if not self.model.notifications():
-                toast.display(self.tr("UID"), result[1])
+                toast.display(QCoreApplication.translate("NavigationController", "UID"), result[1])
             else:
-                await QAsyncMessageBox.critical(self.view, self.tr("UID"), result[1])
+                await QAsyncMessageBox.critical(self.view, QCoreApplication.translate("NavigationController", "UID"), result[1])
 
     @asyncify
     async def send_leave(self):
         reply = await QAsyncMessageBox.warning(
             self,
-            self.tr("Warning"),
-            self.tr(
+            QCoreApplication.translate("NavigationController", "Warning"),
+            QCoreApplication.translate("NavigationController",
                 """Are you sure?
 Sending a leaving demand  cannot be canceled.
 The process to join back the community later will have to be done again."""
@@ -277,26 +277,26 @@ The process to join back the community later will have to be done again."""
             if result[0]:
                 if self.app.preferences["notifications"]:
                     toast.display(
-                        self.tr("Revoke"), self.tr("Success sending Revoke demand")
+                        QCoreApplication.translate("NavigationController", "Revoke"), QCoreApplication.translate("NavigationController", "Success sending Revoke demand")
                     )
                 else:
                     await QAsyncMessageBox.information(
                         self,
-                        self.tr("Revoke"),
-                        self.tr("Success sending Revoke demand"),
+                        QCoreApplication.translate("NavigationController", "Revoke"),
+                        QCoreApplication.translate("NavigationController", "Success sending Revoke demand"),
                     )
             else:
                 if self.app.preferences["notifications"]:
-                    toast.display(self.tr("Revoke"), result[1])
+                    toast.display(QCoreApplication.translate("NavigationController", "Revoke"), result[1])
                 else:
-                    await QAsyncMessageBox.critical(self, self.tr("Revoke"), result[1])
+                    await QAsyncMessageBox.critical(self, QCoreApplication.translate("NavigationController", "Revoke"), result[1])
 
     @asyncify
     async def remove_connection(self, connection):
         reply = await QAsyncMessageBox.question(
             self.view,
-            self.tr("Removing the Sakia account"),
-            self.tr(
+            QCoreApplication.translate("NavigationController", "Removing the Sakia account"),
+            QCoreApplication.translate("NavigationController",
                 """Are you sure? This won't remove your money
  neither your identity from the network."""
             ),
@@ -320,10 +320,10 @@ The process to join back the community later will have to be done again."""
         # Testable way of using a QFileDialog
         selected_files = await QAsyncFileDialog.get_save_filename(
             self.view,
-            self.tr("Save a revocation document"),
+            QCoreApplication.translate("NavigationController", "Save a revocation document"),
             "revocation-{uid}-{pubkey}-{currency}.txt".format(uid=connection.uid, pubkey=connection.pubkey[:8],
                                                               currency=connection.currency),
-            self.tr("All text files (*.txt)"),
+            QCoreApplication.translate("NavigationController", "All text files (*.txt)"),
         )
         if selected_files:
             path = selected_files[0]
@@ -334,8 +334,8 @@ The process to join back the community later will have to be done again."""
 
             dialog = QMessageBox(
                 QMessageBox.Information,
-                self.tr("Revocation file"),
-                self.tr(
+                QCoreApplication.translate("NavigationController", "Revocation file"),
+                QCoreApplication.translate("NavigationController",
                     """<div>Your revocation document has been saved.</div>
 <div><b>Please keep it in a safe place.</b></div>
 The publication of this document will revoke your identity on the network.</p>"""
@@ -362,10 +362,10 @@ The publication of this document will revoke your identity on the network.</p>""
 
         selected_files = await QAsyncFileDialog.get_save_filename(
             self.view,
-            self.tr("Save an identity document"),
+            QCoreApplication.translate("NavigationController", "Save an identity document"),
             "identity-{uid}-{pubkey}-{currency}.txt".format(uid=connection.uid, pubkey=connection.pubkey[:8],
                                                             currency=connection.currency),
-            self.tr("All text files (*.txt)"),
+            QCoreApplication.translate("NavigationController", "All text files (*.txt)"),
         )
         if selected_files:
             path = selected_files[0]
@@ -376,8 +376,8 @@ The publication of this document will revoke your identity on the network.</p>""
 
             dialog = QMessageBox(
                 QMessageBox.Information,
-                self.tr("Identity file"),
-                self.tr(
+                QCoreApplication.translate("NavigationController", "Identity file"),
+                QCoreApplication.translate("NavigationController",
                     """<div>Your identity document has been saved.</div>
 Share this document to your friends for them to certify you.</p>"""
                 ),
diff --git a/src/sakia/gui/navigation/identities/view.py b/src/sakia/gui/navigation/identities/view.py
index f0a783d5a1bf67ce42f6e7b6f3a4e39937faf596..466081c833e1a0ed73284e569e8044a3f83afcb2 100644
--- a/src/sakia/gui/navigation/identities/view.py
+++ b/src/sakia/gui/navigation/identities/view.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import pyqtSignal, QT_TRANSLATE_NOOP, Qt, QEvent
+from PyQt5.QtCore import pyqtSignal, QT_TRANSLATE_NOOP, Qt, QEvent, QCoreApplication
 from PyQt5.QtWidgets import QWidget, QAbstractItemView, QAction
 from .identities_uic import Ui_IdentitiesWidget
 
@@ -24,7 +24,7 @@ class IdentitiesView(QWidget, Ui_IdentitiesWidget):
         super().__init__(parent)
 
         self.direct_connections = QAction(
-            self.tr(IdentitiesView._direct_connections_text), self
+            QCoreApplication.translate("IdentitiesView", IdentitiesView._direct_connections_text), self
         )
         self.direct_connections.triggered.connect(
             self.request_search_direct_connections
@@ -35,7 +35,7 @@ class IdentitiesView(QWidget, Ui_IdentitiesWidget):
         self.table_identities.sortByColumn(0, Qt.AscendingOrder)
         self.table_identities.resizeColumnsToContents()
         self.edit_textsearch.setPlaceholderText(
-            self.tr(IdentitiesView._search_placeholder)
+            QCoreApplication.translate("IdentitiesView", IdentitiesView._search_placeholder)
         )
         self.edit_textsearch.returnPressed.connect(self.request_search_by_text)
         # fixme: as it is this menu can not work because the current connection is missing.
@@ -67,13 +67,13 @@ class IdentitiesView(QWidget, Ui_IdentitiesWidget):
         Search members of community and display found members
         """
         self.edit_textsearch.setPlaceholderText(
-            self.tr(IdentitiesView._search_placeholder)
+            QCoreApplication.translate("IdentitiesView", IdentitiesView._search_placeholder)
         )
         self.search_directly_connected_requested.emit()
 
     def retranslateUi(self, widget):
         self.direct_connections.setText(
-            self.tr(IdentitiesView._direct_connections_text)
+            QCoreApplication.translate("IdentitiesView", IdentitiesView._direct_connections_text)
         )
         super().retranslateUi(self)
 
diff --git a/src/sakia/gui/navigation/identity/controller.py b/src/sakia/gui/navigation/identity/controller.py
index 8546540a0702bfcb6f23cb5904e1a1cca4ee8135..4e1e225f89b00d73f8a8d291961d436804d525aa 100644
--- a/src/sakia/gui/navigation/identity/controller.py
+++ b/src/sakia/gui/navigation/identity/controller.py
@@ -2,7 +2,7 @@ import logging
 
 from PyQt5.QtGui import QCursor
 from PyQt5.QtWidgets import QAction
-from PyQt5.QtCore import QObject, pyqtSignal
+from PyQt5.QtCore import QObject, pyqtSignal, QCoreApplication
 from sakia.errors import NoPeerAvailable
 from sakia.constants import ROOT_SERVERS
 from sakia.data.entities import Identity
@@ -169,18 +169,18 @@ class IdentityController(QObject):
         if result[0]:
             if self.model.notifications():
                 toast.display(
-                    self.tr("Membership"), self.tr("Success sending Membership demand")
+                    QCoreApplication.translate("IdentityController", "Membership"), QCoreApplication.translate("IdentityController", "Success sending Membership demand")
                 )
             else:
                 await QAsyncMessageBox.information(
                     self.view,
-                    self.tr("Membership"),
-                    self.tr("Success sending Membership demand"),
+                    QCoreApplication.translate("IdentityController", "Membership"),
+                    QCoreApplication.translate("IdentityController", "Success sending Membership demand"),
                 )
         else:
             if self.model.notifications():
-                toast.display(self.tr("Membership"), result[1])
+                toast.display(QCoreApplication.translate("IdentityController", "Membership"), result[1])
             else:
                 await QAsyncMessageBox.critical(
-                    self.view, self.tr("Membership"), result[1]
+                    self.view, QCoreApplication.translate("IdentityController", "Membership"), result[1]
                 )
diff --git a/src/sakia/gui/navigation/identity/model.py b/src/sakia/gui/navigation/identity/model.py
index 23cb3b7e7838421c665df6d265f6aff293daa363..4339fd71805a8e0021056336df3c5fa4e77934ae 100644
--- a/src/sakia/gui/navigation/identity/model.py
+++ b/src/sakia/gui/navigation/identity/model.py
@@ -1,7 +1,7 @@
 import logging
 import math
 
-from PyQt5.QtCore import QLocale, QDateTime, pyqtSignal, QObject, QModelIndex, Qt
+from PyQt5.QtCore import QLocale, QDateTime, pyqtSignal, QObject, QModelIndex, Qt, QCoreApplication
 from sakia.errors import NoPeerAvailable
 from sakia.constants import ROOT_SERVERS
 from .table_model import CertifiersTableModel, CertifiersFilterProxyModel
@@ -204,7 +204,7 @@ class IdentityModel(QObject):
         localized_amount = self.app.current_ref.instance(
             amount, self.connection.currency, self.app
         ).localized(False, True)
-        outdistanced_text = self.tr("Outdistanced")
+        outdistanced_text = QCoreApplication.translate("IdentityModel", "Outdistanced")
         is_identity = False
         written = False
         is_member = False
@@ -243,7 +243,7 @@ class IdentityModel(QObject):
                         self.identities_service.certifications_received(identity.pubkey)
                     )
                     if not identity.outdistanced:
-                        outdistanced_text = self.tr("In WoT range")
+                        outdistanced_text = QCoreApplication.translate("IdentityModel", "In WoT range")
             except errors.DuniterError as e:
                 if e.ucode == errors.NO_MEMBER_MATCHING_PUB_OR_UID:
                     pass
diff --git a/src/sakia/gui/navigation/model.py b/src/sakia/gui/navigation/model.py
index 4a54fdd50f2fcfad45dc898f4c89b8e2314ea908..1aa421e46eac73e26fd5a92f2a8770b0a075f91d 100644
--- a/src/sakia/gui/navigation/model.py
+++ b/src/sakia/gui/navigation/model.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import QObject, pyqtSignal
+from PyQt5.QtCore import QObject, pyqtSignal, QCoreApplication
 from PyQt5.QtWidgets import QApplication
 from sakia.models.generic_tree import GenericTreeModel
 from sakia.data.processors import ContactsProcessor
@@ -39,7 +39,7 @@ class NavigationModel(QObject):
     def init_navigation_data(self):
         self.navigation = [
             {
-                "title": self.tr("Network"),
+                "title": QCoreApplication.translate("NavigationModel", "Network"),
                 "icon": ":/icons/network_icon",
                 "component": "Network",
                 "dependencies": {"network_service": self.app.network_service,},
@@ -47,7 +47,7 @@ class NavigationModel(QObject):
                 "children": [],
             },
             {
-                "title": self.tr("Identities"),
+                "title": QCoreApplication.translate("NavigationModel", "Identities"),
                 "icon": ":/icons/members_icon",
                 "component": "Identities",
                 "dependencies": {
@@ -57,7 +57,7 @@ class NavigationModel(QObject):
                 "misc": {},
             },
             {
-                "title": self.tr("Web of Trust"),
+                "title": QCoreApplication.translate("NavigationModel", "Web of Trust"),
                 "icon": ":/icons/wot_icon",
                 "component": "Wot",
                 "dependencies": {
@@ -66,7 +66,7 @@ class NavigationModel(QObject):
                 },
                 "misc": {},
             },
-            {"title": self.tr("Personal accounts"), "children": []},
+            {"title": QCoreApplication.translate("NavigationModel", "Personal accounts"), "children": []},
         ]
 
         self._current_data = self.navigation[0]
@@ -98,7 +98,7 @@ class NavigationModel(QObject):
                 "misc": {"connection": connection},
                 "children": [
                     {
-                        "title": self.tr("Transfers"),
+                        "title": QCoreApplication.translate("NavigationModel", "Transfers"),
                         "icon": ":/icons/tx_icon",
                         "component": "TxHistory",
                         "dependencies": {
diff --git a/src/sakia/gui/navigation/network/controller.py b/src/sakia/gui/navigation/network/controller.py
index c0083286be5e74af0fec8cb6e7aa266b5360a260..4c1b8fb6b4a5744d3e17f4e3201ed53fb4b506b4 100644
--- a/src/sakia/gui/navigation/network/controller.py
+++ b/src/sakia/gui/navigation/network/controller.py
@@ -2,7 +2,7 @@ from .model import NetworkModel
 from .view import NetworkView
 from PyQt5.QtWidgets import QAction, QMenu
 from PyQt5.QtGui import QCursor, QDesktopServices
-from PyQt5.QtCore import pyqtSlot, QUrl, QObject
+from PyQt5.QtCore import pyqtSlot, QUrl, QObject, QCoreApplication
 from duniterpy.api import bma
 from duniterpy.api.endpoint import BMAEndpoint
 
@@ -52,7 +52,7 @@ class NetworkController(QObject):
         valid, node = self.model.table_model_data(index)
         if self.model.app.parameters.expert_mode:
             menu = QMenu()
-            open_in_browser = QAction(self.tr("Open in browser"), self)
+            open_in_browser = QAction(QCoreApplication.translate("NetworkController", "Open in browser"), self)
             open_in_browser.triggered.connect(self.open_node_in_browser)
             open_in_browser.setData(node)
             menu.addAction(open_in_browser)
diff --git a/src/sakia/gui/navigation/txhistory/controller.py b/src/sakia/gui/navigation/txhistory/controller.py
index e52965be7245aa29e143f3c0a275214c1e2e2613..0aafae4bf2a885869e5864df4263c8ea0f153cec 100644
--- a/src/sakia/gui/navigation/txhistory/controller.py
+++ b/src/sakia/gui/navigation/txhistory/controller.py
@@ -1,7 +1,7 @@
 import asyncio
 import logging
 
-from PyQt5.QtCore import QTime, pyqtSignal, QObject, QDateTime
+from PyQt5.QtCore import QTime, pyqtSignal, QObject, QDateTime, QCoreApplication
 from PyQt5.QtGui import QCursor
 
 from sakia.decorators import asyncify
@@ -92,11 +92,11 @@ class TxHistoryController(QObject):
     async def notification_reception(self, received_list):
         if len(received_list) > 0:
             localized_amount = await self.model.received_amount(received_list)
-            text = self.tr("Received {amount} from {number} transfers").format(
+            text = QCoreApplication.translate("TxHistoryController", "Received {amount} from {number} transfers").format(
                 amount=localized_amount, number=len(received_list)
             )
             if self.model.notifications():
-                toast.display(self.tr("New transactions received"), text)
+                toast.display(QCoreApplication.translate("TxHistoryController", "New transactions received"), text)
 
     def refresh_balance(self):
         localized_amount = self.model.localized_balance()
diff --git a/src/sakia/gui/navigation/txhistory/model.py b/src/sakia/gui/navigation/txhistory/model.py
index 7e9b6d8cca2929d4f76856eb760e93cc1a7eb720..52b853a371da620d94478e887a96e05a6c5e8a0d 100644
--- a/src/sakia/gui/navigation/txhistory/model.py
+++ b/src/sakia/gui/navigation/txhistory/model.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import QObject
+from PyQt5.QtCore import QObject, QCoreApplication
 from .table_model import HistoryTableModel
 from PyQt5.QtCore import Qt, QDateTime, QTime, pyqtSignal, QModelIndex
 from sakia.errors import NoPeerAvailable
@@ -134,7 +134,7 @@ class TxHistoryModel(QObject):
             logging.debug(str(e))
         except errors.DuniterError as e:
             logging.debug(str(e))
-        return self.tr("Loading...")
+        return QCoreApplication.translate("TxHistoryModel", "Loading...")
 
     @property
     def table_model(self):
diff --git a/src/sakia/gui/navigation/txhistory/table_model.py b/src/sakia/gui/navigation/txhistory/table_model.py
index 95af6f85fb140878f43640d1bd91e0838d0b5639..6f8401e0468247983309fbe6d726262419178afd 100644
--- a/src/sakia/gui/navigation/txhistory/table_model.py
+++ b/src/sakia/gui/navigation/txhistory/table_model.py
@@ -185,7 +185,7 @@ class HistoryTableModel(QAbstractTableModel):
             date_ts,
             "",
             0,
-            self.tr("Transactions missing from history"),
+            QCoreApplication.translate("HistoryTableModel", "Transactions missing from history"),
             transfer.state,
             txid,
             transfer.issuers,
@@ -462,13 +462,13 @@ class HistoryTableModel(QAbstractTableModel):
                 if current_confirmations >= MAX_CONFIRMATIONS:
                     return None
                 elif self.app.parameters.expert_mode:
-                    return self.tr("{0} / {1} confirmations").format(
+                    return QCoreApplication.translate("HistoryTableModel", "{0} / {1} confirmations").format(
                         current_confirmations, MAX_CONFIRMATIONS
                     )
                 else:
                     confirmation = current_confirmations / MAX_CONFIRMATIONS * 100
                     confirmation = 100 if confirmation > 100 else confirmation
-                    return self.tr("Confirming... {0} %").format(
+                    return QCoreApplication.translate("HistoryTableModel", "Confirming... {0} %").format(
                         QLocale().toString(float(confirmation), "f", 0)
                     )
 
diff --git a/src/sakia/gui/navigation/txhistory/view.py b/src/sakia/gui/navigation/txhistory/view.py
index a3048ea432da84066d068f8066662c28da859fbb..3b756944fff71bc5f5c414d71ed0fd951e859693 100644
--- a/src/sakia/gui/navigation/txhistory/view.py
+++ b/src/sakia/gui/navigation/txhistory/view.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import QDateTime, QEvent
+from PyQt5.QtCore import QDateTime, QEvent, QCoreApplication
 from PyQt5.QtWidgets import QWidget, QAbstractItemView, QHeaderView
 from .delegate import TxHistoryDelegate
 
@@ -60,7 +60,7 @@ class TxHistoryView(QWidget, Ui_TxHistoryWidget):
         self.date_to.setMaximumDateTime(maximum)
 
     def set_max_pages(self, pages):
-        self.spin_page.setSuffix(self.tr(" / {:} pages").format(pages + 1))
+        self.spin_page.setSuffix(QCoreApplication.translate("TxHistoryView", " / {:} pages").format(pages + 1))
         self.spin_page.setMaximum(pages + 1)
 
     def set_balance(self, balance):
diff --git a/src/sakia/gui/sub/certification/controller.py b/src/sakia/gui/sub/certification/controller.py
index 6a4616d54a9e120f61f344aca9397905c6523dbb..109dc9535db1a1f0be380ed5e6f2931699fc4e75 100644
--- a/src/sakia/gui/sub/certification/controller.py
+++ b/src/sakia/gui/sub/certification/controller.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import Qt, QObject, pyqtSignal
+from PyQt5.QtCore import Qt, QObject, pyqtSignal, QCoreApplication
 from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout
 
 from sakia.constants import ROOT_SERVERS
@@ -87,7 +87,7 @@ class CertificationController(QObject):
         """
 
         dialog = QDialog(parent)
-        dialog.setWindowTitle(dialog.tr("Certification"))
+        dialog.setWindowTitle(QCoreApplication.translate("CertificationController", "Certification"))
         dialog.setLayout(QVBoxLayout(dialog))
         certification = cls.create(parent, app)
         certification.set_connection(connection)
@@ -108,7 +108,7 @@ class CertificationController(QObject):
         :return:
         """
         dialog = QDialog(parent)
-        dialog.setWindowTitle(dialog.tr("Certification"))
+        dialog.setWindowTitle(QCoreApplication.translate("CertificationController", "Certification"))
         dialog.setLayout(QVBoxLayout(dialog))
         certification = cls.create(parent, app)
         if connection:
@@ -201,9 +201,9 @@ using cross checking which will help to reveal the problem if needs to be.</br>"
                     )
                 elif days + hours + minutes > 0:
                     if days > 0:
-                        remaining_localized = self.tr("{days} days").format(days=days)
+                        remaining_localized = QCoreApplication.translate("CertificationController", "{days} days").format(days=days)
                     else:
-                        remaining_localized = self.tr("{hours}h {min}min").format(
+                        remaining_localized = QCoreApplication.translate("CertificationController", "{hours}h {min}min").format(
                             hours=hours, min=minutes
                         )
                     self.view.set_button_process(
diff --git a/src/sakia/gui/sub/certification/view.py b/src/sakia/gui/sub/certification/view.py
index 5b5976382c8f9ad7b4e3c58d1c640d8a99ee183c..e7a63dc98141f85478aec10222dd8efb299e6c40 100644
--- a/src/sakia/gui/sub/certification/view.py
+++ b/src/sakia/gui/sub/certification/view.py
@@ -84,7 +84,7 @@ class CertificationView(QWidget, Ui_CertificationWidget):
             lambda c: self.stackedWidget.setCurrentIndex(2)
         )
 
-        licence_text = self.tr(G1_LICENSE)
+        licence_text = QCoreApplication.translate("CertificationView", G1_LICENSE)
         self.text_licence.setText(licence_text)
 
     def clear(self):
@@ -111,9 +111,9 @@ class CertificationView(QWidget, Ui_CertificationWidget):
     def import_identity_document(self):
         file_name = QFileDialog.getOpenFileName(
             self,
-            self.tr("Import identity document"),
+            QCoreApplication.translate("CertificationView", "Import identity document"),
             "",
-            self.tr("Duniter documents (*.txt)"),
+            QCoreApplication.translate("CertificationView", "Duniter documents (*.txt)"),
         )
         if file_name and file_name[0]:
             with open(file_name[0], "r") as open_file:
@@ -124,8 +124,8 @@ class CertificationView(QWidget, Ui_CertificationWidget):
                 except MalformedDocumentError as e:
                     QMessageBox.warning(
                         self,
-                        self.tr("Identity document"),
-                        self.tr("The imported file is not a correct identity document"),
+                        QCoreApplication.translate("CertificationView", "Identity document"),
+                        QCoreApplication.translate("CertificationView", "The imported file is not a correct identity document"),
                         QMessageBox.Ok,
                     )
 
@@ -141,25 +141,25 @@ class CertificationView(QWidget, Ui_CertificationWidget):
     async def show_success(self, notification):
         if notification:
             toast.display(
-                self.tr("Certification"), self.tr("Success sending certification")
+                QCoreApplication.translate("CertificationView", "Certification"), QCoreApplication.translate("CertificationView", "Success sending certification")
             )
         else:
             await QAsyncMessageBox.information(
-                self, self.tr("Certification"), self.tr("Success sending certification")
+                self, QCoreApplication.translate("CertificationView", "Certification"), QCoreApplication.translate("CertificationView", "Success sending certification")
             )
 
     async def show_error(self, notification, error_txt):
 
         if notification:
             toast.display(
-                self.tr("Certification"),
-                self.tr("Could not broadcast certification: {0}".format(error_txt)),
+                QCoreApplication.translate("CertificationView", "Certification"),
+                QCoreApplication.translate("CertificationView", "Could not broadcast certification: {0}".format(error_txt)),
             )
         else:
             await QAsyncMessageBox.critical(
                 self,
-                self.tr("Certification"),
-                self.tr("Could not broadcast certification: {0}".format(error_txt)),
+                QCoreApplication.translate("CertificationView", "Certification"),
+                QCoreApplication.translate("CertificationView", "Could not broadcast certification: {0}".format(error_txt)),
             )
 
     def display_cert_stock(
@@ -180,7 +180,7 @@ class CertificationView(QWidget, Ui_CertificationWidget):
         :param int remaining_hours:
         :param int remaining_minutes:
         """
-        cert_text = self.tr("Certifications sent: {nb_certifications}/{stock}").format(
+        cert_text = QCoreApplication.translate("CertificationView", "Certifications sent: {nb_certifications}/{stock}").format(
             nb_certifications=written, stock=stock
         )
         if pending > 0:
@@ -189,13 +189,13 @@ class CertificationView(QWidget, Ui_CertificationWidget):
             )
 
         if remaining_days > 0:
-            remaining_localized = self.tr("{days} days").format(days=remaining_days)
+            remaining_localized = QCoreApplication.translate("CertificationView", "{days} days").format(days=remaining_days)
         else:
-            remaining_localized = self.tr("{hours} hours and {min} min.").format(
+            remaining_localized = QCoreApplication.translate("CertificationView", "{hours} hours and {min} min.").format(
                 hours=remaining_hours, min=remaining_minutes
             )
         cert_text += "\n"
-        cert_text += self.tr(
+        cert_text += QCoreApplication.translate("CertificationView",
             "Remaining time before next certification validation: {0}".format(
                 remaining_localized
             )
diff --git a/src/sakia/gui/sub/password_input/controller.py b/src/sakia/gui/sub/password_input/controller.py
index e93ab211a8f9b101e2d6b5b136f07a677d0a9fe2..e9fc6ea89b80e553f73214b254571193d284f01d 100644
--- a/src/sakia/gui/sub/password_input/controller.py
+++ b/src/sakia/gui/sub/password_input/controller.py
@@ -3,7 +3,7 @@ from duniterpy.key import SigningKey
 from .view import PasswordInputView
 from sakia.helpers import detect_non_printable
 from sakia.gui.widgets.dialogs import dialog_async_exec
-from PyQt5.QtCore import QObject, pyqtSignal, QMetaObject
+from PyQt5.QtCore import QObject, pyqtSignal, QMetaObject, QCoreApplication
 from PyQt5.QtWidgets import QDialog, QVBoxLayout
 
 
@@ -47,7 +47,7 @@ class PasswordInputController(QObject):
         dialog = QDialog(parent.view)
         dialog.setLayout(QVBoxLayout(dialog))
         password_input = cls.create(parent, connection)
-        dialog.setWindowTitle(password_input.tr("Please enter your password"))
+        dialog.setWindowTitle(QCoreApplication.translate("PasswordInputController", "Please enter your password"))
         dialog.layout().addWidget(password_input.view)
         password_input.view.button_box.accepted.connect(dialog.accept)
         password_input.view.button_box.rejected.connect(dialog.reject)
@@ -64,18 +64,18 @@ class PasswordInputController(QObject):
 
     def check_private_key(self, secret_key, password):
         if detect_non_printable(secret_key):
-            self.view.error(self.tr("Non printable characters in secret key"))
+            self.view.error(QCoreApplication.translate("PasswordInputController", "Non printable characters in secret key"))
             return False
 
         if detect_non_printable(password):
-            self.view.error(self.tr("Non printable characters in password"))
+            self.view.error(QCoreApplication.translate("PasswordInputController", "Non printable characters in password"))
             return False
         if (
             SigningKey.from_credentials(secret_key, password, self.connection.scrypt_params).pubkey
             != self.connection.pubkey
         ):
             self.view.error(
-                self.tr("Wrong secret key or password. Cannot open the private key")
+                QCoreApplication.translate("PasswordInputController", "Wrong secret key or password. Cannot open the private key")
             )
             return False
         return True
diff --git a/src/sakia/gui/sub/password_input/view.py b/src/sakia/gui/sub/password_input/view.py
index c235134d143f5a10d8a8d05ab90dc42055b682b6..175690540189c1eeece42e46b317b6552b37ecaf 100644
--- a/src/sakia/gui/sub/password_input/view.py
+++ b/src/sakia/gui/sub/password_input/view.py
@@ -1,5 +1,5 @@
 from PyQt5.QtWidgets import QWidget, QDialogButtonBox
-from PyQt5.QtCore import QEvent, Qt
+from PyQt5.QtCore import QEvent, Qt, QCoreApplication
 from .password_input_uic import Ui_PasswordInputWidget
 
 
@@ -30,7 +30,7 @@ class PasswordInputView(QWidget, Ui_PasswordInputWidget):
         self.edit_secret_key.clear()
 
     def valid(self):
-        self.label_info.setText(self.tr("Password is valid"))
+        self.label_info.setText(QCoreApplication.translate("PasswordInputView", "Password is valid"))
         self.button_box.button(QDialogButtonBox.Ok).setEnabled(True)
 
     def changeEvent(self, event):
diff --git a/src/sakia/gui/sub/search_user/view.py b/src/sakia/gui/sub/search_user/view.py
index bd17bb96438339ac5986aa7a23554764e7b3e628..5511e905b2c7af035bc5e390b23fa0b53925d778 100644
--- a/src/sakia/gui/sub/search_user/view.py
+++ b/src/sakia/gui/sub/search_user/view.py
@@ -38,7 +38,7 @@ class SearchUserView(QWidget, Ui_SearchUserWidget):
     def clear(self):
         self.combobox_search.clear()
         self.combobox_search.lineEdit().setPlaceholderText(
-            self.tr(SearchUserView._search_placeholder)
+            QCoreApplication.translate("SearchUserView", SearchUserView._search_placeholder)
         )
 
     def search(self, text=""):
@@ -53,7 +53,7 @@ class SearchUserView(QWidget, Ui_SearchUserWidget):
             text = self.combobox_search.lineEdit().text()
         self.combobox_search.lineEdit().clear()
         self.combobox_search.lineEdit().setPlaceholderText(
-            self.tr("Looking for {0}...").format(text)
+            QCoreApplication.translate("SearchUserView", "Looking for {0}...").format(text)
         )
         self.search_requested.emit(text)
 
@@ -77,7 +77,7 @@ class SearchUserView(QWidget, Ui_SearchUserWidget):
         Retranslate missing widgets from generated code
         """
         self.combobox_search.lineEdit().setPlaceholderText(
-            self.tr(SearchUserView._search_placeholder)
+            QCoreApplication.translate("SearchUserView", SearchUserView._search_placeholder)
         )
         super().retranslateUi(self)
 
diff --git a/src/sakia/gui/sub/transfer/controller.py b/src/sakia/gui/sub/transfer/controller.py
index 652d55a7f9ba5b93cba43f8ed740b31de17b18ad..a8caef78bf4ef408755957f5ca2564d6e7b1daa8 100644
--- a/src/sakia/gui/sub/transfer/controller.py
+++ b/src/sakia/gui/sub/transfer/controller.py
@@ -1,7 +1,7 @@
 import re
 import logging
 
-from PyQt5.QtCore import Qt, QObject, pyqtSignal
+from PyQt5.QtCore import Qt, QObject, pyqtSignal, QCoreApplication
 from PyQt5.QtWidgets import QApplication, QDialog, QVBoxLayout
 
 from duniterpy.constants import PUBKEY_REGEX
@@ -106,7 +106,7 @@ class TransferController(QObject):
     @classmethod
     def send_money_to_pubkey(cls, parent, app, connection, pubkey):
         dialog = QDialog(parent)
-        dialog.setWindowTitle(dialog.tr("Transfer"))
+        dialog.setWindowTitle(QCoreApplication.translate("TransferController", "Transfer"))
         dialog.setLayout(QVBoxLayout(dialog))
         transfer = cls.open_transfer_with_pubkey(parent, app, connection, pubkey)
 
@@ -118,7 +118,7 @@ class TransferController(QObject):
     @classmethod
     def send_money_to_identity(cls, parent, app, connection, identity):
         dialog = QDialog(parent)
-        dialog.setWindowTitle(dialog.tr("Transfer"))
+        dialog.setWindowTitle(QCoreApplication.translate("TransferController", "Transfer"))
         dialog.setLayout(QVBoxLayout(dialog))
         transfer = cls.open_transfer_with_pubkey(
             parent, app, connection, identity.pubkey
@@ -134,7 +134,7 @@ class TransferController(QObject):
     @classmethod
     def send_transfer_again(cls, parent, app, connection, resent_transfer):
         dialog = QDialog(parent)
-        dialog.setWindowTitle(dialog.tr("Transfer"))
+        dialog.setWindowTitle(QCoreApplication.translate("TransferController", "Transfer"))
         dialog.setLayout(QVBoxLayout(dialog))
         transfer = cls.create(parent, app)
         transfer.view.groupbox_connection.show()
diff --git a/src/sakia/gui/sub/transfer/view.py b/src/sakia/gui/sub/transfer/view.py
index f5ee1a56cb2ab71e0d6254301575518aa274e20d..3585ace189454a4e335667f8c788dfbdec7e5ab6 100644
--- a/src/sakia/gui/sub/transfer/view.py
+++ b/src/sakia/gui/sub/transfer/view.py
@@ -195,21 +195,21 @@ class TransferView(QWidget, Ui_TransferMoneyWidget):
     async def show_success(self, notification, recipient):
         if notification:
             toast.display(
-                self.tr("Transfer"),
-                self.tr("Success sending money to {0}").format(recipient),
+                QCoreApplication.translate("TransferView", "Transfer"),
+                QCoreApplication.translate("TransferView", "Success sending money to {0}").format(recipient),
             )
         else:
             await QAsyncMessageBox.information(
                 self,
-                self.tr("Transfer"),
-                self.tr("Success sending money to {0}").format(recipient),
+                QCoreApplication.translate("TransferView", "Transfer"),
+                QCoreApplication.translate("TransferView", "Success sending money to {0}").format(recipient),
             )
 
     async def show_error(self, notification, error_txt):
         if notification:
-            toast.display(self.tr("Transfer"), "Error: {0}".format(error_txt))
+            toast.display(QCoreApplication.translate("TransferView", "Transfer"), "Error: {0}".format(error_txt))
         else:
-            await QAsyncMessageBox.critical(self, self.tr("Transfer"), error_txt)
+            await QAsyncMessageBox.critical(self, QCoreApplication.translate("TransferView", "Transfer"), error_txt)
 
     def pubkey_value(self):
         return self.edit_pubkey.text()
diff --git a/src/sakia/gui/sub/user_information/view.py b/src/sakia/gui/sub/user_information/view.py
index 0f58ec5cbed96c30af0a17f571415f6132c51fdc..6718d5d10e629fa504bfe14b13178cd536fd6547 100644
--- a/src/sakia/gui/sub/user_information/view.py
+++ b/src/sakia/gui/sub/user_information/view.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import QLocale, QDateTime
+from PyQt5.QtCore import QLocale, QDateTime, QCoreApplication
 from PyQt5.QtWidgets import QWidget
 from .user_information_uic import Ui_UserInformationWidget
 from sakia.gui.widgets.busy import Busy
@@ -59,7 +59,7 @@ class UserInformationView(QWidget, Ui_UserInformationWidget):
         else:
             localized_mstime_remaining = "###"
 
-        text = self.tr(
+        text = QCoreApplication.translate("UserInformationView",
             """
             <table cellpadding="5">
             <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
@@ -69,15 +69,15 @@ class UserInformationView(QWidget, Ui_UserInformationWidget):
             <tr><td align="right"><b>{:}</b></td><td>{:}</td></tr>
             """
         ).format(
-            self.tr("Public key"),
+            QCoreApplication.translate("UserInformationView", "Public key"),
             pubkey,
-            self.tr("UID Published on"),
+            QCoreApplication.translate("UserInformationView", "UID Published on"),
             localized_publish_date,
-            self.tr("Join date"),
+            QCoreApplication.translate("UserInformationView", "Join date"),
             localized_join_date,
-            self.tr("Expires in"),
+            QCoreApplication.translate("UserInformationView", "Expires in"),
             localized_mstime_remaining,
-            self.tr("Certs. received"),
+            QCoreApplication.translate("UserInformationView", "Certs. received"),
             nb_certs,
         )
 
@@ -92,8 +92,8 @@ class UserInformationView(QWidget, Ui_UserInformationWidget):
         Display the uid in the label
         :param str uid:
         """
-        status_label = self.tr("Member") if member else self.tr("Not a member")
-        status_color = "#00AA00" if member else self.tr("#FF0000")
+        status_label = QCoreApplication.translate("UserInformationView", "Member") if member else QCoreApplication.translate("UserInformationView", "Not a member")
+        status_color = "#00AA00" if member else QCoreApplication.translate("UserInformationView", "#FF0000")
         text = "<b>{uid}</b> <p style='color: {status_color};'>({status_label})</p>".format(
             uid=uid, status_color=status_color, status_label=status_label
         )
diff --git a/src/sakia/gui/widgets/context_menu.py b/src/sakia/gui/widgets/context_menu.py
index fcb4dc117a28acae41d8ac751aff176230704dce..105c3576f62f48b8c34a5107ef32e2386bb0959b 100644
--- a/src/sakia/gui/widgets/context_menu.py
+++ b/src/sakia/gui/widgets/context_menu.py
@@ -1,6 +1,6 @@
 import logging
 import re
-from PyQt5.QtCore import QObject, pyqtSignal
+from PyQt5.QtCore import QObject, pyqtSignal, QCoreApplication
 from PyQt5.QtWidgets import QMenu, QAction, QApplication, QMessageBox
 
 from duniterpy.constants import PUBKEY_REGEX
@@ -38,31 +38,31 @@ class ContextMenu(QObject):
             identity.uid if identity.uid else identity.pubkey[:7]
         )
 
-        informations = QAction(menu.qmenu.tr("Informations"), menu.qmenu.parent())
+        informations = QAction(QCoreApplication.translate("ContextMenu", "Informations"), menu.qmenu.parent())
         informations.triggered.connect(lambda checked, i=identity: menu.informations(i))
         menu.qmenu.addAction(informations)
 
         if identity.uid and (
             not menu._connection or menu._connection.pubkey != identity.pubkey
         ):
-            certify = QAction(menu.tr("Certify identity"), menu.qmenu.parent())
+            certify = QAction(QCoreApplication.translate("ContextMenu", "Certify identity"), menu.qmenu.parent())
             certify.triggered.connect(
                 lambda checked, i=identity: menu.certify_identity(i)
             )
             menu.qmenu.addAction(certify)
 
             view_wot = QAction(
-                menu.qmenu.tr("View in Web of Trust"), menu.qmenu.parent()
+                QCoreApplication.translate("ContextMenu", "View in Web of Trust"), menu.qmenu.parent()
             )
             view_wot.triggered.connect(lambda checked, i=identity: menu.view_wot(i))
             menu.qmenu.addAction(view_wot)
 
-            send_money = QAction(menu.qmenu.tr("Send money"), menu.qmenu.parent())
+            send_money = QAction(QCoreApplication.translate("ContextMenu", "Send money"), menu.qmenu.parent())
             send_money.triggered.connect(lambda checked, i=identity: menu.send_money(i))
             menu.qmenu.addAction(send_money)
 
         copy_pubkey = QAction(
-            menu.qmenu.tr("Copy pubkey to clipboard"), menu.qmenu.parent()
+            QCoreApplication.translate("ContextMenu", "Copy pubkey to clipboard"), menu.qmenu.parent()
         )
         copy_pubkey.triggered.connect(
             lambda checked, i=identity: ContextMenu.copy_pubkey_to_clipboard(i)
@@ -70,7 +70,7 @@ class ContextMenu(QObject):
         menu.qmenu.addAction(copy_pubkey)
 
         copy_pubkey = QAction(
-            menu.qmenu.tr("Copy pubkey to clipboard (with CRC)"), menu.qmenu.parent()
+            QCoreApplication.translate("ContextMenu", "Copy pubkey to clipboard (with CRC)"), menu.qmenu.parent()
         )
         copy_pubkey.triggered.connect(
             lambda checked, i=identity: ContextMenu.copy_pubkey_to_clipboard_with_crc(i)
@@ -79,7 +79,7 @@ class ContextMenu(QObject):
 
         if identity.uid and menu._app.parameters.expert_mode:
             copy_selfcert = QAction(
-                menu.qmenu.tr("Copy self-certification document to clipboard"),
+                QCoreApplication.translate("ContextMenu", "Copy self-certification document to clipboard"),
                 menu.qmenu.parent(),
             )
             copy_selfcert.triggered.connect(
@@ -93,15 +93,15 @@ class ContextMenu(QObject):
         :param ContextMenu menu: the qmenu to add actions to
         :param Transfer transfer: the transfer
         """
-        menu.qmenu.addSeparator().setText(menu.qmenu.tr("Transfer"))
+        menu.qmenu.addSeparator().setText(QCoreApplication.translate("ContextMenu", "Transfer"))
         if transfer.state in (Transaction.REFUSED, Transaction.TO_SEND):
-            send_back = QAction(menu.qmenu.tr("Send again"), menu.qmenu.parent())
+            send_back = QAction(QCoreApplication.translate("ContextMenu", "Send again"), menu.qmenu.parent())
             send_back.triggered.connect(
                 lambda checked, tr=transfer: menu.send_again(tr)
             )
             menu.qmenu.addAction(send_back)
 
-            cancel = QAction(menu.qmenu.tr("Cancel"), menu.qmenu.parent())
+            cancel = QAction(QCoreApplication.translate("ContextMenu", "Cancel"), menu.qmenu.parent())
             cancel.triggered.connect(
                 lambda checked, tr=transfer: menu.cancel_transfer(tr)
             )
@@ -109,7 +109,7 @@ class ContextMenu(QObject):
 
         if menu._app.parameters.expert_mode:
             copy_doc = QAction(
-                menu.qmenu.tr("Copy raw transaction to clipboard"), menu.qmenu.parent()
+                QCoreApplication.translate("ContextMenu", "Copy raw transaction to clipboard"), menu.qmenu.parent()
             )
             copy_doc.triggered.connect(
                 lambda checked, tx=transfer: menu.copy_transaction_to_clipboard(tx)
@@ -118,7 +118,7 @@ class ContextMenu(QObject):
 
             if transfer.blockstamp:
                 copy_doc = QAction(
-                    menu.qmenu.tr("Copy transaction block to clipboard"),
+                    QCoreApplication.translate("ContextMenu", "Copy transaction block to clipboard"),
                     menu.qmenu.parent(),
                 )
                 copy_doc.triggered.connect(
@@ -133,7 +133,7 @@ class ContextMenu(QObject):
         if re.match(PUBKEY_REGEX, str_value):
             menu.qmenu.addSeparator().setText(str_value[:7])
             copy_pubkey = QAction(
-                menu.qmenu.tr("Copy pubkey to clipboard"), menu.qmenu.parent()
+                QCoreApplication.translate("ContextMenu", "Copy pubkey to clipboard"), menu.qmenu.parent()
             )
             copy_pubkey.triggered.connect(
                 lambda checked, p=str_value: ContextMenu.copy_pubkey_to_clipboard(p)
@@ -141,7 +141,7 @@ class ContextMenu(QObject):
             menu.qmenu.addAction(copy_pubkey)
 
             copy_pubkey = QAction(
-                menu.qmenu.tr("Copy pubkey to clipboard (with CRC)"),
+                QCoreApplication.translate("ContextMenu", "Copy pubkey to clipboard (with CRC)"),
                 menu.qmenu.parent(),
             )
             copy_pubkey.triggered.connect(
@@ -152,7 +152,7 @@ class ContextMenu(QObject):
             menu.qmenu.addAction(copy_pubkey)
 
             if menu._connection.pubkey != str_value:
-                send_money = QAction(menu.qmenu.tr("Send money"), menu.qmenu.parent())
+                send_money = QAction(QCoreApplication.translate("ContextMenu", "Send money"), menu.qmenu.parent())
                 send_money.triggered.connect(
                     lambda checked, p=str_value: menu.send_money(p)
                 )
@@ -235,8 +235,8 @@ class ContextMenu(QObject):
     def cancel_transfer(self, transfer):
         reply = QMessageBox.warning(
             self.qmenu,
-            self.tr("Warning"),
-            self.tr(
+            QCoreApplication.translate("ContextMenu", "Warning"),
+            QCoreApplication.translate("ContextMenu",
                 """Are you sure?
 This money transfer will be removed and not sent."""
             ),