From 751cca35e12fb7e278eccf9b726832e26883a6b6 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Tue, 27 Oct 2020 15:15:31 -0400 Subject: [PATCH] Attempt to calculate font size by DPI --- piker/ui/_chart.py | 22 ++++++++++++++++++-- piker/ui/_exec.py | 25 ++++++++++++++++++++++- piker/ui/_style.py | 51 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/piker/ui/_chart.py b/piker/ui/_chart.py index c5329138..57c9a292 100644 --- a/piker/ui/_chart.py +++ b/piker/ui/_chart.py @@ -36,7 +36,7 @@ from ..data import ( maybe_open_shm_array, ) from ..log import get_logger -from ._exec import run_qtractor +from ._exec import run_qtractor, current_screen from ._interaction import ChartView from .. import fsp @@ -233,7 +233,10 @@ class LinkedSplitCharts(QtGui.QWidget): cpw = ChartPlotWidget( array=array, parent=self.splitter, - axisItems={'bottom': xaxis, 'right': PriceAxis()}, + axisItems={ + 'bottom': xaxis, + 'right': PriceAxis(linked_charts=self) + }, viewBox=cv, cursor=self._ch, **cpw_kwargs, @@ -688,6 +691,21 @@ async def _async_main( """ chart_app = widgets['main'] + screen = current_screen() + + from ._style import configure_font_to_dpi + print( + f'screen: {screen.name()} {screen.size()}') + + configure_font_to_dpi(screen) + + # from ._exec import get_screen + # screen = get_screen(chart_app.geometry().bottomRight()) + + # XXX: bug zone if you try to ctl-c after this we get hangs again? + # wtf... + # await tractor.breakpoint() + # historical data fetch brokermod = brokers.get_brokermod(brokername) diff --git a/piker/ui/_exec.py b/piker/ui/_exec.py index 1270d8ac..d9ac918e 100644 --- a/piker/ui/_exec.py +++ b/piker/ui/_exec.py @@ -16,12 +16,22 @@ from PyQt5.QtCore import ( pyqtRemoveInputHook, Qt, QCoreApplication ) import qdarkstyle - import trio import tractor from outcome import Error +# singleton app per actor +_qt_app: QtGui.QApplication = None +_qt_win: QtGui.QMainWindow = None + + +def current_screen() -> QtGui.QScreen: + + global _qt_win, _qt_app + return _qt_app.screenAt(_qt_win.centralWidget().geometry().center()) + + # Proper high DPI scaling is available in Qt >= 5.6.0. This attibute # must be set before creating the application if hasattr(Qt, 'AA_EnableHighDpiScaling'): @@ -62,6 +72,10 @@ def run_qtractor( # currently seem tricky.. app.setQuitOnLastWindowClosed(False) + # set global app singleton + global _qt_app + _qt_app = app + # This code is from Nathaniel, and I quote: # "This is substantially faster than using a signal... for some # reason Qt signal dispatch is really slow (and relies on events @@ -84,10 +98,13 @@ def run_qtractor( app.postEvent(reenter, event) def done_callback(outcome): + print(f"Outcome: {outcome}") + if isinstance(outcome, Error): exc = outcome.error traceback.print_exception(type(exc), exc, exc.__traceback__) + app.quit() # load dark theme @@ -125,6 +142,12 @@ def run_qtractor( window.main_widget = main_widget window.setCentralWidget(instance) + + # store global ref + # set global app singleton + global _qt_win + _qt_win = window + # actually render to screen window.show() app.exec_() diff --git a/piker/ui/_style.py b/piker/ui/_style.py index 210b4780..87e94c4d 100644 --- a/piker/ui/_style.py +++ b/piker/ui/_style.py @@ -5,19 +5,54 @@ import pyqtgraph as pg from PyQt5 import QtGui from qdarkstyle.palette import DarkPalette +from ..log import get_logger + +log = get_logger(__name__) # chart-wide font -_font = QtGui.QFont("Hack") +# font size 6px / 53 dpi (3x scaled down on 4k hidpi) +_font_inches_we_like = 6 / 53 + # use pixel size to be cross-resolution compatible? -_font.setPixelSize(6) +_font = QtGui.QFont("Hack") +_font.setPixelSize(6) # default -# TODO: use QScreen to determine the same physical font size -# on screen despite different displays? -# PyQt docs: https://doc.qt.io/qtforpython/PySide2/QtGui/QScreen.html -# - supposedly it's ``from QtGui import QScreen`` -# Qt forums: https://forum.qt.io/topic/43625/point-sizes-are-they-reliable/4 +# _physical_font_height_in = 1/6 # inches +_font._fm = QtGui.QFontMetrics(_font) -_i3_rgba = QtGui.QColor.fromRgbF(*[0.14]*3 + [1]) +# TODO: re-compute font size when main widget switches screens? +# https://forum.qt.io/topic/54136/how-do-i-get-the-qscreen-my-widget-is-on-qapplication-desktop-screen-returns-a-qwidget-and-qobject_cast-qscreen-returns-null/3 + + +def configure_font_to_dpi(screen: QtGui.QScreen): + """Set an appropriately sized font size depending on the screen DPI. + + If we end up needing to generalize this more here are some resources: + + - https://stackoverflow.com/questions/42141354/convert-pixel-size-to-point-size-for-fonts-on-multiple-platforms + - https://stackoverflow.com/questions/25761556/qt5-font-rendering-different-on-various-platforms/25929628#25929628 + - https://doc.qt.io/qt-5/highdpi.html + - https://stackoverflow.com/questions/20464814/changing-dpi-scaling-size-of-display-make-qt-applications-font-size-get-rendere + - https://stackoverflow.com/a/20465247 + - https://doc.qt.io/archives/qt-4.8/qfontmetrics.html#width + - https://forum.qt.io/topic/54136/how-do-i-get-the-qscreen-my-widget-is-on-qapplication-desktop-screen-returns-a-qwidget-and-qobject_cast-qscreen-returns-null/3 + - https://forum.qt.io/topic/43625/point-sizes-are-they-reliable/4 + + Also, see the script in ``snippets/qt_screen_info.py``. + + """ + dpi = screen.physicalDotsPerInch() + font_size = round(_font_inches_we_like * dpi) + log.info( + f"\nscreen:{screen.name()} with DPI: {dpi}" + f"\nbest font size is {font_size}\n" + ) + global _font + _font.setPixelSize(font_size) + return _font + + +# _i3_rgba = QtGui.QColor.fromRgbF(*[0.14]*3 + [1]) # splitter widget config _xaxis_at = 'bottom'