From 5013dc8d82b95f46b22f3141ad993865d43ce00b Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 4 Sep 2013 23:07:00 -0500 Subject: [PATCH 1/8] replaced `col2hex` which seems to have gotten lost in a bad merge --- lib/matplotlib/backends/qt4_editor/formlayout.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/matplotlib/backends/qt4_editor/formlayout.py b/lib/matplotlib/backends/qt4_editor/formlayout.py index 470d12b8e60d..e219dd63897e 100644 --- a/lib/matplotlib/backends/qt4_editor/formlayout.py +++ b/lib/matplotlib/backends/qt4_editor/formlayout.py @@ -60,6 +60,12 @@ import datetime + +def col2hex(color): + """Convert matplotlib color to hex before passing to Qt""" + return rgb2hex(colorConverter.to_rgb(color)) + + class ColorButton(QtGui.QPushButton): """ Color choosing push button From c5abc50492ae1b660c8ac28a8e14149610481f5b Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 4 Sep 2013 23:08:09 -0500 Subject: [PATCH 2/8] pep8 fixes --- .../backends/qt4_editor/formlayout.py | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/matplotlib/backends/qt4_editor/formlayout.py b/lib/matplotlib/backends/qt4_editor/formlayout.py index e219dd63897e..8aa4c7ac6d9e 100644 --- a/lib/matplotlib/backends/qt4_editor/formlayout.py +++ b/lib/matplotlib/backends/qt4_editor/formlayout.py @@ -107,9 +107,9 @@ def to_qcolor(color): color = col2hex(color) except ValueError: #print('WARNING: ignoring invalid color %r' % color) - return qcolor # return invalid QColor - qcolor.setNamedColor(color) # set using hex color - return qcolor # return valid QColor + return qcolor # return invalid QColor + qcolor.setNamedColor(color) # set using hex color + return qcolor # return valid QColor class ColorLayout(QtGui.QHBoxLayout): @@ -130,7 +130,7 @@ def __init__(self, color, parent=None): def update_color(self): color = self.text() qcolor = to_qcolor(color) - self.colorbtn.color = qcolor # defaults to black if not qcolor.isValid() + self.colorbtn.color = qcolor # defaults to black if not qcolor.isValid() def update_text(self, color): self.lineedit.setText(color.name()) @@ -141,7 +141,9 @@ def text(self): def font_is_installed(font): """Check if font is installed""" - return [fam for fam in QtGui.QFontDatabase().families() if six.text_type(fam)==font] + return [fam for fam in QtGui.QFontDatabase().families() + if six.text_type(fam) == font] + def tuple_to_qfont(tup): """ @@ -162,10 +164,12 @@ def tuple_to_qfont(tup): font.setBold(bold) return font + def qfont_to_tuple(font): return (six.text_type(font.family()), int(font.pointSize()), font.italic(), font.bold()) + class FontLayout(QtGui.QGridLayout): """Font selection""" def __init__(self, value, parent=None): @@ -214,6 +218,7 @@ def is_edit_valid(edit): return state == QtGui.QDoubleValidator.Acceptable + class FormWidget(QtGui.QWidget): def __init__(self, data, comment="", parent=None): QtGui.QWidget.__init__(self, parent) @@ -264,8 +269,8 @@ def setup(self): selindex = value.pop(0) field = QtGui.QComboBox(self) if isinstance(value[0], (list, tuple)): - keys = [ key for key, _val in value ] - value = [ val for _key, val in value ] + keys = [key for key, _val in value] + value = [val for _key, val in value] else: keys = value field.addItems(value) @@ -274,7 +279,7 @@ def setup(self): elif selindex in keys: selindex = keys.index(selindex) elif not isinstance(selindex, int): - print("Warning: '%s' index is invalid (label: " \ + print("Warning: '%s' index is invalid (label: " "%s, value: %s)" % (selindex, label, value), file=STDERR) selindex = 0 field.setCurrentIndex(selindex) @@ -282,7 +287,7 @@ def setup(self): field = QtGui.QCheckBox(self) if value: field.setCheckState(QtCore.Qt.Checked) - else : + else: field.setCheckState(QtCore.Qt.Unchecked) elif isinstance(value, float): field = QtGui.QLineEdit(repr(value), self) @@ -364,7 +369,7 @@ def setup(self): widget.setup() def get(self): - return [ widget.get() for widget in self.widgetlist] + return [widget.get() for widget in self.widgetlist] class FormTabWidget(QtGui.QWidget): @@ -376,7 +381,7 @@ def __init__(self, datalist, comment="", parent=None): self.setLayout(layout) self.widgetlist = [] for data, title, comment in datalist: - if len(data[0])==3: + if len(data[0]) == 3: widget = FormComboWidget(data, comment=comment, parent=self) else: widget = FormWidget(data, comment=comment, parent=self) @@ -389,7 +394,7 @@ def setup(self): widget.setup() def get(self): - return [ widget.get() for widget in self.widgetlist] + return [widget.get() for widget in self.widgetlist] class FormDialog(QtGui.QDialog): @@ -404,7 +409,7 @@ def __init__(self, data, title="", comment="", if isinstance(data[0][0], (list, tuple)): self.formwidget = FormTabWidget(data, comment=comment, parent=self) - elif len(data[0])==3: + elif len(data[0]) == 3: self.formwidget = FormComboWidget(data, comment=comment, parent=self) else: @@ -418,7 +423,7 @@ def __init__(self, data, title="", comment="", # Button box self.bbox = bbox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok - |QtGui.QDialogButtonBox.Cancel) + | QtGui.QDialogButtonBox.Cancel) self.connect(self.formwidget, QtCore.SIGNAL('update_buttons()'), self.update_buttons) if self.apply_callback is not None: @@ -502,7 +507,6 @@ def fedit(data, title="", comment="", icon=None, parent=None, apply=None): return dialog.get() - if __name__ == "__main__": def create_datalist_example(): @@ -529,6 +533,7 @@ def create_datagroup_example(): #--------- datalist example datalist = create_datalist_example() + def apply_test(data): print("data:", data) print("result:", fedit(datalist, title="Example", From b5add85e8c9c79eeb5bb4df68958ea0243b4179b Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 4 Sep 2013 23:09:07 -0500 Subject: [PATCH 3/8] pep8 fixes --- lib/matplotlib/backends/backend_qt4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index f9916a363bad..6ba4a370c178 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -781,7 +781,7 @@ def __init__(self, targetfig, parent): layout.setAlignment(self.slidertop, QtCore.Qt.AlignHCenter) bottomlabel = QtGui.QLabel('bottom') # this might not ever be used - layout.addWidget(QtGui.QLabel('bottom'), 4, 2) + layout.addWidget(bottomlabel, 4, 2) layout.addWidget(self.sliderbottom, 3, 2) layout.setAlignment(self.sliderbottom, QtCore.Qt.AlignHCenter) From 7ddc5ee2cacaa48a77dbc21b6ef951644d004b26 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 4 Sep 2013 23:13:47 -0500 Subject: [PATCH 4/8] converted import-critical PyQt calls to new style so that it will not seg-fault when using PySide Addresses issue #2378 --- lib/matplotlib/backends/backend_qt4.py | 52 ++++++------------- .../backends/qt4_editor/formlayout.py | 28 +++++----- 2 files changed, 29 insertions(+), 51 deletions(-) diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index 6ba4a370c178..99e0276aabe5 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -82,9 +82,8 @@ def _create_qApp(): if display is None or not re.search(':\d', display): raise RuntimeError('Invalid DISPLAY variable') - qApp = QtGui.QApplication([" "]) - QtCore.QObject.connect(qApp, QtCore.SIGNAL("lastWindowClosed()"), - qApp, QtCore.SLOT("quit()")) + qApp = QtGui.QApplication([" "]) # probably fine, not used by QT to resolve anything + qApp.lastWindowClosed.connect(qApp.quit) else: qApp = app @@ -469,8 +468,7 @@ def __init__(self, canvas, num): self.toolbar = self._get_toolbar(self.canvas, self.window) if self.toolbar is not None: self.window.addToolBar(self.toolbar) - QtCore.QObject.connect(self.toolbar, QtCore.SIGNAL("message"), - self._show_message) + self.toolbar.message.connect(self._show_message) tbs_height = self.toolbar.sizeHint().height() else: tbs_height = 0 @@ -556,6 +554,8 @@ def set_window_title(self, title): class NavigationToolbar2QT(NavigationToolbar2, QtGui.QToolBar): + message = QtCore.Signal(str) + def __init__(self, canvas, parent, coordinates=True): """ coordinates: should we show the coordinates on the right? """ self.canvas = canvas @@ -656,7 +656,7 @@ def dynamic_update(self): self.canvas.draw() def set_message(self, s): - self.emit(QtCore.SIGNAL("message"), s) + self.message.emit(s) if self.coordinates: self.locLabel.setText(s.replace(', ', '\n')) @@ -746,18 +746,10 @@ def __init__(self, targetfig, parent): self.sliderhspace = QtGui.QSlider(QtCore.Qt.Vertical) # constraints - QtCore.QObject.connect(self.sliderleft, - QtCore.SIGNAL("valueChanged(int)"), - self.sliderright.setMinimum) - QtCore.QObject.connect(self.sliderright, - QtCore.SIGNAL("valueChanged(int)"), - self.sliderleft.setMaximum) - QtCore.QObject.connect(self.sliderbottom, - QtCore.SIGNAL("valueChanged(int)"), - self.slidertop.setMinimum) - QtCore.QObject.connect(self.slidertop, - QtCore.SIGNAL("valueChanged(int)"), - self.sliderbottom.setMaximum) + self.sliderleft.valueChanged.connect(self.sliderright.setMinimum) + self.sliderright.valueChanged.connect(self.sliderleft.setMaximum) + self.sliderbottom.valueChanged.connect(self.slidertop.setMinimum) + self.slidertop.valueChanged.connect(self.sliderbottom.setMaximum) sliders = (self.sliderleft, self.sliderbottom, self.sliderright, self.slidertop, self.sliderwspace, self.sliderhspace,) @@ -820,24 +812,12 @@ def __init__(self, targetfig, parent): self.sliderhspace.setSliderPosition( int(targetfig.subplotpars.hspace*1000)) - QtCore.QObject.connect(self.sliderleft, - QtCore.SIGNAL("valueChanged(int)"), - self.funcleft) - QtCore.QObject.connect(self.sliderbottom, - QtCore.SIGNAL("valueChanged(int)"), - self.funcbottom) - QtCore.QObject.connect(self.sliderright, - QtCore.SIGNAL("valueChanged(int)"), - self.funcright) - QtCore.QObject.connect(self.slidertop, - QtCore.SIGNAL("valueChanged(int)"), - self.functop) - QtCore.QObject.connect(self.sliderwspace, - QtCore.SIGNAL("valueChanged(int)"), - self.funcwspace) - QtCore.QObject.connect(self.sliderhspace, - QtCore.SIGNAL("valueChanged(int)"), - self.funchspace) + self.sliderleft.valueChanged.connect(self.funcleft) + self.sliderbottom.valueChanged.connect(self.funcbottom) + self.sliderright.valueChanged.connect(self.funcright) + self.slidertop.valueChanged.connect(self.functop) + self.sliderwspace.valueChanged.connect(self.funcwspace) + self.sliderhspace.valueChanged.connect(self.funchspace) def funcleft(self, val): if val == self.sliderright.value(): diff --git a/lib/matplotlib/backends/qt4_editor/formlayout.py b/lib/matplotlib/backends/qt4_editor/formlayout.py index 8aa4c7ac6d9e..cb57df3d39d5 100644 --- a/lib/matplotlib/backends/qt4_editor/formlayout.py +++ b/lib/matplotlib/backends/qt4_editor/formlayout.py @@ -70,33 +70,33 @@ class ColorButton(QtGui.QPushButton): """ Color choosing push button """ - __pyqtSignals__ = ("colorChanged(QColor)",) + colorChanged = QtCore.Signal(QtGui.QColor) def __init__(self, parent=None): QtGui.QPushButton.__init__(self, parent) self.setFixedSize(20, 20) self.setIconSize(QtCore.QSize(12, 12)) - self.connect(self, QtCore.SIGNAL("clicked()"), self.choose_color) + self.clicked.connect(self.choose_color) self._color = QtGui.QColor() def choose_color(self): - color = QtGui.QColorDialog.getColor(self._color,self.parentWidget(),'') + color = QtGui.QColorDialog.getColor(self._color, self.parentWidget(), '') if color.isValid(): self.set_color(color) def get_color(self): return self._color - @QtCore.Slot("QColor") + @QtCore.Slot(QtGui.QColor) def set_color(self, color): if color != self._color: self._color = color - self.emit(QtCore.SIGNAL("colorChanged(QColor)"), self._color) + self.colorChanged.emit(self._color) pixmap = QtGui.QPixmap(self.iconSize()) pixmap.fill(color) self.setIcon(QtGui.QIcon(pixmap)) - color = QtCore.Property("QColor", get_color, set_color) + color = QtCore.Property(QtGui.QColor, get_color, set_color) def to_qcolor(color): @@ -118,13 +118,11 @@ def __init__(self, color, parent=None): QtGui.QHBoxLayout.__init__(self) assert isinstance(color, QtGui.QColor) self.lineedit = QtGui.QLineEdit(color.name(), parent) - self.connect(self.lineedit, QtCore.SIGNAL("editingFinished()"), - self.update_color) + self.lineedit.editingFinished.connect(self.update_color) self.addWidget(self.lineedit) self.colorbtn = ColorButton(parent) self.colorbtn.color = color - self.connect(self.colorbtn, QtCore.SIGNAL("colorChanged(QColor)"), - self.update_text) + self.colorbtn.colorChanged.connect(self.update_text) self.addWidget(self.colorbtn) def update_color(self): @@ -354,8 +352,7 @@ def __init__(self, datalist, comment="", parent=None): self.stackwidget = QtGui.QStackedWidget(self) layout.addWidget(self.stackwidget) - self.connect(self.combobox, QtCore.SIGNAL("currentIndexChanged(int)"), - self.stackwidget, QtCore.SLOT("setCurrentIndex(int)")) + self.combobox.currentIndexChanged.connect(self.stackwidget.setCurrentIndex) self.widgetlist = [] for data, title, comment in datalist: @@ -428,9 +425,10 @@ def __init__(self, data, title="", comment="", self.update_buttons) if self.apply_callback is not None: apply_btn = bbox.addButton(QtGui.QDialogButtonBox.Apply) - self.connect(apply_btn, QtCore.SIGNAL("clicked()"), self.apply) - self.connect(bbox, QtCore.SIGNAL("accepted()"), QtCore.SLOT("accept()")) - self.connect(bbox, QtCore.SIGNAL("rejected()"), QtCore.SLOT("reject()")) + apply_btn.clicked.connect(self.apply) + + bbox.accepted.connect(self.accept) + bbox.rejected.connect(self.reject) layout.addWidget(bbox) self.setLayout(layout) From bf3b1b45b3714ebb29d72e6f8be94e7ee279e729 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Wed, 4 Sep 2013 23:20:29 -0500 Subject: [PATCH 5/8] pep8 fixes --- examples/user_interfaces/embedding_in_qt4.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/user_interfaces/embedding_in_qt4.py b/examples/user_interfaces/embedding_in_qt4.py index 6d9b5b5a0d08..5ce964d3ecec 100755 --- a/examples/user_interfaces/embedding_in_qt4.py +++ b/examples/user_interfaces/embedding_in_qt4.py @@ -10,7 +10,9 @@ # may be distributed without limitation. from __future__ import unicode_literals -import sys, os, random +import sys +import os +import random from matplotlib.backends import qt4_compat use_pyside = qt4_compat.QT_API == qt4_compat.QT_API_PYSIDE if use_pyside: @@ -62,18 +64,18 @@ class MyDynamicMplCanvas(MyMplCanvas): def __init__(self, *args, **kwargs): MyMplCanvas.__init__(self, *args, **kwargs) timer = QtCore.QTimer(self) - if use_pyside: + if use_pyside: timer.timeout.connect(self.update_figure) else: QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self.update_figure) timer.start(1000) def compute_initial_figure(self): - self.axes.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r') + self.axes.plot([0, 1, 2, 3], [1, 2, 0, 4], 'r') def update_figure(self): # Build a list of 4 random integers between 0 and 10 (both inclusive) - l = [ random.randint(0, 10) for i in range(4) ] + l = [random.randint(0, 10) for i in range(4)] self.axes.plot([0, 1, 2, 3], l, 'r') self.draw() From bcdf5f5c7708ef1e6e62dacca1ab09cf2589503d Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 5 Sep 2013 00:14:06 -0500 Subject: [PATCH 6/8] second pass at catching the rest of the old-style signal/slot connections. --- lib/matplotlib/backends/backend_qt4.py | 20 +++++++++---------- .../backends/qt4_editor/formlayout.py | 11 ++++++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index 99e0276aabe5..6ae808359cae 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -133,8 +133,7 @@ def __init__(self, *args, **kwargs): # Create a new timer and connect the timeout() signal to the # _on_timer method. self._timer = QtCore.QTimer() - QtCore.QObject.connect(self._timer, QtCore.SIGNAL('timeout()'), - self._on_timer) + self._timer.timeout.connect(self._on_timer) self._timer_set_interval() def __del__(self): @@ -142,8 +141,7 @@ def __del__(self): # disconnect try: TimerBase.__del__(self) - QtCore.QObject.disconnect(self._timer, - QtCore.SIGNAL('timeout()'), self._on_timer) + self._timer.timeout.disconnect(self._on_timer) except RuntimeError: # Timer C++ object already deleted pass @@ -422,8 +420,10 @@ def idle_draw(*args): class MainWindow(QtGui.QMainWindow): + closing = QtCore.Signal() + def closeEvent(self, event): - self.emit(QtCore.SIGNAL('closing()')) + self.closing.emit() QtGui.QMainWindow.closeEvent(self, event) @@ -443,10 +443,8 @@ def __init__(self, canvas, num): FigureManagerBase.__init__(self, canvas, num) self.canvas = canvas self.window = MainWindow() - self.window.connect(self.window, QtCore.SIGNAL('closing()'), - canvas.close_event) - self.window.connect(self.window, QtCore.SIGNAL('closing()'), - self._widgetclosed) + self.window.closing.connect(canvas.close_event) + self.window.closing.connect(self._widgetclosed) self.window.setWindowTitle("Figure %d" % num) image = os.path.join(matplotlib.rcParams['datapath'], @@ -538,8 +536,8 @@ def destroy(self, *args): if self.window._destroying: return self.window._destroying = True - QtCore.QObject.disconnect(self.window, QtCore.SIGNAL('destroyed()'), - self._widgetclosed) + self.window.destroyed.connect(self._widgetclosed) + if self.toolbar: self.toolbar.destroy() if DEBUG: diff --git a/lib/matplotlib/backends/qt4_editor/formlayout.py b/lib/matplotlib/backends/qt4_editor/formlayout.py index cb57df3d39d5..f1fcd66670da 100644 --- a/lib/matplotlib/backends/qt4_editor/formlayout.py +++ b/lib/matplotlib/backends/qt4_editor/formlayout.py @@ -218,6 +218,7 @@ def is_edit_valid(edit): class FormWidget(QtGui.QWidget): + update_buttons = QtCore.Signal() def __init__(self, data, comment="", parent=None): QtGui.QWidget.__init__(self, parent) from copy import deepcopy @@ -292,8 +293,7 @@ def setup(self): field.setValidator(QtGui.QDoubleValidator(field)) dialog = self.get_dialog() dialog.register_float_field(field) - self.connect(field, QtCore.SIGNAL('textChanged(QString)'), - lambda text: dialog.update_buttons()) + field.textChanged.connect(lambda text: dialog.update_buttons()) elif isinstance(value, int): field = QtGui.QSpinBox(self) field.setRange(-1e9, 1e9) @@ -343,6 +343,8 @@ def get(self): class FormComboWidget(QtGui.QWidget): + update_buttons = QtCore.Signal() + def __init__(self, datalist, comment="", parent=None): QtGui.QWidget.__init__(self, parent) layout = QtGui.QVBoxLayout() @@ -370,6 +372,8 @@ def get(self): class FormTabWidget(QtGui.QWidget): + update_buttons = QtCore.Signal() + def __init__(self, datalist, comment="", parent=None): QtGui.QWidget.__init__(self, parent) layout = QtGui.QVBoxLayout() @@ -421,8 +425,7 @@ def __init__(self, data, title="", comment="", # Button box self.bbox = bbox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel) - self.connect(self.formwidget, QtCore.SIGNAL('update_buttons()'), - self.update_buttons) + self.formwidget.update_buttons.connect(self.update_buttons) if self.apply_callback is not None: apply_btn = bbox.addButton(QtGui.QDialogButtonBox.Apply) apply_btn.clicked.connect(self.apply) From 1c649f57893b40d394173f0b664da7f5fbaa2671 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Thu, 5 Sep 2013 15:32:25 -0500 Subject: [PATCH 7/8] change from mdboom --- lib/matplotlib/backends/backend_qt4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index 6ae808359cae..788947900df1 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -82,7 +82,7 @@ def _create_qApp(): if display is None or not re.search(':\d', display): raise RuntimeError('Invalid DISPLAY variable') - qApp = QtGui.QApplication([" "]) # probably fine, not used by QT to resolve anything + qApp = QtGui.QApplication([str(" ")]) qApp.lastWindowClosed.connect(qApp.quit) else: qApp = app From df3d8829c99f4ee4108b654e1b06121efd3e987c Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sat, 7 Sep 2013 09:55:44 -0500 Subject: [PATCH 8/8] use new-style for PyQt as well as PySide --- examples/user_interfaces/embedding_in_qt4.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/user_interfaces/embedding_in_qt4.py b/examples/user_interfaces/embedding_in_qt4.py index 5ce964d3ecec..84b1fc372594 100755 --- a/examples/user_interfaces/embedding_in_qt4.py +++ b/examples/user_interfaces/embedding_in_qt4.py @@ -64,10 +64,7 @@ class MyDynamicMplCanvas(MyMplCanvas): def __init__(self, *args, **kwargs): MyMplCanvas.__init__(self, *args, **kwargs) timer = QtCore.QTimer(self) - if use_pyside: - timer.timeout.connect(self.update_figure) - else: - QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self.update_figure) + timer.timeout.connect(self.update_figure) timer.start(1000) def compute_initial_figure(self): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy