1
0

Merge pull request #7909 from SomberNight/202207_qt_receive_tab_macos

Qt receive_tab: fix receive_tabs widget on macOS
This commit is contained in:
ThomasV
2022-07-31 11:32:01 +02:00
committed by GitHub
2 changed files with 66 additions and 44 deletions

View File

@@ -155,7 +155,7 @@ class ReceiveTab(QWidget, MessageBoxMixin, Logger):
from .util import VTabWidget
self.receive_tabs = VTabWidget()
self.receive_tabs.setMinimumHeight(ReceiveTabWidget.min_size.height() + 4) # for margins
#self.receive_tabs.setMinimumHeight(ReceiveTabWidget.min_size.height() + 4) # for margins
self.receive_tabs.addTab(self.receive_URI_widget, read_QIcon("link.png"), _('URI'))
self.receive_tabs.addTab(self.receive_address_widget, read_QIcon("bitcoin.png"), _('Address'))
self.receive_tabs.addTab(self.receive_lightning_widget, read_QIcon("lightning.png"), _('Lightning'))
@@ -395,7 +395,7 @@ class ReceiveTab(QWidget, MessageBoxMixin, Logger):
class ReceiveTabWidget(QWidget):
min_size = QSize(200, 200)
def __init__(self, receive_tab: 'ReceiveTab', textedit, qr, help_widget):
def __init__(self, receive_tab: 'ReceiveTab', textedit: QWidget, qr: QWidget, help_widget: QWidget):
self.textedit = textedit
self.qr = qr
self.help_widget = help_widget

View File

@@ -12,6 +12,7 @@ from functools import partial, lru_cache, wraps
from typing import (NamedTuple, Callable, Optional, TYPE_CHECKING, Union, List, Dict, Any,
Sequence, Iterable, Tuple)
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtGui import (QFont, QColor, QCursor, QPixmap, QStandardItem, QImage,
QPalette, QIcon, QFontMetrics, QShowEvent, QPainter, QHelpEvent)
from PyQt5.QtCore import (Qt, QPersistentModelIndex, QModelIndex, pyqtSignal,
@@ -24,7 +25,7 @@ from PyQt5.QtWidgets import (QPushButton, QLabel, QMessageBox, QHBoxLayout,
QFileDialog, QWidget, QToolButton, QTreeView, QPlainTextEdit,
QHeaderView, QApplication, QToolTip, QTreeWidget, QStyledItemDelegate,
QMenu, QStyleOptionViewItem, QLayout, QLayoutItem, QAbstractButton,
QGraphicsEffect, QGraphicsScene, QGraphicsPixmapItem)
QGraphicsEffect, QGraphicsScene, QGraphicsPixmapItem, QSizePolicy)
from electrum.i18n import _, languages
from electrum.util import FileImportFailed, FileExportFailed, make_aiohttp_session, resource_path
@@ -1570,54 +1571,75 @@ class ImageGraphicsEffect(QObject):
return result
# vertical tabs
# from https://stackoverflow.com/questions/51230544/pyqt5-how-to-set-tabwidget-west-but-keep-the-text-horizontal
from PyQt5 import QtWidgets, QtCore
class VTabBar(QtWidgets.QTabBar):
def tabSizeHint(self, index):
s = QtWidgets.QTabBar.tabSizeHint(self, index)
s.transpose()
return s
def paintEvent(self, event):
painter = QtWidgets.QStylePainter(self)
opt = QtWidgets.QStyleOptionTab()
for i in range(self.count()):
self.initStyleOption(opt, i)
painter.drawControl(QtWidgets.QStyle.CE_TabBarTabShape, opt)
painter.save()
s = opt.rect.size()
s.transpose()
r = QtCore.QRect(QtCore.QPoint(), s)
r.moveCenter(opt.rect.center())
opt.rect = r
c = self.tabRect(i).center()
painter.translate(c)
painter.rotate(90)
painter.translate(-c)
painter.drawControl(QtWidgets.QStyle.CE_TabBarTabLabel, opt);
painter.restore()
class VTabWidget(QtWidgets.QTabWidget):
def __init__(self, *args, **kwargs):
QtWidgets.QTabWidget.__init__(self, *args, **kwargs)
self.setTabBar(VTabBar(self))
self.setTabPosition(QtWidgets.QTabWidget.West)
class SquareTabWidget(QtWidgets.QTabWidget):
def resizeEvent(self, e):
# keep square aspect ratio when resized
size = e.size()
w = self.tabBar().width() + size.height()
w = size.height()
w += self.tabBar().width() if self.tabBar().isVisible() else 0
self.setFixedWidth(w)
return super().resizeEvent(e)
class VTabWidget(QWidget):
"""QtWidgets.QTabWidget alternative with "West" tab positions and horizontal tab-text."""
def __init__(self):
QWidget.__init__(self)
hbox = QHBoxLayout()
self.setLayout(hbox)
hbox.setContentsMargins(0, 0, 0, 0)
hbox.setSpacing(0)
self._tabs_vbox = tabs_vbox = QVBoxLayout()
self._tab_btns = [] # type: List[QPushButton]
tabs_vbox.setContentsMargins(0, 0, 0, 0)
tabs_vbox.setSpacing(0)
_tabs_vbox_outer_w = QWidget()
_tabs_vbox_outer = QVBoxLayout()
_tabs_vbox_outer_w.setLayout(_tabs_vbox_outer)
_tabs_vbox_outer_w.setSizePolicy(QSizePolicy(QSizePolicy.Maximum, _tabs_vbox_outer_w.sizePolicy().verticalPolicy()))
_tabs_vbox_outer.setContentsMargins(0, 0, 0, 0)
_tabs_vbox_outer.setSpacing(0)
_tabs_vbox_outer.addLayout(tabs_vbox)
_tabs_vbox_outer.addStretch(1)
self.content_w = content_w = SquareTabWidget()
content_w.setStyleSheet("QTabBar::tab {height: 0px;}") # TODO Linux/mac: still insufficient to rm top padding...
content_w.tabBar().hide()
hbox.addStretch(1)
hbox.addWidget(_tabs_vbox_outer_w)
hbox.addWidget(content_w)
self.currentChanged = content_w.currentChanged
self.currentIndex = content_w.currentIndex
def addTab(self, widget: QWidget, icon: QIcon, text: str):
btn = QPushButton(icon, text)
btn.setCheckable(True)
btn.setSizePolicy(QSizePolicy.Preferred, btn.sizePolicy().verticalPolicy())
def on_btn_click():
self.content_w.setCurrentIndex(idx)
for btn2 in self._tab_btns:
if btn2 != btn:
btn2.setChecked(False)
btn.clicked.connect(on_btn_click)
idx = len(self._tab_btns)
self._tab_btns.append(btn)
self._tabs_vbox.addWidget(btn)
self.content_w.addTab(widget, "")
def setTabIcon(self, idx: int, icon: QIcon):
self._tab_btns[idx].setIcon(icon)
def setCurrentIndex(self, idx: int):
self._tab_btns[idx].click()
class QtEventListener(EventListener):
qt_callback_signal = QtCore.pyqtSignal(tuple)