1
0

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

This commit is contained in:
SomberNight
2022-08-10 19:53:36 +02:00
parent 05863a611f
commit 388811296e
14 changed files with 81 additions and 54 deletions

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)))

View File

@@ -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")))

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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)

View File

@@ -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.

View File

@@ -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)

View File

@@ -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)