Browse Source

qt: replace some hardcoded pixel sizes for better high-dpi support

master
SomberNight 3 years ago
parent
commit
388811296e
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 26
      electrum/gui/qt/balance_dialog.py
  2. 13
      electrum/gui/qt/channels_list.py
  3. 4
      electrum/gui/qt/console.py
  4. 4
      electrum/gui/qt/exception_window.py
  5. 4
      electrum/gui/qt/installwizard.py
  6. 4
      electrum/gui/qt/lightning_tx_dialog.py
  7. 16
      electrum/gui/qt/main_window.py
  8. 26
      electrum/gui/qt/new_channel_dialog.py
  9. 4
      electrum/gui/qt/seed_dialog.py
  10. 5
      electrum/gui/qt/send_tab.py
  11. 5
      electrum/gui/qt/swap_dialog.py
  12. 9
      electrum/gui/qt/util.py
  13. 2
      electrum/gui/qt/watchtower_dialog.py
  14. 13
      electrum/plugins/virtualkeyboard/qt.py

26
electrum/gui/qt/balance_dialog.py

@ -25,19 +25,16 @@
from typing import TYPE_CHECKING
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (QVBoxLayout, QCheckBox, QHBoxLayout, QLineEdit,
QLabel, QCompleter, QDialog, QStyledItemDelegate,
QScrollArea, QWidget, QPushButton, QGridLayout, QToolButton)
from PyQt5.QtCore import QRect, QEventLoop, Qt, pyqtSignal
from PyQt5.QtGui import QPalette, QPen, QPainter, QPixmap
from electrum.i18n import _
from .util import Buttons, CloseButton, WindowModalDialog, ColorScheme
from .util import Buttons, CloseButton, WindowModalDialog, ColorScheme, font_height
if TYPE_CHECKING:
from .main_window import ElectrumWindow
@ -100,7 +97,7 @@ class BalanceToolButton(QToolButton, PieChartObject):
def __init__(self):
QToolButton.__init__(self)
self.size = 18
self.size = max(18, font_height())
self._list = []
self.R = QRect(6, 3, self.size, self.size)
@ -167,14 +164,17 @@ class BalanceDialog(WindowModalDialog):
lightning_fiat_str = self.fx.format_amount_and_units(lightning) if self.fx else ''
f_lightning_fiat_str = self.fx.format_amount_and_units(f_lightning) if self.fx else ''
piechart = PieChartWidget(120, [
(_('Frozen'), COLOR_FROZEN, frozen),
(_('Unmatured'), COLOR_UNMATURED, unmatured),
(_('Unconfirmed'), COLOR_UNCONFIRMED, unconfirmed),
(_('On-chain'), COLOR_CONFIRMED, confirmed),
(_('Lightning'), COLOR_LIGHTNING, lightning),
(_('Lightning frozen'), COLOR_FROZEN_LIGHTNING, f_lightning),
])
piechart = PieChartWidget(
max(120, 9 * font_height()),
[
(_('Frozen'), COLOR_FROZEN, frozen),
(_('Unmatured'), COLOR_UNMATURED, unmatured),
(_('Unconfirmed'), COLOR_UNCONFIRMED, unconfirmed),
(_('On-chain'), COLOR_CONFIRMED, confirmed),
(_('Lightning'), COLOR_LIGHTNING, lightning),
(_('Lightning frozen'), COLOR_FROZEN_LIGHTNING, f_lightning),
]
)
vbox = QVBoxLayout()
vbox.addWidget(piechart)

13
electrum/gui/qt/channels_list.py

@ -22,7 +22,7 @@ from electrum.gui import messages
from .util import (MyTreeView, WindowModalDialog, Buttons, OkButton, CancelButton,
EnterButton, WaitingDialog, MONOSPACE_FONT, ColorScheme)
from .amountedit import BTCAmountEdit, FreezableLineEdit
from .util import read_QIcon
from .util import read_QIcon, font_height
ROLE_CHANNEL_ID = Qt.UserRole
@ -442,9 +442,10 @@ class ChanFeatNoOnchainBackup(ChannelFeature):
class ChannelFeatureIcons:
ICON_SIZE = QSize(16, 16)
def __init__(self, features: Sequence['ChannelFeature']):
size = max(16, font_height())
self.icon_size = QSize(size, size)
self.features = features
@classmethod
@ -466,17 +467,17 @@ class ChannelFeatureIcons:
painter.save()
cur_x = rect.x()
for feat in self.features:
icon_rect = QRect(cur_x, rect.y(), self.ICON_SIZE.width(), self.ICON_SIZE.height())
icon_rect = QRect(cur_x, rect.y(), self.icon_size.width(), self.icon_size.height())
feat.rect = icon_rect
if rect.contains(icon_rect): # stay inside parent
painter.drawPixmap(icon_rect, feat.icon().pixmap(self.ICON_SIZE))
cur_x += self.ICON_SIZE.width() + 1
painter.drawPixmap(icon_rect, feat.icon().pixmap(self.icon_size))
cur_x += self.icon_size.width() + 1
painter.restore()
def sizeHint(self, default_size: QSize) -> QSize:
if not self.features:
return default_size
width = len(self.features) * (self.ICON_SIZE.width() + 1)
width = len(self.features) * (self.icon_size.width() + 1)
return QSize(width, default_size.height())
def show_tooltip(self, evt: QHelpEvent) -> bool:

4
electrum/gui/qt/console.py

@ -13,7 +13,7 @@ from PyQt5 import QtWidgets
from electrum import util
from electrum.i18n import _
from .util import MONOSPACE_FONT
from .util import MONOSPACE_FONT, font_height
# sys.ps1 and sys.ps2 are only declared if an interpreter is in interactive mode.
sys.ps1 = '>>> '
@ -32,7 +32,7 @@ class OverlayLabel(QtWidgets.QLabel):
'''
def __init__(self, text, parent):
super().__init__(text, parent)
self.setMinimumHeight(150)
self.setMinimumHeight(max(150, 10 * font_height()))
self.setGeometry(0, 0, self.width(), self.height())
self.setStyleSheet(self.STYLESHEET)
self.setMargin(0)

4
electrum/gui/qt/exception_window.py

@ -36,7 +36,7 @@ from electrum.logging import Logger
from electrum import constants
from electrum.network import Network
from .util import MessageBoxMixin, read_QIcon, WaitingDialog
from .util import MessageBoxMixin, read_QIcon, WaitingDialog, font_height
if TYPE_CHECKING:
from electrum.simple_config import SimpleConfig
@ -76,7 +76,7 @@ class Exception_Window(BaseCrashReporter, QWidget, MessageBoxMixin, Logger):
main_box.addWidget(QLabel(BaseCrashReporter.DESCRIBE_ERROR_MESSAGE))
self.description_textfield = QTextEdit()
self.description_textfield.setFixedHeight(50)
self.description_textfield.setFixedHeight(4 * font_height())
self.description_textfield.setPlaceholderText(self.USER_COMMENT_PLACEHOLDER)
main_box.addWidget(self.description_textfield)

4
electrum/gui/qt/installwizard.py

@ -26,7 +26,7 @@ from electrum.i18n import _
from .seed_dialog import SeedLayout, KeysLayout
from .network_dialog import NetworkChoiceLayout
from .util import (MessageBoxMixin, Buttons, icon_path, ChoicesLayout, WWLabel,
InfoButton, char_width_in_lineedit, PasswordLineEdit)
InfoButton, char_width_in_lineedit, PasswordLineEdit, font_height)
from .password_dialog import PasswordLayout, PasswordLayoutForHW, PW_NEW
from .bip39_recovery_dialog import Bip39RecoveryDialog
from electrum.plugin import run_hook, Plugins
@ -58,10 +58,10 @@ MSG_PASSPHRASE_WARN_ISSUE4566 = _("Warning") + ": "\
class CosignWidget(QWidget):
size = 120
def __init__(self, m, n):
QWidget.__init__(self)
self.size = max(120, 9 * font_height())
self.R = QRect(0, 0, self.size, self.size)
self.setGeometry(self.R)
self.setMinimumHeight(self.size)

4
electrum/gui/qt/lightning_tx_dialog.py

@ -33,7 +33,7 @@ from PyQt5.QtWidgets import QVBoxLayout, QLabel, QGridLayout
from electrum.i18n import _
from electrum.lnworker import PaymentDirection
from .util import WindowModalDialog, ShowQRLineEdit, ColorScheme, Buttons, CloseButton, MONOSPACE_FONT
from .util import WindowModalDialog, ShowQRLineEdit, ColorScheme, Buttons, CloseButton, font_height
from .qrtextedit import ShowQRTextEdit
if TYPE_CHECKING:
@ -80,7 +80,7 @@ class LightningTxDialog(WindowModalDialog):
vbox.addWidget(self.preimage_e)
vbox.addWidget(QLabel(_("Lightning Invoice") + ":"))
self.invoice_e = ShowQRTextEdit(self.invoice, config=self.config)
self.invoice_e.setMaximumHeight(150)
self.invoice_e.setMaximumHeight(max(150, 10 * font_height()))
self.invoice_e.addCopyButton()
vbox.addWidget(self.invoice_e)
vbox.addLayout(Buttons(CloseButton(self)))

16
electrum/gui/qt/main_window.py

@ -38,7 +38,7 @@ import asyncio
from typing import Optional, TYPE_CHECKING, Sequence, List, Union, Dict, Set
import concurrent.futures
from PyQt5.QtGui import QPixmap, QKeySequence, QIcon, QCursor, QFont
from PyQt5.QtGui import QPixmap, QKeySequence, QIcon, QCursor, QFont, QFontMetrics
from PyQt5.QtCore import Qt, QRect, QStringListModel, QSize, pyqtSignal
from PyQt5.QtWidgets import (QMessageBox, QSystemTrayIcon, QTabWidget,
QMenuBar, QFileDialog, QCheckBox, QLabel,
@ -88,7 +88,7 @@ from .util import (read_QIcon, ColorScheme, text_dialog, icon_path, WaitingDialo
import_meta_gui, export_meta_gui,
filename_field, address_field, char_width_in_lineedit, webopen,
TRANSACTION_FILE_EXTENSION_FILTER_ANY, MONOSPACE_FONT,
getOpenFileName, getSaveFileName, BlockingWaitingDialog)
getOpenFileName, getSaveFileName, BlockingWaitingDialog, font_height)
from .util import ButtonsLineEdit, ShowQRLineEdit
from .util import QtEventListener, qt_event_listener, event_listener
from .installwizard import WIF_HELP_TEXT
@ -117,10 +117,11 @@ class StatusBarButton(QToolButton):
self.setToolTip(tooltip)
self.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.setAutoRaise(True)
self.setMaximumWidth(25)
size = max(25, round(1.8 * font_height()))
self.setMaximumWidth(size)
self.clicked.connect(self.onPress)
self.func = func
self.setIconSize(QSize(25,25))
self.setIconSize(QSize(size, size))
self.setCursor(QCursor(Qt.PointingHandCursor))
def onPress(self, checked=False):
@ -1528,13 +1529,16 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
def create_status_bar(self):
sb = QStatusBar()
sb.setFixedHeight(35)
self.balance_label = BalanceToolButton()
self.balance_label.setText("Loading wallet...")
self.balance_label.setAutoRaise(True)
self.balance_label.clicked.connect(self.show_balance_dialog)
sb.addWidget(self.balance_label)
font_height = QFontMetrics(self.balance_label.font()).height()
sb_height = max(35, int(2 * font_height))
sb.setFixedHeight(sb_height)
# remove border of all items in status bar
self.setStyleSheet("QStatusBar::item { border: 0px;} ")
@ -1813,7 +1817,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
ks_w.setLayout(ks_vbox)
mpk_text = ShowQRTextEdit(ks.get_master_public_key(), config=self.config)
mpk_text.setMaximumHeight(150)
mpk_text.setMaximumHeight(max(150, 10 * font_height()))
mpk_text.addCopyButton()
run_hook('show_xpub_button', mpk_text, ks)
ks_vbox.addWidget(WWLabel(_("Master Public Key")))

26
electrum/gui/qt/new_channel_dialog.py

@ -1,6 +1,6 @@
from typing import TYPE_CHECKING, Optional
from PyQt5.QtWidgets import QLabel, QVBoxLayout, QGridLayout, QPushButton, QComboBox, QLineEdit
from PyQt5.QtWidgets import QLabel, QVBoxLayout, QGridLayout, QPushButton, QComboBox, QLineEdit, QSpacerItem, QWidget, QHBoxLayout
from electrum.i18n import _
from electrum.transaction import PartialTxOutput, PartialTransaction
@ -11,7 +11,8 @@ from electrum.util import NotEnoughFunds, NoDynamicFeeEstimates
from .util import (WindowModalDialog, Buttons, OkButton, CancelButton,
EnterButton, ColorScheme, WWLabel, read_QIcon, IconLabel)
EnterButton, ColorScheme, WWLabel, read_QIcon, IconLabel,
char_width_in_lineedit)
from .amountedit import BTCAmountEdit
@ -49,14 +50,17 @@ class NewChannelDialog(WindowModalDialog):
self.trampoline_combo.setCurrentIndex(1)
self.amount_e = BTCAmountEdit(self.window.get_decimal_point)
self.amount_e.setAmount(amount_sat)
btn_width = 10 * char_width_in_lineedit()
self.min_button = EnterButton(_("Min"), self.spend_min)
self.min_button.setEnabled(bool(self.min_amount_sat))
self.min_button.setFixedWidth(btn_width)
self.max_button = EnterButton(_("Max"), self.spend_max)
self.max_button.setFixedWidth(100)
self.max_button.setFixedWidth(btn_width)
self.max_button.setCheckable(True)
self.clear_button = QPushButton(self, text=_('Clear'))
self.clear_button.clicked.connect(self.on_clear)
self.clear_button.setFixedWidth(100)
self.clear_button.setFixedWidth(btn_width)
h = QGridLayout()
if self.network.channel_db:
h.addWidget(QLabel(_('Remote Node ID')), 0, 0)
@ -66,10 +70,16 @@ class NewChannelDialog(WindowModalDialog):
h.addWidget(QLabel(_('Remote Node')), 0, 0)
h.addWidget(self.trampoline_combo, 0, 1, 1, 4)
h.addWidget(QLabel('Amount'), 2, 0)
h.addWidget(self.amount_e, 2, 1)
h.addWidget(self.min_button, 2, 2)
h.addWidget(self.max_button, 2, 3)
h.addWidget(self.clear_button, 2, 4)
amt_hbox = QHBoxLayout()
amt_hbox.setContentsMargins(0, 0, 0, 0)
amt_hbox.addWidget(self.amount_e)
amt_hbox.addWidget(self.min_button)
amt_hbox.addWidget(self.max_button)
amt_hbox.addWidget(self.clear_button)
amt_hbox.addStretch()
h.addLayout(amt_hbox, 2, 1, 1, 4)
vbox.addLayout(h)
vbox.addStretch()
ok_button = OkButton(self)

4
electrum/gui/qt/seed_dialog.py

@ -38,7 +38,7 @@ from electrum import slip39
from .util import (Buttons, OkButton, WWLabel, ButtonsTextEdit, icon_path,
EnterButton, CloseButton, WindowModalDialog, ColorScheme,
ChoicesLayout)
ChoicesLayout, font_height)
from .qrtextedit import ShowQRTextEdit, ScanQRTextEdit
from .completion_text_edit import CompletionTextEdit
@ -157,7 +157,7 @@ class SeedLayout(QVBoxLayout):
self.seed_e.textChanged.connect(self.on_edit)
self.initialize_completer()
self.seed_e.setMaximumHeight(75)
self.seed_e.setMaximumHeight(max(75, 5 * font_height()))
hbox = QHBoxLayout()
if icon:
logo = QLabel()

5
electrum/gui/qt/send_tab.py

@ -26,7 +26,7 @@ from electrum.lnaddr import lndecode, LnInvoiceException
from electrum.lnurl import decode_lnurl, request_lnurl, callback_lnurl, LNURLError, LNURL6Data
from .amountedit import AmountEdit, BTCAmountEdit, SizedFreezableLineEdit
from .util import WaitingDialog, HelpLabel, MessageBoxMixin, EnterButton
from .util import WaitingDialog, HelpLabel, MessageBoxMixin, EnterButton, char_width_in_lineedit
from .confirm_tx_dialog import ConfirmTxDialog
from .transaction_dialog import PreviewTxDialog
@ -119,7 +119,8 @@ class SendTab(QWidget, MessageBoxMixin, Logger):
self.window.connect_fields(self.amount_e, self.fiat_send_e)
self.max_button = EnterButton(_("Max"), self.spend_max)
self.max_button.setFixedWidth(100)
btn_width = 10 * char_width_in_lineedit()
self.max_button.setFixedWidth(btn_width)
self.max_button.setCheckable(True)
grid.addWidget(self.max_button, 3, 3)

5
electrum/gui/qt/swap_dialog.py

@ -9,7 +9,7 @@ from electrum.lnutil import ln_dummy_address
from electrum.transaction import PartialTxOutput, PartialTransaction
from .util import (WindowModalDialog, Buttons, OkButton, CancelButton,
EnterButton, ColorScheme, WWLabel, read_QIcon, IconLabel)
EnterButton, ColorScheme, WWLabel, read_QIcon, IconLabel, char_width_in_lineedit)
from .amountedit import BTCAmountEdit
from .fee_slider import FeeSlider, FeeComboBox
@ -43,7 +43,8 @@ class SwapDialog(WindowModalDialog):
self.send_amount_e = BTCAmountEdit(self.window.get_decimal_point)
self.recv_amount_e = BTCAmountEdit(self.window.get_decimal_point)
self.max_button = EnterButton(_("Max"), self.spend_max)
self.max_button.setFixedWidth(100)
btn_width = 10 * char_width_in_lineedit()
self.max_button.setFixedWidth(btn_width)
self.max_button.setCheckable(True)
self.toggle_button = QPushButton(u'\U000021c4')
self.toggle_button.setEnabled(is_reverse is None)

9
electrum/gui/qt/util.py

@ -1403,10 +1403,11 @@ def read_QIcon(icon_basename):
return QIcon(icon_path(icon_basename))
class IconLabel(QWidget):
IconSize = QSize(16, 16)
HorizontalSpacing = 2
def __init__(self, *, text='', final_stretch=True):
super(QWidget, self).__init__()
size = max(16, font_height())
self.icon_size = QSize(size, size)
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(layout)
@ -1421,7 +1422,7 @@ class IconLabel(QWidget):
def setText(self, text):
self.label.setText(text)
def setIcon(self, icon):
self.icon.setPixmap(icon.pixmap(self.IconSize))
self.icon.setPixmap(icon.pixmap(self.icon_size))
self.icon.repaint() # macOS hack for #6269
def get_default_language():
@ -1435,6 +1436,10 @@ def char_width_in_lineedit() -> int:
return max(9, char_width)
def font_height() -> int:
return QFontMetrics(QLabel().font()).height()
def webopen(url: str):
if sys.platform == 'linux' and os.environ.get('APPIMAGE'):
# When on Linux webbrowser.open can fail in AppImage because it can't find the correct libdbus.

2
electrum/gui/qt/watchtower_dialog.py

@ -67,7 +67,7 @@ class WatchtowerDialog(QDialog):
assert self.network
self.lnwatcher = self.network.local_watchtower
self.setWindowTitle(_('Watchtower'))
self.setMinimumSize(600, 20)
self.setMinimumSize(600, 200)
self.size_label = QLabel()
self.watcher_list = WatcherList(self)

13
electrum/plugins/virtualkeyboard/qt.py

@ -1,6 +1,7 @@
import random
from PyQt5.QtWidgets import (QVBoxLayout, QGridLayout, QPushButton)
from PyQt5.QtGui import QFontMetrics
from electrum.plugin import BasePlugin, hook
from electrum.i18n import _
@ -12,8 +13,9 @@ class Plugin(BasePlugin):
@hook
def password_dialog(self, pw, grid, pos):
vkb_button = QPushButton(_("+"))
vkb_button.setFixedWidth(20)
vkb_button = QPushButton("+")
font_height = QFontMetrics(vkb_button.font()).height()
vkb_button.setFixedWidth(round(1.7 * font_height))
vkb_button.clicked.connect(lambda: self.toggle_vkb(grid, pw))
grid.addWidget(vkb_button, pos, 2)
self.kb_pos = 2
@ -47,13 +49,16 @@ class Plugin(BasePlugin):
def add_target(t):
return lambda: pw.setText(str(pw.text()) + t)
font_height = QFontMetrics(QPushButton().font()).height()
btn_size = max(25, round(1.7 * font_height))
vbox = QVBoxLayout()
grid = QGridLayout()
grid.setSpacing(2)
for i in range(n):
l_button = QPushButton(chars[s[i]])
l_button.setFixedWidth(25)
l_button.setFixedHeight(25)
l_button.setFixedWidth(btn_size)
l_button.setFixedHeight(btn_size)
l_button.clicked.connect(add_target(chars[s[i]]))
grid.addWidget(l_button, i // 6, i % 6)

Loading…
Cancel
Save