tMerge pull request #2911 from SomberNight/pyqt5 - electrum - Electrum Bitcoin wallet
HTML git clone https://git.parazyd.org/electrum
DIR Log
DIR Files
DIR Refs
DIR Submodules
---
DIR commit 99bc43d8db3879b1118ca8b3db44dbb9152c8da8
DIR parent c43b48f4f59d3214bbb3fa851d6e039f086adb45
HTML Author: ThomasV <thomasv@electrum.org>
Date: Sun, 24 Sep 2017 09:42:32 +0200
Merge pull request #2911 from SomberNight/pyqt5
migration to PyQt5
Diffstat:
M README.rst | 6 +++---
M gui/qt/__init__.py | 30 ++++++++++++++++++++----------
M gui/qt/address_dialog.py | 6 +++---
M gui/qt/amountedit.py | 7 ++++---
M gui/qt/console.py | 13 +++++++------
M gui/qt/contact_list.py | 8 +++++---
M gui/qt/fee_slider.py | 9 +++++----
M gui/qt/installwizard.py | 23 +++++++++++++----------
M gui/qt/invoice_list.py | 4 ++--
M gui/qt/main_window.py | 70 ++++++++++++++++++-------------
M gui/qt/network_dialog.py | 38 ++++++++++++++++---------------
M gui/qt/password_dialog.py | 4 ++--
M gui/qt/paytoedit.py | 5 +++--
M gui/qt/qrcodewidget.py | 13 ++++++++-----
M gui/qt/qrtextedit.py | 7 ++++---
M gui/qt/qrwindow.py | 9 +++++----
M gui/qt/request_list.py | 7 ++++---
M gui/qt/seed_dialog.py | 4 ++--
M gui/qt/transaction_dialog.py | 8 ++++----
M gui/qt/util.py | 23 ++++++++++++-----------
M lib/plot.py | 4 ++--
M plugins/audio_modem/qt.py | 5 +++--
M plugins/cosigner_pool/qt.py | 17 +++++++++++------
M plugins/digitalbitbox/qt.py | 2 +-
M plugins/email_requests/qt.py | 19 ++++++++++++-------
M plugins/greenaddress_instant/qt.py | 2 +-
M plugins/hw_wallet/qt.py | 2 +-
M plugins/labels/qt.py | 15 ++++++++++-----
M plugins/ledger/auth2fa.py | 5 +++--
M plugins/ledger/qt.py | 6 +++---
M plugins/trezor/qt_generic.py | 8 ++++----
M plugins/trustedcoin/qt.py | 16 ++++++++++++----
M plugins/virtualkeyboard/qt.py | 3 ++-
M setup-release.py | 2 +-
34 files changed, 232 insertions(+), 168 deletions(-)
---
DIR diff --git a/README.rst b/README.rst
t@@ -23,7 +23,7 @@ Getting started
Electrum is a pure python application. If you want to use the
Qt interface, install the Qt dependencies::
- sudo apt-get install python3-pyqt4
+ sudo apt-get install python3-pyqt5
If you downloaded the official package (tar.gz), you can run
Electrum from its root directory, without installing it on your
t@@ -60,8 +60,8 @@ Run install (this should install dependencies)::
Compile the icons file for Qt::
- sudo apt-get install pyqt4-dev-tools
- pyrcc4 icons.qrc -o gui/qt/icons_rc.py -py3
+ sudo apt-get install pyqt5-dev-tools
+ pyrcc5 icons.qrc -o gui/qt/icons_rc.py
Compile the protobuf description file::
DIR diff --git a/gui/qt/__init__.py b/gui/qt/__init__.py
t@@ -28,13 +28,14 @@ import os
import signal
try:
- import PyQt4
+ import PyQt5
except Exception:
- sys.exit("Error: Could not import PyQt4 on Linux systems, you may try 'sudo apt-get install python3-pyqt4'")
+ sys.exit("Error: Could not import PyQt5 on Linux systems, you may try 'sudo apt-get install python3-pyqt5'")
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
+from PyQt5.QtGui import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtCore import *
+import PyQt5.QtCore as QtCore
from electrum.i18n import _, set_language
from electrum.plugins import run_hook
t@@ -52,7 +53,7 @@ try:
except Exception as e:
print(e)
print("Error: Could not find icons file.")
- print("Please run 'pyrcc4 icons.qrc -o gui/qt/icons_rc.py -py3', and reinstall Electrum")
+ print("Please run 'pyrcc5 icons.qrc -o gui/qt/icons_rc.py', and reinstall Electrum")
sys.exit(1)
from .util import * # * needed for plugins
t@@ -73,6 +74,13 @@ class OpenFileEventFilter(QObject):
return False
+class QElectrumApplication(QApplication):
+ new_window_signal = pyqtSignal(str, object)
+
+
+class QNetworkUpdatedSignalObject(QObject):
+ network_updated_signal = pyqtSignal(str, object)
+
class ElectrumGui:
t@@ -88,10 +96,11 @@ class ElectrumGui:
self.plugins = plugins
self.windows = []
self.efilter = OpenFileEventFilter(self.windows)
- self.app = QApplication(sys.argv)
+ self.app = QElectrumApplication(sys.argv)
self.app.installEventFilter(self.efilter)
self.timer = Timer()
self.nd = None
+ self.network_updated_signal_obj = QNetworkUpdatedSignalObject()
# init tray
self.dark_icon = self.config.get("dark_icon", False)
self.tray = QSystemTrayIcon(self.tray_icon(), None)
t@@ -99,7 +108,7 @@ class ElectrumGui:
self.tray.activated.connect(self.tray_activated)
self.build_tray_menu()
self.tray.show()
- self.app.connect(self.app, QtCore.SIGNAL('new_window'), self.start_new_window)
+ self.app.new_window_signal.connect(self.start_new_window)
run_hook('init_qt', self)
def build_tray_menu(self):
t@@ -141,7 +150,7 @@ class ElectrumGui:
def new_window(self, path, uri=None):
# Use a signal as can be called from daemon thread
- self.app.emit(SIGNAL('new_window'), path, uri)
+ self.app.new_window_signal.emit(path, uri)
def show_network_dialog(self, parent):
if not self.daemon.network:
t@@ -152,7 +161,8 @@ class ElectrumGui:
self.nd.show()
self.nd.raise_()
return
- self.nd = NetworkDialog(self.daemon.network, self.config)
+ self.nd = NetworkDialog(self.daemon.network, self.config,
+ self.network_updated_signal_obj)
self.nd.show()
def create_window_for_wallet(self, wallet):
DIR diff --git a/gui/qt/address_dialog.py b/gui/qt/address_dialog.py
t@@ -30,9 +30,9 @@ from __future__ import unicode_literals
import six
from electrum.i18n import _
-import PyQt4
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+import PyQt5
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
from .util import *
from .history_list import HistoryList
DIR diff --git a/gui/qt/amountedit.py b/gui/qt/amountedit.py
t@@ -5,8 +5,9 @@ from __future__ import print_function
from __future__ import unicode_literals
import six
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtWidgets import (QLineEdit, QStyle, QStyleOptionFrame)
from decimal import Decimal
from electrum.util import format_satoshis_plain
t@@ -59,7 +60,7 @@ class AmountEdit(MyLineEdit):
def paintEvent(self, event):
QLineEdit.paintEvent(self, event)
if self.base_unit:
- panel = QStyleOptionFrameV2()
+ panel = QStyleOptionFrame()
self.initStyleOption(panel)
textRect = self.style().subElementRect(QStyle.SE_LineEditContents, panel, self)
textRect.adjust(2, 0, -10, 0)
DIR diff --git a/gui/qt/console.py b/gui/qt/console.py
t@@ -8,8 +8,9 @@ import six
import sys, os, re
import traceback, platform
-from PyQt4 import QtCore
-from PyQt4 import QtGui
+from PyQt5 import QtCore
+from PyQt5 import QtGui
+from PyQt5 import QtWidgets
from electrum import util
t@@ -21,9 +22,9 @@ else:
MONOSPACE_FONT = 'monospace'
-class Console(QtGui.QPlainTextEdit):
+class Console(QtWidgets.QPlainTextEdit):
def __init__(self, prompt='>> ', startup_message='', parent=None):
- QtGui.QPlainTextEdit.__init__(self, parent)
+ QtWidgets.QPlainTextEdit.__init__(self, parent)
self.prompt = prompt
self.history = []
t@@ -315,8 +316,8 @@ welcome_message = '''
'''
if __name__ == '__main__':
- app = QtGui.QApplication(sys.argv)
+ app = QtWidgets.QApplication(sys.argv)
console = Console(startup_message=welcome_message)
console.updateNamespace({'myVar1' : app, 'myVar2' : 1234})
- console.show();
+ console.show()
sys.exit(app.exec_())
DIR diff --git a/gui/qt/contact_list.py b/gui/qt/contact_list.py
t@@ -35,8 +35,10 @@ from electrum.bitcoin import is_address
from electrum.util import block_explorer_URL, format_satoshis, format_time, age
from electrum.plugins import run_hook
from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import (
+ QAbstractItemView, QFileDialog, QMenu, QTreeWidgetItem)
from .util import MyTreeWidget, pr_tooltips, pr_icons
t@@ -59,7 +61,7 @@ class ContactList(MyTreeWidget):
def import_contacts(self):
wallet_folder = self.parent.get_wallet_folder()
- filename = QFileDialog.getOpenFileName(self.parent, "Select your wallet file", wallet_folder)
+ filename, __ = QFileDialog.getOpenFileName(self.parent, "Select your wallet file", wallet_folder)
if not filename:
return
self.parent.contacts.import_file(filename)
DIR diff --git a/gui/qt/fee_slider.py b/gui/qt/fee_slider.py
t@@ -6,10 +6,11 @@ from __future__ import unicode_literals
import six
from electrum.i18n import _
-import PyQt4
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
+import PyQt5
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+import PyQt5.QtCore as QtCore
+from PyQt5.QtWidgets import QSlider, QToolTip
import threading
DIR diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py
t@@ -7,9 +7,9 @@ import six
import sys
import os
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+import PyQt5.QtCore as QtCore
import electrum
from electrum import Wallet, WalletStorage
t@@ -101,6 +101,9 @@ def wizard_dialog(func):
# WindowModalDialog must come first as it overrides show_error
class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
+ accept_signal = pyqtSignal()
+ synchronized_signal = pyqtSignal(str)
+
def __init__(self, config, app, plugins, storage):
BaseWizard.__init__(self, config, storage)
QDialog.__init__(self, None)
t@@ -111,7 +114,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
self.plugins = plugins
self.language_for_seed = config.get('language')
self.setMinimumSize(600, 400)
- self.connect(self, QtCore.SIGNAL('accept'), self.accept)
+ self.accept_signal.connect(self.accept)
self.title = QLabel()
self.main_widget = QWidget()
self.back_button = QPushButton(_("Back"), self)
t@@ -176,7 +179,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
wallet_folder = os.path.dirname(self.storage.path)
def on_choose():
- path = QFileDialog.getOpenFileName(self, "Select your wallet file", wallet_folder)
+ path, __ = QFileDialog.getOpenFileName(self, "Select your wallet file", wallet_folder)
if path:
self.name_e.setText(path)
t@@ -227,11 +230,11 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
self.storage.decrypt(password)
break
except InvalidPassword as e:
- QMessageBox.information(None, _('Error'), str(e), _('OK'))
+ QMessageBox.information(None, _('Error'), str(e))
continue
except BaseException as e:
traceback.print_exc(file=sys.stdout)
- QMessageBox.information(None, _('Error'), str(e), _('OK'))
+ QMessageBox.information(None, _('Error'), str(e))
return
path = self.storage.path
t@@ -408,8 +411,8 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
msg = _("Recovery successful")
else:
msg = _("No transactions found for this seed")
- self.emit(QtCore.SIGNAL('synchronized'), msg)
- self.connect(self, QtCore.SIGNAL('synchronized'), self.show_message)
+ self.synchronized_signal.emit(msg)
+ self.synchronized_signal.connect(self.show_message)
t = threading.Thread(target = task)
t.daemon = True
t.start()
t@@ -436,7 +439,7 @@ class InstallWizard(QDialog, MessageBoxMixin, BaseWizard):
self.run(action)
def terminate(self):
- self.emit(QtCore.SIGNAL('accept'))
+ self.accept_signal.emit()
def waiting_dialog(self, task, msg):
self.please_wait.setText(MSG_GENERATING_WAIT)
DIR diff --git a/gui/qt/invoice_list.py b/gui/qt/invoice_list.py
t@@ -40,7 +40,7 @@ class InvoiceList(MyTreeWidget):
def __init__(self, parent):
MyTreeWidget.__init__(self, parent, self.create_menu, [_('Expires'), _('Requestor'), _('Description'), _('Amount'), _('Status')], 2)
self.setSortingEnabled(True)
- self.header().setResizeMode(1, QHeaderView.Interactive)
+ self.header().setSectionResizeMode(1, QHeaderView.Interactive)
self.setColumnWidth(1, 200)
def on_update(self):
t@@ -64,7 +64,7 @@ class InvoiceList(MyTreeWidget):
def import_invoices(self):
wallet_folder = self.parent.get_wallet_folder()
- filename = QFileDialog.getOpenFileName(self.parent, "Select your wallet file", wallet_folder)
+ filename, __ = QFileDialog.getOpenFileName(self.parent, "Select your wallet file", wallet_folder)
if not filename:
return
self.parent.invoices.import_file(filename)
DIR diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
t@@ -33,10 +33,10 @@ from decimal import Decimal
import base64
from functools import partial
-import PyQt4
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
+import PyQt5
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+import PyQt5.QtCore as QtCore
from electrum.util import bh2u, bfh
from . import icons_rc
t@@ -81,7 +81,7 @@ class StatusBarButton(QPushButton):
self.setIconSize(QSize(25,25))
def onPress(self, checked=False):
- '''Drops the unwanted PyQt4 "checked" argument'''
+ '''Drops the unwanted PyQt5 "checked" argument'''
self.func()
def keyPressEvent(self, e):
t@@ -94,6 +94,15 @@ from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
+ payment_request_ok_signal = pyqtSignal()
+ payment_request_error_signal = pyqtSignal()
+ new_fx_quotes_signal = pyqtSignal()
+ new_fx_history_signal = pyqtSignal()
+ network_signal = pyqtSignal(str, object)
+ alias_received_signal = pyqtSignal()
+ computing_privkeys_signal = pyqtSignal()
+ show_privkeys_signal = pyqtSignal()
+
def __init__(self, gui_object, wallet):
QMainWindow.__init__(self)
t@@ -167,13 +176,13 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
for i in range(wrtabs.count()):
QShortcut(QKeySequence("Alt+" + str(i + 1)), self, lambda i=i: wrtabs.setCurrentIndex(i))
- self.connect(self, QtCore.SIGNAL('payment_request_ok'), self.payment_request_ok)
- self.connect(self, QtCore.SIGNAL('payment_request_error'), self.payment_request_error)
+ self.payment_request_ok_signal.connect(self.payment_request_ok)
+ self.payment_request_error_signal.connect(self.payment_request_error)
self.history_list.setFocus(True)
# network callbacks
if self.network:
- self.connect(self, QtCore.SIGNAL('network'), self.on_network_qt)
+ self.network_signal.connect(self.on_network_qt)
interests = ['updated', 'new_transaction', 'status',
'banner', 'verified', 'fee']
# To avoid leaking references to "self" that prevent the
t@@ -185,8 +194,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.console.showMessage(self.network.banner)
self.network.register_callback(self.on_quotes, ['on_quotes'])
self.network.register_callback(self.on_history, ['on_history'])
- self.connect(self, SIGNAL('new_fx_quotes'), self.on_fx_quotes)
- self.connect(self, SIGNAL('new_fx_history'), self.on_fx_history)
+ self.new_fx_quotes_signal.connect(self.on_fx_quotes)
+ self.new_fx_history_signal.connect(self.on_fx_history)
# update fee slider in case we missed the callback
self.fee_slider.update()
t@@ -195,7 +204,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.fetch_alias()
def on_history(self, b):
- self.emit(SIGNAL('new_fx_history'))
+ self.new_fx_history_signal.emit()
def on_fx_history(self):
self.history_list.refresh_headers()
t@@ -203,7 +212,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
self.address_list.update()
def on_quotes(self, b):
- self.emit(SIGNAL('new_fx_quotes'))
+ self.new_fx_quotes_signal.emit()
def on_fx_quotes(self):
self.update_status()
t@@ -275,17 +284,18 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
def on_network(self, event, *args):
if event == 'updated':
self.need_update.set()
- self.emit(QtCore.SIGNAL('updated'), event, *args)
+ self.gui_object.network_updated_signal_obj.network_updated_signal \
+ .emit(event, args)
elif event == 'new_transaction':
self.tx_notifications.append(args[0])
elif event in ['status', 'banner', 'verified', 'fee']:
# Handle in GUI thread
- self.emit(QtCore.SIGNAL('network'), event, *args)
+ self.network_signal.emit(event, args)
else:
self.print_error("unexpected network message:", event, args)
- def on_network_qt(self, event, *args):
+ def on_network_qt(self, event, args=None):
# Handle a network message in the GUI thread
if event == 'status':
self.update_status()
t@@ -307,7 +317,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
alias = str(alias)
def f():
self.alias_info = self.contacts.resolve_openalias(alias)
- self.emit(SIGNAL('alias_received'))
+ self.alias_received_signal.emit()
t = threading.Thread(target=f)
t.setDaemon(True)
t.start()
t@@ -380,7 +390,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
def open_wallet(self):
wallet_folder = self.get_wallet_folder()
- filename = QFileDialog.getOpenFileName(self, "Select your wallet file", wallet_folder)
+ filename, __ = QFileDialog.getOpenFileName(self, "Select your wallet file", wallet_folder)
if not filename:
return
self.gui_object.new_window(filename)
t@@ -389,7 +399,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
def backup_wallet(self):
path = self.wallet.storage.path
wallet_folder = os.path.dirname(path)
- filename = QFileDialog.getSaveFileName(self, _('Enter a filename for the copy of your wallet'), wallet_folder)
+ filename, __ = QFileDialog.getSaveFileName(self, _('Enter a filename for the copy of your wallet'), wallet_folder)
if not filename:
return
t@@ -574,7 +584,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
# custom wrappers for getOpenFileName and getSaveFileName, that remember the path selected by the user
def getOpenFileName(self, title, filter = ""):
directory = self.config.get('io_dir', os.path.expanduser('~'))
- fileName = QFileDialog.getOpenFileName(self, title, directory, filter)
+ fileName, __ = QFileDialog.getOpenFileName(self, title, directory, filter)
if fileName and directory != os.path.dirname(fileName):
self.config.set_key('io_dir', os.path.dirname(fileName), True)
return fileName
t@@ -582,13 +592,13 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
def getSaveFileName(self, title, filename, filter = ""):
directory = self.config.get('io_dir', os.path.expanduser('~'))
path = os.path.join( directory, filename )
- fileName = QFileDialog.getSaveFileName(self, title, path, filter)
+ fileName, __ = QFileDialog.getSaveFileName(self, title, path, filter)
if fileName and directory != os.path.dirname(fileName):
self.config.set_key('io_dir', os.path.dirname(fileName), True)
return fileName
def connect_slots(self, sender):
- self.connect(sender, QtCore.SIGNAL('timersignal'), self.timer_actions)
+ sender.timer_signal.connect(self.timer_actions)
def timer_actions(self):
# Note this runs in the GUI thread
t@@ -1499,9 +1509,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
def on_pr(self, request):
self.payment_request = request
if self.payment_request.verify(self.contacts):
- self.emit(SIGNAL('payment_request_ok'))
+ self.payment_request_ok_signal.emit()
else:
- self.emit(SIGNAL('payment_request_error'))
+ self.payment_request_error_signal.emit()
def pay_to_URI(self, URI):
if not URI:
t@@ -1558,7 +1568,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
w.searchable_list = l
vbox = QVBoxLayout()
w.setLayout(vbox)
- vbox.setMargin(0)
+ vbox.setContentsMargins(0, 0, 0, 0)
vbox.setSpacing(0)
vbox.addWidget(l)
buttons = QWidget()
t@@ -2121,16 +2131,16 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
if done:
break
private_keys[addr] = "\n".join(self.wallet.get_private_key(addr, password))
- d.emit(SIGNAL('computing_privkeys'))
- d.emit(SIGNAL('show_privkeys'))
+ self.computing_privkeys_signal.emit()
+ self.show_privkeys_signal.emit()
def show_privkeys():
s = "\n".join( map( lambda x: x[0] + "\t"+ x[1], private_keys.items()))
e.setText(s)
b.setEnabled(True)
- d.connect(d, QtCore.SIGNAL('computing_privkeys'), lambda: e.setText("Please wait... %d/%d"%(len(private_keys),len(addresses))))
- d.connect(d, QtCore.SIGNAL('show_privkeys'), show_privkeys)
+ self.computing_privkeys_signal.connect(lambda: e.setText("Please wait... %d/%d"%(len(private_keys),len(addresses))))
+ self.show_privkeys_signal.connect(show_privkeys)
threading.Thread(target=privkeys_thread).start()
if not d.exec_():
t@@ -2470,7 +2480,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
if alias:
self.fetch_alias()
set_alias_color()
- self.connect(self, SIGNAL('alias_received'), set_alias_color)
+ self.alias_received_signal.connect(set_alias_color)
alias_e.editingFinished.connect(on_alias_edit)
id_widgets.append((alias_label, alias_e))
t@@ -2730,7 +2740,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
if self.fx:
self.fx.timeout = 0
- self.disconnect(self, SIGNAL('alias_received'), set_alias_color)
+ self.alias_received_signal.disconnect(set_alias_color)
run_hook('close_settings_dialog')
if self.need_restart:
DIR diff --git a/gui/qt/network_dialog.py b/gui/qt/network_dialog.py
t@@ -31,9 +31,9 @@ from __future__ import unicode_literals
import socket
import six
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+import PyQt5.QtCore as QtCore
from electrum.i18n import _
from electrum.network import DEFAULT_PORTS
t@@ -45,19 +45,21 @@ protocol_names = ['TCP', 'SSL']
protocol_letters = 'ts'
class NetworkDialog(QDialog):
- def __init__(self, network, config):
+ def __init__(self, network, config, network_updated_signal_obj):
QDialog.__init__(self)
self.setWindowTitle(_('Network'))
self.setMinimumSize(500, 20)
self.nlayout = NetworkChoiceLayout(network, config)
+ self.network_updated_signal_obj = network_updated_signal_obj
vbox = QVBoxLayout(self)
vbox.addLayout(self.nlayout.layout())
vbox.addLayout(Buttons(CloseButton(self)))
- self.connect(self, QtCore.SIGNAL('updated'), self.on_update)
+ self.network_updated_signal_obj.network_updated_signal.connect(
+ self.on_update)
network.register_callback(self.on_network, ['updated', 'interfaces'])
def on_network(self, event, *args):
- self.emit(QtCore.SIGNAL('updated'), event, *args)
+ self.network_updated_signal_obj.network_updated_signal.emit(event, args)
def on_update(self):
self.nlayout.update()
t@@ -97,7 +99,7 @@ class NodesListWidget(QTreeWidget):
# on 'enter' we show the menu
pt = self.visualItemRect(item).bottomLeft()
pt.setX(50)
- self.emit(SIGNAL('customContextMenuRequested(const QPoint&)'), pt)
+ self.customContextMenuRequested.emit(pt)
def update(self, network):
self.clear()
t@@ -125,8 +127,8 @@ class NodesListWidget(QTreeWidget):
h = self.header()
h.setStretchLastSection(False)
- h.setResizeMode(0, QHeaderView.Stretch)
- h.setResizeMode(1, QHeaderView.ResizeToContents)
+ h.setSectionResizeMode(0, QHeaderView.Stretch)
+ h.setSectionResizeMode(1, QHeaderView.ResizeToContents)
class ServerListWidget(QTreeWidget):
t@@ -163,7 +165,7 @@ class ServerListWidget(QTreeWidget):
# on 'enter' we show the menu
pt = self.visualItemRect(item).bottomLeft()
pt.setX(50)
- self.emit(SIGNAL('customContextMenuRequested(const QPoint&)'), pt)
+ self.customContextMenuRequested.emit(pt)
def update(self, servers, protocol, use_tor):
self.clear()
t@@ -179,8 +181,8 @@ class ServerListWidget(QTreeWidget):
h = self.header()
h.setStretchLastSection(False)
- h.setResizeMode(0, QHeaderView.Stretch)
- h.setResizeMode(1, QHeaderView.ResizeToContents)
+ h.setSectionResizeMode(0, QHeaderView.Stretch)
+ h.setSectionResizeMode(1, QHeaderView.ResizeToContents)
class NetworkChoiceLayout(object):
t@@ -251,13 +253,13 @@ class NetworkChoiceLayout(object):
self.proxy_password.editingFinished.connect(self.set_proxy)
self.check_disable_proxy()
- self.proxy_mode.connect(self.proxy_mode, SIGNAL('currentIndexChanged(int)'), self.check_disable_proxy)
+ self.proxy_mode.currentIndexChanged.connect(self.check_disable_proxy)
- self.proxy_mode.connect(self.proxy_mode, SIGNAL('currentIndexChanged(int)'), self.proxy_settings_changed)
- self.proxy_host.connect(self.proxy_host, SIGNAL('textEdited(QString)'), self.proxy_settings_changed)
- self.proxy_port.connect(self.proxy_port, SIGNAL('textEdited(QString)'), self.proxy_settings_changed)
- self.proxy_user.connect(self.proxy_user, SIGNAL('textEdited(QString)'), self.proxy_settings_changed)
- self.proxy_password.connect(self.proxy_password, SIGNAL('textEdited(QString)'), self.proxy_settings_changed)
+ self.proxy_mode.currentIndexChanged.connect(self.proxy_settings_changed)
+ self.proxy_host.textEdited.connect(self.proxy_settings_changed)
+ self.proxy_port.textEdited.connect(self.proxy_settings_changed)
+ self.proxy_user.textEdited.connect(self.proxy_settings_changed)
+ self.proxy_password.textEdited.connect(self.proxy_settings_changed)
self.tor_cb = QCheckBox(_("Use Tor Proxy"))
self.tor_cb.setIcon(QIcon(":icons/tor_logo.png"))
DIR diff --git a/gui/qt/password_dialog.py b/gui/qt/password_dialog.py
t@@ -28,8 +28,8 @@ from __future__ import print_function
from __future__ import unicode_literals
import six
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
from electrum.i18n import _
from .util import *
import re
DIR diff --git a/gui/qt/paytoedit.py b/gui/qt/paytoedit.py
t@@ -28,8 +28,9 @@ from __future__ import print_function
from __future__ import unicode_literals
import six
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtWidgets import QCompleter, QPlainTextEdit
from .qrtextedit import ScanQRTextEdit
import re
DIR diff --git a/gui/qt/qrcodewidget.py b/gui/qt/qrcodewidget.py
t@@ -4,9 +4,11 @@ from __future__ import print_function
from __future__ import unicode_literals
import six
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtGui as QtGui
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+import PyQt5.QtGui as QtGui
+from PyQt5.QtWidgets import (
+ QApplication, QVBoxLayout, QTextEdit, QHBoxLayout, QPushButton, QWidget)
import os
import qrcode
t@@ -95,6 +97,7 @@ class QRDialog(WindowModalDialog):
vbox = QVBoxLayout()
qrw = QRCodeWidget(data)
+ qscreen = QApplication.primaryScreen()
vbox.addWidget(qrw, 1)
if show_text:
text = QTextEdit()
t@@ -109,12 +112,12 @@ class QRDialog(WindowModalDialog):
filename = os.path.join(config.path, "qrcode.png")
def print_qr():
- p = QPixmap.grabWindow(qrw.winId())
+ p = qscreen.grabWindow(qrw.winId())
p.save(filename, 'png')
self.show_message(_("QR code saved to file") + " " + filename)
def copy_to_clipboard():
- p = QPixmap.grabWindow(qrw.winId())
+ p = qscreen.grabWindow(qrw.winId())
p.save(filename, 'png')
QApplication.clipboard().setImage(QImage(filename))
self.show_message(_("QR code copied to clipboard"))
DIR diff --git a/gui/qt/qrtextedit.py b/gui/qt/qrtextedit.py
t@@ -6,8 +6,9 @@ from __future__ import unicode_literals
import six
from electrum.i18n import _
from electrum.plugins import run_hook
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import QFileDialog
from .util import ButtonsTextEdit, MessageBoxMixin
t@@ -45,7 +46,7 @@ class ScanQRTextEdit(ButtonsTextEdit, MessageBoxMixin):
run_hook('scan_text_edit', self)
def file_input(self):
- fileName = QFileDialog.getOpenFileName(self, 'select file')
+ fileName, __ = QFileDialog.getOpenFileName(self, 'select file')
if not fileName:
return
with open(fileName, "r") as f:
DIR diff --git a/gui/qt/qrwindow.py b/gui/qt/qrwindow.py
t@@ -32,10 +32,11 @@ import re
import platform
from decimal import Decimal
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
-import PyQt4.QtGui as QtGui
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+import PyQt5.QtCore as QtCore
+import PyQt5.QtGui as QtGui
+from PyQt5.QtWidgets import (QHBoxLayout, QVBoxLayout, QLabel, QWidget)
from electrum_gui.qt.qrcodewidget import QRCodeWidget
from electrum.i18n import _
DIR diff --git a/gui/qt/request_list.py b/gui/qt/request_list.py
t@@ -33,8 +33,9 @@ from electrum.i18n import _
from electrum.util import block_explorer_URL, format_satoshis, format_time, age
from electrum.plugins import run_hook
from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import QTreeWidgetItem, QMenu
from .util import MyTreeWidget, pr_tooltips, pr_icons
t@@ -53,7 +54,7 @@ class RequestList(MyTreeWidget):
def item_changed(self, item):
if item is None:
return
- if not self.isItemSelected(item):
+ if not item.isSelected():
return
addr = str(item.text(1))
req = self.wallet.receive_requests[addr]
DIR diff --git a/gui/qt/seed_dialog.py b/gui/qt/seed_dialog.py
t@@ -28,8 +28,8 @@ from __future__ import print_function
from __future__ import unicode_literals
import six
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
from electrum.i18n import _
from .util import *
DIR diff --git a/gui/qt/transaction_dialog.py b/gui/qt/transaction_dialog.py
t@@ -32,10 +32,10 @@ import copy
import datetime
import json
-import PyQt4
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
+import PyQt5
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+import PyQt5.QtCore as QtCore
from electrum import transaction
from electrum.bitcoin import base_encode
DIR diff --git a/gui/qt/util.py b/gui/qt/util.py
t@@ -15,8 +15,9 @@ from collections import namedtuple
from functools import partial
from electrum.i18n import _
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
if platform.system() == 'Windows':
MONOSPACE_FONT = 'Lucida Console'
t@@ -57,10 +58,11 @@ expiration_values = [
class Timer(QThread):
stopped = False
+ timer_signal = pyqtSignal()
def run(self):
while not self.stopped:
- self.emit(SIGNAL('timersignal'))
+ self.timer_signal.emit()
time.sleep(0.5)
def stop(self):
t@@ -111,7 +113,7 @@ class HelpLabel(QLabel):
self.font = QFont()
def mouseReleaseEvent(self, x):
- QMessageBox.information(self, 'Help', self.help_text, 'OK')
+ QMessageBox.information(self, 'Help', self.help_text)
def enterEvent(self, event):
self.font.setUnderline(True)
t@@ -135,7 +137,7 @@ class HelpButton(QPushButton):
self.clicked.connect(self.onclick)
def onclick(self):
- QMessageBox.information(self, 'Help', self.help_text, 'OK')
+ QMessageBox.information(self, 'Help', self.help_text)
class Buttons(QHBoxLayout):
def __init__(self, *buttons):
t@@ -349,7 +351,7 @@ def filename_field(parent, config, defaultname, select_msg):
def func():
text = filename_e.text()
_filter = "*.csv" if text.endswith(".csv") else "*.json" if text.endswith(".json") else None
- p = QFileDialog.getSaveFileName(None, select_msg, text, _filter)
+ p, __ = QFileDialog.getSaveFileName(None, select_msg, text, _filter)
if p:
filename_e.setText(p)
t@@ -405,7 +407,7 @@ class MyTreeWidget(QTreeWidget):
self.header().setStretchLastSection(False)
for col in range(len(headers)):
sm = QHeaderView.Stretch if col == self.stretch_column else QHeaderView.ResizeToContents
- self.header().setResizeMode(col, sm)
+ self.header().setSectionResizeMode(col, sm)
def editItem(self, item, column):
if column in self.editable_columns:
t@@ -436,13 +438,12 @@ class MyTreeWidget(QTreeWidget):
# on 'enter' we show the menu
pt = self.visualItemRect(item).bottomLeft()
pt.setX(50)
- self.emit(SIGNAL('customContextMenuRequested(const QPoint&)'), pt)
+ self.customContextMenuRequested.emit(pt)
def createEditor(self, parent, option, index):
self.editor = QStyledItemDelegate.createEditor(self.itemDelegate(),
parent, option, index)
- self.editor.connect(self.editor, SIGNAL("editingFinished()"),
- self.editing_finished)
+ self.editor.editingFinished.connect(self.editing_finished)
return self.editor
def editing_finished(self):
t@@ -603,6 +604,6 @@ class TaskThread(QThread):
if __name__ == "__main__":
app = QApplication([])
- t = WaitingDialog(None, 'testing ...', lambda: [time.sleep(1)], lambda x: QMessageBox.information(None, 'done', "done", _('OK')))
+ t = WaitingDialog(None, 'testing ...', lambda: [time.sleep(1)], lambda x: QMessageBox.information(None, 'done', "done"))
t.start()
app.exec_()
DIR diff --git a/lib/plot.py b/lib/plot.py
t@@ -1,4 +1,4 @@
-from PyQt4.QtGui import *
+from PyQt5.QtGui import *
from electrum.i18n import _
t@@ -9,7 +9,7 @@ from electrum.util import format_satoshis
from electrum.bitcoin import COIN
import matplotlib
-matplotlib.use('Qt4Agg')
+matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as md
from matplotlib.patches import Ellipse
DIR diff --git a/plugins/audio_modem/qt.py b/plugins/audio_modem/qt.py
t@@ -10,8 +10,9 @@ from electrum_gui.qt.util import WaitingDialog, EnterButton, WindowModalDialog
from electrum.util import print_msg, print_error
from electrum.i18n import _
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import (QComboBox, QGridLayout, QLabel, QPushButton)
try:
import amodem.audio
DIR diff --git a/plugins/cosigner_pool/qt.py b/plugins/cosigner_pool/qt.py
t@@ -28,8 +28,9 @@ import threading
import time
from xmlrpc.client import ServerProxy
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import QPushButton
from electrum import bitcoin, util
from electrum import transaction
t@@ -82,19 +83,23 @@ class Listener(util.DaemonThread):
if message:
self.received.add(keyhash)
self.print_error("received message for", keyhash)
- self.parent.obj.emit(SIGNAL("cosigner:receive"), keyhash,
- message)
+ self.parent.obj.cosigner_receive_signal.emit(
+ keyhash, message)
# poll every 30 seconds
time.sleep(30)
+class QReceiveSignalObject(QObject):
+ cosigner_receive_signal = pyqtSignal(object, object)
+
+
class Plugin(BasePlugin):
def __init__(self, parent, config, name):
BasePlugin.__init__(self, parent, config, name)
self.listener = None
- self.obj = QObject()
- self.obj.connect(self.obj, SIGNAL('cosigner:receive'), self.on_receive)
+ self.obj = QReceiveSignalObject()
+ self.obj.cosigner_receive_signal.connect(self.on_receive)
self.keys = []
self.cosigner_list = []
DIR diff --git a/plugins/digitalbitbox/qt.py b/plugins/digitalbitbox/qt.py
t@@ -1,4 +1,4 @@
-from PyQt4.Qt import (QInputDialog, QLineEdit)
+from PyQt5.QtWidgets import (QInputDialog, QLineEdit)
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
from .digitalbitbox import DigitalBitboxPlugin
DIR diff --git a/plugins/email_requests/qt.py b/plugins/email_requests/qt.py
t@@ -35,10 +35,11 @@ from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.encoders import encode_base64
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
-import PyQt4.QtCore as QtCore
-import PyQt4.QtGui as QtGui
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+import PyQt5.QtCore as QtCore
+import PyQt5.QtGui as QtGui
+from PyQt5.QtWidgets import (QVBoxLayout, QLabel, QGridLayout, QLineEdit)
from electrum.plugins import BasePlugin, hook
from electrum.paymentrequest import PaymentRequest
t@@ -102,6 +103,10 @@ class Processor(threading.Thread):
s.quit()
+class QEmailSignalObject(QObject):
+ email_new_invoice_signal = pyqtSignal()
+
+
class Plugin(BasePlugin):
def fullname(self):
t@@ -121,13 +126,13 @@ class Plugin(BasePlugin):
if self.imap_server and self.username and self.password:
self.processor = Processor(self.imap_server, self.username, self.password, self.on_receive)
self.processor.start()
- self.obj = QObject()
- self.obj.connect(self.obj, SIGNAL('email:new_invoice'), self.new_invoice)
+ self.obj = QEmailSignalObject()
+ self.obj.email_new_invoice_signal.connect(self.new_invoice)
def on_receive(self, pr_str):
self.print_error('received payment request')
self.pr = PaymentRequest(pr_str)
- self.obj.emit(SIGNAL('email:new_invoice'))
+ self.obj.email_new_invoice_signal.emit()
def new_invoice(self):
self.parent.invoices.add(self.pr)
DIR diff --git a/plugins/greenaddress_instant/qt.py b/plugins/greenaddress_instant/qt.py
t@@ -28,7 +28,7 @@ import urllib
import sys
import requests
-from PyQt4.QtGui import QApplication, QPushButton
+from PyQt5.QtWidgets import QApplication, QPushButton
from electrum.plugins import BasePlugin, hook
from electrum.i18n import _
DIR diff --git a/plugins/hw_wallet/qt.py b/plugins/hw_wallet/qt.py
t@@ -26,7 +26,7 @@
import threading
-from PyQt4.Qt import QVBoxLayout, QLabel, SIGNAL
+from PyQt5.Qt import QVBoxLayout, QLabel
from electrum_gui.qt.password_dialog import PasswordDialog, PW_PASSPHRASE
from electrum_gui.qt.util import *
DIR diff --git a/plugins/labels/qt.py b/plugins/labels/qt.py
t@@ -1,7 +1,8 @@
from functools import partial
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import (QHBoxLayout, QLabel, QVBoxLayout)
from electrum.plugins import hook
from electrum.i18n import _
t@@ -12,11 +13,15 @@ from electrum_gui.qt.util import WindowModalDialog, OkButton
from .labels import LabelsPlugin
+class QLabelsSignalObject(QObject):
+ labels_changed_signal = pyqtSignal(object)
+
+
class Plugin(LabelsPlugin):
def __init__(self, *args):
LabelsPlugin.__init__(self, *args)
- self.obj = QObject()
+ self.obj = QLabelsSignalObject()
def requires_settings(self):
return True
t@@ -47,14 +52,14 @@ class Plugin(LabelsPlugin):
return bool(d.exec_())
def on_pulled(self, wallet):
- self.obj.emit(SIGNAL('labels_changed'), wallet)
+ self.obj.labels_changed_signal.emit(wallet)
def done_processing(self, dialog, result):
dialog.show_message(_("Your labels have been synchronised."))
@hook
def on_new_window(self, window):
- window.connect(window.app, SIGNAL('labels_changed'), window.update_tabs)
+ self.obj.labels_changed_signal.connect(window.update_tabs)
self.start_wallet(window.wallet)
@hook
DIR diff --git a/plugins/ledger/auth2fa.py b/plugins/ledger/auth2fa.py
t@@ -1,8 +1,9 @@
from binascii import hexlify, unhexlify
import threading
-from PyQt4.Qt import (QDialog, QInputDialog, QLineEdit, QTextEdit, QVBoxLayout, QLabel, SIGNAL)
-import PyQt4.QtCore as QtCore
+from PyQt5.Qt import (QDialog, QInputDialog, QLineEdit, QTextEdit, QVBoxLayout, QLabel)
+import PyQt5.QtCore as QtCore
+from PyQt5.QtWidgets import *
from electrum.i18n import _
from electrum_gui.qt.util import *
DIR diff --git a/plugins/ledger/qt.py b/plugins/ledger/qt.py
t@@ -1,8 +1,8 @@
import threading
-from PyQt4.Qt import (QDialog, QInputDialog, QLineEdit,
- QVBoxLayout, QLabel, SIGNAL)
-import PyQt4.QtCore as QtCore
+from PyQt5.Qt import (QDialog, QInputDialog, QLineEdit,
+ QVBoxLayout, QLabel)
+import PyQt5.QtCore as QtCore
from electrum.i18n import _
from .ledger import LedgerPlugin
DIR diff --git a/plugins/trezor/qt_generic.py b/plugins/trezor/qt_generic.py
t@@ -1,9 +1,9 @@
from functools import partial
import threading
-from PyQt4.Qt import Qt
-from PyQt4.Qt import QGridLayout, QInputDialog, QPushButton
-from PyQt4.Qt import QVBoxLayout, QLabel, SIGNAL
+from PyQt5.Qt import Qt
+from PyQt5.Qt import QGridLayout, QInputDialog, QPushButton
+from PyQt5.Qt import QVBoxLayout, QLabel
from electrum_gui.qt.util import *
from .plugin import TIM_NEW, TIM_RECOVER, TIM_MNEMONIC
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
t@@ -377,7 +377,7 @@ class SettingsDialog(WindowModalDialog):
def change_homescreen():
from PIL import Image # FIXME
dialog = QFileDialog(self, _("Choose Homescreen"))
- filename = dialog.getOpenFileName()
+ filename, __ = dialog.getOpenFileName()
if filename:
im = Image.open(str(filename))
if im.size != (hs_cols, hs_rows):
DIR diff --git a/plugins/trustedcoin/qt.py b/plugins/trustedcoin/qt.py
t@@ -28,8 +28,8 @@ from threading import Thread
import re
from decimal import Decimal
-from PyQt4.QtGui import *
-from PyQt4.QtCore import *
+from PyQt5.QtGui import *
+from PyQt5.QtCore import *
from electrum_gui.qt.util import *
from electrum_gui.qt.qrcodewidget import QRCodeWidget
t@@ -40,8 +40,16 @@ from electrum.plugins import hook
from .trustedcoin import TrustedCoinPlugin, server
+class QTOSSignalObject(QObject):
+ two_factor_tos_signal = pyqtSignal()
+
+
class Plugin(TrustedCoinPlugin):
+ def __init__(self, parent, config, name):
+ super().__init__(parent, config, name)
+ self.tos_signal_obj = QTOSSignalObject()
+
@hook
def on_new_window(self, window):
wallet = window.wallet
t@@ -196,7 +204,7 @@ class Plugin(TrustedCoinPlugin):
def request_TOS():
tos = server.get_terms_of_service()
self.TOS = tos
- window.emit(SIGNAL('twofactor:TOS'))
+ self.tos_signal_obj.two_factor_tos_signal.emit()
def on_result():
tos_e.setText(self.TOS)
t@@ -204,7 +212,7 @@ class Plugin(TrustedCoinPlugin):
def set_enabled():
next_button.setEnabled(re.match(regexp,email_e.text()) is not None)
- window.connect(window, SIGNAL('twofactor:TOS'), on_result)
+ self.tos_signal_obj.two_factor_tos_signal.connect(on_result)
t = Thread(target=request_TOS)
t.setDaemon(True)
t.start()
DIR diff --git a/plugins/virtualkeyboard/qt.py b/plugins/virtualkeyboard/qt.py
t@@ -1,4 +1,5 @@
-from PyQt4.QtGui import *
+from PyQt5.QtGui import *
+from PyQt5.QtWidgets import (QVBoxLayout, QGridLayout, QPushButton)
from electrum.plugins import BasePlugin, hook
from electrum.i18n import _
import random
DIR diff --git a/setup-release.py b/setup-release.py
t@@ -34,7 +34,7 @@ if sys.platform == 'darwin':
setup_requires=['py2app'],
app=[mainscript],
options=dict(py2app=dict(argv_emulation=False,
- includes=['PyQt4.QtCore', 'PyQt4.QtGui', 'PyQt4.QtWebKit', 'PyQt4.QtNetwork', 'sip'],
+ includes=['PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWebKit', 'PyQt5.QtNetwork', 'sip'],
packages=['lib', 'gui', 'plugins'],
iconfile='electrum.icns',
plist=plist,