diff options
author | Simo Fält <simo.falt@qt.io> | 2022-09-01 08:15:19 +0300 |
---|---|---|
committer | Simo Fält <simo.falt@qt.io> | 2022-09-01 08:15:19 +0300 |
commit | 789fc5d65d2e0ba95cda25e63f74dd4def87a775 (patch) | |
tree | 28019fcbb368b64fad68d930a2587ee22092d71b | |
parent | 54a301d83910a760ff7f7aa5bea1e3c3d7226bc8 (diff) | |
parent | 0ad10f40c9cdbe6d054b6e7ffd60d14846a1d4aa (diff) |
Merge remote-tracking branch 'origin/6.3' into wip/6.3_pypy
Change-Id: I049daa7bbac16b4cf680dc60d65553277064b231
64 files changed, 465 insertions, 114 deletions
diff --git a/build_history/blacklist.txt b/build_history/blacklist.txt index 3355a2b6e..d3455dd60 100644 --- a/build_history/blacklist.txt +++ b/build_history/blacklist.txt @@ -33,8 +33,6 @@ linux darwin # Open GL functions failures on macOS (2/2020) -[registry::existence_test] - darwin [QtQml::qqmlnetwork_test] linux ci # extended, see PyPy section below [QtWidgets::bug_750] diff --git a/coin_test_instructions.py b/coin_test_instructions.py index d52521615..da53b1c12 100644 --- a/coin_test_instructions.py +++ b/coin_test_instructions.py @@ -186,7 +186,16 @@ def run_test_instructions(): p_ver = "pypy" call_testrunner(p_ver, str(testRun), pypy) else: - call_testrunner("3", str(testRun)) + # In win machines, there are additional python versions to test with + if CI_HOST_OS == "Windows": + if os.environ.get('HOST_OSVERSION_COIN') == 'windows_10_21h2': + call_testrunner("3.10.0", str(testRun)) + else: + call_testrunner("3.7.9", str(testRun)) + elif CI_HOST_OS == "Linux": + call_testrunner("3.8", str(testRun)) + else: + call_testrunner("3", str(testRun)) if __name__ == "__main__": diff --git a/examples/bluetooth/btscanner/device.py b/examples/bluetooth/btscanner/device.py index bf8194bc5..feb1cd967 100644 --- a/examples/bluetooth/btscanner/device.py +++ b/examples/bluetooth/btscanner/device.py @@ -125,7 +125,7 @@ class DeviceDiscoveryDialog(QDialog): else: self._local_device.setHostMode(QBluetoothLocalDevice.HostPoweredOff) - @Slot(QBluetoothLocalDevice.HostMode) + @Slot("QBluetoothLocalDevice::HostMode") def host_mode_state_changed(self, mode): self._ui.power.setChecked(mode != QBluetoothLocalDevice.HostPoweredOff) self._ui.discoverable.setChecked(mode == QBluetoothLocalDevice.HostDiscoverable) @@ -155,7 +155,7 @@ class DeviceDiscoveryDialog(QDialog): elif chosen_action == remove_pair_action: self._local_device.requestPairing(address, QBluetoothLocalDevice.Unpaired) - @Slot(QBluetoothAddress, QBluetoothLocalDevice.Pairing) + @Slot(QBluetoothAddress, "QBluetoothLocalDevice::Pairing") def pairing_done(self, address, pairing): items = self._ui.list.findItems(address.toString(), Qt.MatchContains) diff --git a/examples/charts/chartthemes/main.py b/examples/charts/chartthemes/main.py index 5f3bfce10..b385d0b5e 100644 --- a/examples/charts/chartthemes/main.py +++ b/examples/charts/chartthemes/main.py @@ -171,7 +171,7 @@ class ThemeWidget(QWidget): for j in range(len(self.data_table[i])): data = self.data_table[i][j] if lower_series: - points = lower_series.pointsVector() + points = lower_series.points() y_value = points[i].y() + data[0].y() upper_series.append(QPointF(j, y_value)) else: @@ -182,10 +182,12 @@ class ThemeWidget(QWidget): lower_series = upper_series chart.createDefaultAxes() - chart.axisX().setRange(0, self.value_count - 1) - chart.axisY().setRange(0, self.value_max) + axis_x = chart.axes(Qt.Horizontal)[0] + axis_x.setRange(0, self.value_count - 1) + axis_y = chart.axes(Qt.Vertical)[0] + axis_y.setRange(0, self.value_max) # Add space to label to add space between labels and axis - chart.axisY().setLabelFormat("%.1f ") + axis_y.setLabelFormat("%.1f ") return chart @@ -203,9 +205,10 @@ class ThemeWidget(QWidget): chart.addSeries(series) chart.createDefaultAxes() - chart.axisY().setRange(0, self.value_max * 2) + axis_y = chart.axes(Qt.Vertical)[0] + axis_y.setRange(0, self.value_max * 2) # Add space to label to add space between labels and axis - chart.axisY().setLabelFormat("%.1f ") + axis_y.setLabelFormat("%.1f ") return chart @@ -222,10 +225,12 @@ class ThemeWidget(QWidget): chart.addSeries(series) chart.createDefaultAxes() - chart.axisX().setRange(0, self.value_max) - chart.axisY().setRange(0, self.value_count) + axis_x = chart.axes(Qt.Horizontal)[0] + axis_x.setRange(0, self.value_max) + axis_y = chart.axes(Qt.Vertical)[0] + axis_y.setRange(0, self.value_count) # Add space to label to add space between labels and axis - chart.axisY().setLabelFormat("%.1f ") + axis_y.setLabelFormat("%.1f ") return chart @@ -259,10 +264,12 @@ class ThemeWidget(QWidget): chart.addSeries(series) chart.createDefaultAxes() - chart.axisX().setRange(0, self.value_max) - chart.axisY().setRange(0, self.value_count) + axis_x = chart.axes(Qt.Horizontal)[0] + axis_x.setRange(0, self.value_max) + axis_y = chart.axes(Qt.Vertical)[0] + axis_y.setRange(0, self.value_count) # Add space to label to add space between labels and axis - chart.axisY().setLabelFormat("%.1f ") + axis_y.setLabelFormat("%.1f ") return chart @@ -278,10 +285,12 @@ class ThemeWidget(QWidget): chart.addSeries(series) chart.createDefaultAxes() - chart.axisX().setRange(0, self.value_max) - chart.axisY().setRange(0, self.value_count) + axis_x = chart.axes(Qt.Horizontal)[0] + axis_x.setRange(0, self.value_max) + axis_y = chart.axes(Qt.Vertical)[0] + axis_y.setRange(0, self.value_count) # Add space to label to add space between labels and axis - chart.axisY().setLabelFormat("%.1f ") + axis_y.setLabelFormat("%.1f ") return chart diff --git a/examples/charts/donutbreakdown/donutbreakdown.py b/examples/charts/donutbreakdown/donutbreakdown.py index 3030d1e0d..160494e2a 100644 --- a/examples/charts/donutbreakdown/donutbreakdown.py +++ b/examples/charts/donutbreakdown/donutbreakdown.py @@ -42,7 +42,7 @@ import sys -from PySide6.QtCore import Qt +from PySide6.QtCore import Qt, Slot from PySide6.QtGui import QColor, QFont, QPainter, QScreen from PySide6.QtWidgets import QApplication, QMainWindow from PySide6.QtCharts import QChart, QChartView, QPieSeries, QPieSlice @@ -66,6 +66,7 @@ class MainSlice(QPieSlice): def name(self): return self.name + @Slot() def update_label(self): p = self.percentage() * 100 self.setLabel(f"{self.name} {p:.2f}%") diff --git a/examples/charts/legend/legend.py b/examples/charts/legend/legend.py index 0f3a99d40..84e12dd86 100644 --- a/examples/charts/legend/legend.py +++ b/examples/charts/legend/legend.py @@ -41,7 +41,7 @@ """PySide6 port of the Legend example from Qt v5.x""" import sys -from PySide6.QtCore import Qt, QRectF +from PySide6.QtCore import Qt, QRectF, Slot from PySide6.QtGui import QBrush, QColor, QPainter, QPen from PySide6.QtWidgets import (QApplication, QDoubleSpinBox, QFormLayout, QGridLayout, QGroupBox, QPushButton, QWidget) @@ -160,6 +160,7 @@ class MainWidget(QWidget): def hide_legend_spinbox(self): self.legend_settings.setVisible(False) + @Slot() def toggle_attached(self): legend = self.chart.legend() if legend.isAttachedToChart(): @@ -176,6 +177,7 @@ class MainWidget(QWidget): self.hide_legend_spinbox() self.update() + @Slot() def add_barset(self): series_count = self.series.count() bar_set = QBarSet(f"set {series_count}") @@ -183,12 +185,14 @@ class MainWidget(QWidget): bar_set.append([1 + delta, 2 + delta, 3 + delta, 4 + delta]) self.series.append(bar_set) + @Slot() def remove_barset(self): sets = self.series.barSets() len_sets = len(sets) if len_sets > 0: self.series.remove(sets[len_sets - 1]) + @Slot() def set_legend_alignment(self): button = self.sender() legend = self.chart.legend() @@ -211,18 +215,21 @@ class MainWidget(QWidget): button.setText("Align (Top)") legend.setAlignment(Qt.AlignTop) + @Slot() def toggle_bold(self): legend = self.chart.legend() font = legend.font() font.setBold(not font.bold()) legend.setFont(font) + @Slot() def toggle_italic(self): legend = self.chart.legend() font = legend.font() font.setItalic(not font.italic()) legend.setFont(font) + @Slot() def font_size_changed(self): legend = self.chart.legend() font = legend.font() @@ -232,6 +239,7 @@ class MainWidget(QWidget): font.setPointSizeF(font_size) legend.setFont(font) + @Slot() def update_legend_layout(self): legend = self.chart.legend() diff --git a/examples/charts/nesteddonuts/nesteddonuts.py b/examples/charts/nesteddonuts/nesteddonuts.py index ddc18131b..c9b43e49d 100644 --- a/examples/charts/nesteddonuts/nesteddonuts.py +++ b/examples/charts/nesteddonuts/nesteddonuts.py @@ -43,7 +43,7 @@ import sys -from PySide6.QtCore import Qt, QTimer +from PySide6.QtCore import Qt, QTimer, Slot from PySide6.QtGui import QPainter from PySide6.QtWidgets import QApplication, QGridLayout, QWidget from PySide6.QtCharts import QChart, QChartView, QPieSeries, QPieSlice @@ -103,6 +103,7 @@ class Widget(QWidget): self.donuts.append(donut) self.chart_view.chart().addSeries(donut) + @Slot() def update_rotation(self): for donut in self.donuts: phase_shift = randrange(-50, 100) diff --git a/examples/charts/percentbarchart/percentbarchart.py b/examples/charts/percentbarchart/percentbarchart.py index beabe0d6c..de067455c 100644 --- a/examples/charts/percentbarchart/percentbarchart.py +++ b/examples/charts/percentbarchart/percentbarchart.py @@ -81,7 +81,8 @@ class MainWindow(QMainWindow): axis = QBarCategoryAxis() axis.append(categories) chart.createDefaultAxes() - chart.setAxisX(axis, series) + chart.addAxis(axis, Qt.AlignBottom) + series.attachAxis(axis) chart.legend().setVisible(True) chart.legend().setAlignment(Qt.AlignBottom) diff --git a/examples/corelib/settingseditor/settingseditor.py b/examples/corelib/settingseditor/settingseditor.py index 389a2ffb7..79fcab5e5 100644 --- a/examples/corelib/settingseditor/settingseditor.py +++ b/examples/corelib/settingseditor/settingseditor.py @@ -46,7 +46,7 @@ import sys from PySide6.QtCore import (QByteArray, QDate, QDateTime, QDir, QEvent, QPoint, - QRect, QRegularExpression, QSettings, QSize, QTime, QTimer, Qt) + QRect, QRegularExpression, QSettings, QSize, QTime, QTimer, Qt, Slot) from PySide6.QtGui import (QAction, QColor, QIcon, QIntValidator, QDoubleValidator, QRegularExpressionValidator, QValidator) from PySide6.QtWidgets import (QAbstractItemView, QApplication, @@ -183,6 +183,7 @@ class MainWindow(QMainWindow): self.setWindowTitle("Settings Editor") self.resize(500, 600) + @Slot() def open_settings(self): if self.location_dialog is None: self.location_dialog = LocationDialog(self) @@ -195,6 +196,7 @@ class MainWindow(QMainWindow): self.set_settings_object(settings) self.fallbacks_action.setEnabled(True) + @Slot() def open_inifile(self): file_name, _ = QFileDialog.getOpenFileName(self, "Open INI File", '', "INI Files (*.ini *.conf)") @@ -209,6 +211,7 @@ class MainWindow(QMainWindow): self.set_settings_object(settings) self.fallbacks_action.setEnabled(False) + @Slot() def open_property_list(self): file_name, _ = QFileDialog.getOpenFileName(self, "Open Property List", '', "Property List Files (*.plist)") @@ -218,6 +221,7 @@ class MainWindow(QMainWindow): self.set_settings_object(settings) self.fallbacks_action.setEnabled(False) + @Slot() def open_registry_path(self): path, ok = QInputDialog.getText(self, "Open Registry Path", "Enter the path in the Windows registry:", @@ -228,6 +232,7 @@ class MainWindow(QMainWindow): self.set_settings_object(settings) self.fallbacks_action.setEnabled(False) + @Slot() def about(self): QMessageBox.about(self, "About Settings Editor", "The <b>Settings Editor</b> example shows how to access " @@ -512,6 +517,7 @@ class SettingsTree(QTreeWidget): def sizeHint(self): return QSize(800, 600) + @Slot(bool) def set_auto_refresh(self, autoRefresh): self.auto_refresh = autoRefresh @@ -522,15 +528,18 @@ class SettingsTree(QTreeWidget): else: self.refresh_timer.stop() + @Slot(bool) def set_fallbacks_enabled(self, enabled): if self.settings is not None: self.settings.setFallbacksEnabled(enabled) self.refresh() + @Slot() def maybe_refresh(self): if self.state() != QAbstractItemView.EditingState: self.refresh() + @Slot() def refresh(self): if self.settings is None: return diff --git a/examples/corelib/threads/mandelbrot.py b/examples/corelib/threads/mandelbrot.py index 824f4197d..b1f7a2fc8 100644 --- a/examples/corelib/threads/mandelbrot.py +++ b/examples/corelib/threads/mandelbrot.py @@ -47,7 +47,7 @@ import sys from PySide6.QtCore import (Signal, QMutex, QElapsedTimer, QMutexLocker, QPoint, QPointF, QSize, Qt, QThread, - QWaitCondition) + QWaitCondition, Slot) from PySide6.QtGui import QColor, QImage, QPainter, QPixmap, qRgb from PySide6.QtWidgets import QApplication, QWidget @@ -340,6 +340,7 @@ class MandelbrotWidget(QWidget): delta_y = (self.height() - self.pixmap.height()) / 2 - self._pixmap_offset.y() self.scroll(delta_x, delta_y) + @Slot(QImage,float) def update_pixmap(self, image, scale_factor): if not self._last_drag_pos.isNull(): return diff --git a/examples/datavisualization/surface/surfacegraph.py b/examples/datavisualization/surface/surfacegraph.py index f98c419f9..9bf2f41f8 100644 --- a/examples/datavisualization/surface/surfacegraph.py +++ b/examples/datavisualization/surface/surfacegraph.py @@ -108,6 +108,7 @@ class SurfaceGraph(QObject): self._sqrtSinProxy.resetArray(data_array) + @Slot(bool) def enable_sqrt_sin_model(self, enable): if enable: self._sqrtSinSeries.setDrawMode(QSurface3DSeries.DrawSurfaceAndWireframe) @@ -139,6 +140,7 @@ class SurfaceGraph(QObject): self._axisMaxSliderZ.setMaximum(SAMPLE_COUNT_Z - 1) self._axisMaxSliderZ.setValue(SAMPLE_COUNT_Z - 1) + @Slot(bool) def enable_height_map_model(self, enable): if enable: self._heightMapSeries.setDrawMode(QSurface3DSeries.DrawSurface) @@ -173,6 +175,7 @@ class SurfaceGraph(QObject): self._axisMaxSliderZ.setMaximum(map_grid_count_z - 1) self._axisMaxSliderZ.setValue(map_grid_count_z - 1) + @Slot(int) def adjust_xmin(self, minimum): min_x = self._stepX * float(minimum) + self._rangeMinX @@ -184,6 +187,7 @@ class SurfaceGraph(QObject): self.set_axis_xrange(min_x, max_x) + @Slot(int) def adjust_xmax(self, maximum): max_x = self._stepX * float(maximum) + self._rangeMinX @@ -195,6 +199,7 @@ class SurfaceGraph(QObject): self.set_axis_xrange(min_x, max_x) + @Slot(int) def adjust_zmin(self, minimum): min_z = self._stepZ * float(minimum) + self._rangeMinZ @@ -206,6 +211,7 @@ class SurfaceGraph(QObject): self.set_axis_zrange(min_z, max_z) + @Slot(int) def adjust_zmax(self, maximum): max_x = self._stepZ * float(maximum) + self._rangeMinZ @@ -223,10 +229,11 @@ class SurfaceGraph(QObject): def set_axis_zrange(self, minimum, maximum): self._graph.axisZ().setRange(minimum, maximum) - @Slot() + @Slot(int) def change_theme(self, theme): self._graph.activeTheme().setType(Q3DTheme.Theme(theme)) + @Slot() def set_black_to_yellow_gradient(self): gr = QLinearGradient() gr.setColorAt(0.0, Qt.black) @@ -238,6 +245,7 @@ class SurfaceGraph(QObject): series.setBaseGradient(gr) series.setColorStyle(Q3DTheme.ColorStyleRangeGradient) + @Slot() def set_green_to_red_gradient(self): gr = QLinearGradient() gr.setColorAt(0.0, Qt.darkGreen) @@ -249,17 +257,21 @@ class SurfaceGraph(QObject): series.setBaseGradient(gr) series.setColorStyle(Q3DTheme.ColorStyleRangeGradient) + @Slot() def toggle_mode_none(self): self._graph.setSelectionMode(QAbstract3DGraph.SelectionNone) + @Slot() def toggle_mode_item(self): self._graph.setSelectionMode(QAbstract3DGraph.SelectionItem) + @Slot() def toggle_mode_slice_row(self): self._graph.setSelectionMode( QAbstract3DGraph.SelectionItemAndRow | QAbstract3DGraph.SelectionSlice ) + @Slot() def toggle_mode_slice_column(self): self._graph.setSelectionMode( QAbstract3DGraph.SelectionItemAndColumn | QAbstract3DGraph.SelectionSlice diff --git a/examples/datavisualization/surface_model_numpy/surfacegraph.py b/examples/datavisualization/surface_model_numpy/surfacegraph.py index c95cec2a0..4b69ed161 100644 --- a/examples/datavisualization/surface_model_numpy/surfacegraph.py +++ b/examples/datavisualization/surface_model_numpy/surfacegraph.py @@ -150,6 +150,7 @@ class SurfaceGraph(QObject): self.m_stepX = 0.0 self.m_stepZ = 0.0 + @Slot(bool) def enable_sqrt_sin_model(self, enable): if enable: self.m_sqrtSinSeries.setDrawMode(QSurface3DSeries.DrawSurfaceAndWireframe) @@ -181,6 +182,7 @@ class SurfaceGraph(QObject): self.m_axisMaxSliderZ.setMaximum(SAMPLE_COUNT_Z - 1) self.m_axisMaxSliderZ.setValue(SAMPLE_COUNT_Z - 1) + @Slot(bool) def enable_height_map_model(self, enable): if enable: self.m_heightMapSeries.setDrawMode(QSurface3DSeries.DrawSurface) @@ -215,6 +217,7 @@ class SurfaceGraph(QObject): self.m_axisMaxSliderZ.setMaximum(map_grid_count_z - 1) self.m_axisMaxSliderZ.setValue(map_grid_count_z - 1) + @Slot(int) def adjust_xmin(self, minimum): min_x = self.m_stepX * float(minimum) + self.m_rangeMinX @@ -226,6 +229,7 @@ class SurfaceGraph(QObject): self.set_axis_xrange(min_x, max_x) + @Slot(int) def adjust_xmax(self, maximum): max_x = self.m_stepX * float(maximum) + self.m_rangeMinX @@ -237,6 +241,7 @@ class SurfaceGraph(QObject): self.set_axis_xrange(min_x, max_x) + @Slot(int) def adjust_zmin(self, minimum): min_z = self.m_stepZ * float(minimum) + self.m_rangeMinZ @@ -248,6 +253,7 @@ class SurfaceGraph(QObject): self.set_axis_zrange(min_z, max_z) + @Slot(int) def adjust_zmax(self, maximum): max_x = self.m_stepZ * float(maximum) + self.m_rangeMinZ @@ -265,10 +271,11 @@ class SurfaceGraph(QObject): def set_axis_zrange(self, minimum, maximum): self.m_graph.axisZ().setRange(minimum, maximum) - @Slot() + @Slot(int) def change_theme(self, theme): self.m_graph.activeTheme().setType(Q3DTheme.Theme(theme)) + @Slot() def set_black_to_yellow_gradient(self): gr = QLinearGradient() gr.setColorAt(0.0, Qt.black) @@ -280,6 +287,7 @@ class SurfaceGraph(QObject): series.setBaseGradient(gr) series.setColorStyle(Q3DTheme.ColorStyleRangeGradient) + @Slot() def set_green_to_red_gradient(self): gr = QLinearGradient() gr.setColorAt(0.0, Qt.darkGreen) @@ -291,17 +299,21 @@ class SurfaceGraph(QObject): series.setBaseGradient(gr) series.setColorStyle(Q3DTheme.ColorStyleRangeGradient) + @Slot() def toggle_mode_none(self): self.m_graph.setSelectionMode(QAbstract3DGraph.SelectionNone) + @Slot() def toggle_mode_item(self): self.m_graph.setSelectionMode(QAbstract3DGraph.SelectionItem) + @Slot() def toggle_mode_slice_row(self): self.m_graph.setSelectionMode( QAbstract3DGraph.SelectionItemAndRow | QAbstract3DGraph.SelectionSlice ) + @Slot() def toggle_mode_slice_column(self): self.m_graph.setSelectionMode( QAbstract3DGraph.SelectionItemAndColumn | QAbstract3DGraph.SelectionSlice diff --git a/examples/declarative/rendercontrol/rendercontrol_opengl/window_singlethreaded.py b/examples/declarative/rendercontrol/rendercontrol_opengl/window_singlethreaded.py index f6e7bb274..534513277 100644 --- a/examples/declarative/rendercontrol/rendercontrol_opengl/window_singlethreaded.py +++ b/examples/declarative/rendercontrol/rendercontrol_opengl/window_singlethreaded.py @@ -55,7 +55,7 @@ from PySide6.QtQml import QQmlComponent, QQmlEngine from PySide6.QtQuick import (QQuickGraphicsDevice, QQuickItem, QQuickRenderControl, QQuickRenderTarget, QQuickWindow) -from PySide6.QtCore import QCoreApplication, QTimer, QUrl +from PySide6.QtCore import QCoreApplication, QTimer, QUrl, Slot from shiboken6 import VoidPtr from cuberenderer import CubeRenderer @@ -164,6 +164,7 @@ class WindowSingleThreaded(QWindow): def set_texture_id(self, texture_id): self.m_texture_ids[0] = texture_id + @Slot() def createTexture(self): # The scene graph has been initialized. It is now time to create a # texture and associate it with the QQuickWindow. @@ -183,10 +184,12 @@ class WindowSingleThreaded(QWindow): self.m_textureSize) self.m_quickWindow.setRenderTarget(target) + @Slot() def destroyTexture(self): self.m_context.functions().glDeleteTextures(1, self.m_texture_ids) self.set_texture_id(0) + @Slot() def render(self): if not self.m_context.makeCurrent(self.m_offscreenSurface): return @@ -287,6 +290,7 @@ class WindowSingleThreaded(QWindow): and self.m_textureSize != self.size() * self.devicePixelRatio()): self.resizeTexture() + @Slot() def handleScreenChange(self): if self.m_dpr != self.devicePixelRatio(): self.resizeTexture() diff --git a/examples/multimedia/audiooutput/audiooutput.py b/examples/multimedia/audiooutput/audiooutput.py index 2950a66a0..de1177693 100644 --- a/examples/multimedia/audiooutput/audiooutput.py +++ b/examples/multimedia/audiooutput/audiooutput.py @@ -289,7 +289,7 @@ class AudioTest(QMainWindow): QAudio.StoppedState: "StoppedState", QAudio.IdleState: "IdleState"} - @Slot(QAudio.State) + @Slot("QAudio::State") def handle_state_changed(self, state): state = self.state_map.get(state, 'Unknown') qWarning(f"state = {state}") diff --git a/examples/multimedia/player/player.py b/examples/multimedia/player/player.py index d0bdbb4c1..430b876a7 100644 --- a/examples/multimedia/player/player.py +++ b/examples/multimedia/player/player.py @@ -203,6 +203,7 @@ class MainWindow(QMainWindow): self._playlist_index += 1 self._player.setSource(self._playlist[self._playlist_index]) + @Slot("QMediaPlayer::PlaybackState") def update_buttons(self, state): media_count = len(self._playlist) self._play_action.setEnabled(media_count > 0 @@ -215,7 +216,7 @@ class MainWindow(QMainWindow): def show_status_message(self, message): self.statusBar().showMessage(message, 5000) - @Slot(QMediaPlayer.Error, str) + @Slot("QMediaPlayer::Error", str) def _player_error(self, error, error_string): print(error_string, file=sys.stderr) self.show_status_message(error_string) diff --git a/examples/opengl/contextinfo/contextinfo.py b/examples/opengl/contextinfo/contextinfo.py index a3bab44d8..67a2cd8d1 100644 --- a/examples/opengl/contextinfo/contextinfo.py +++ b/examples/opengl/contextinfo/contextinfo.py @@ -47,7 +47,8 @@ import sys from textwrap import dedent -from PySide6.QtCore import QCoreApplication, QLibraryInfo, QSize, QTimer, Qt +from PySide6.QtCore import (QCoreApplication, QLibraryInfo, QSize, QTimer, Qt, + Slot) from PySide6.QtGui import (QMatrix4x4, QOpenGLContext, QSurfaceFormat, QWindow) from PySide6.QtOpenGL import (QOpenGLBuffer, QOpenGLShader, QOpenGLShaderProgram, QOpenGLVertexArrayObject) @@ -230,6 +231,7 @@ class RenderWindow(QWindow): self.context.swapBuffers(self) self.context.doneCurrent() + @Slot() def slot_timer(self): self.render() self.angle += 1 diff --git a/examples/opengl/hellogl2/hellogl2.py b/examples/opengl/hellogl2/hellogl2.py index 733cc25ee..3e1c5ac3d 100644 --- a/examples/opengl/hellogl2/hellogl2.py +++ b/examples/opengl/hellogl2/hellogl2.py @@ -46,7 +46,8 @@ from argparse import ArgumentParser, RawTextHelpFormatter import ctypes import math import sys -from PySide6.QtCore import QCoreApplication, Signal, SIGNAL, SLOT, Qt, QSize, QPointF +from PySide6.QtCore import (QCoreApplication, Signal, Slot, + Qt, QSize, QPointF) from PySide6.QtGui import (QVector3D, QOpenGLFunctions, QMatrix4x4, QOpenGLContext, QSurfaceFormat, QVector3DList) from PySide6.QtOpenGL import (QOpenGLVertexArrayObject, QOpenGLBuffer, @@ -266,6 +267,7 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions): angle -= 360 * 16 return angle + @Slot(int) def set_xrotation(self, angle): angle = self.normalize_angle(angle) if angle != self._x_rot: @@ -273,6 +275,7 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions): self.x_rotation_changed.emit(angle) self.update() + @Slot(int) def set_yrotation(self, angle): angle = self.normalize_angle(angle) if angle != self._y_rot: @@ -280,6 +283,7 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions): self.y_rotation_changed.emit(angle) self.update() + @Slot(int) def set_zrotation(self, angle): angle = self.normalize_angle(angle) if angle != self._z_rot: @@ -287,6 +291,7 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions): self.z_rotation_changed.emit(angle) self.update() + @Slot() def cleanup(self): self.makeCurrent() self._logo_vbo.destroy() diff --git a/examples/opengl/threadedqopenglwidget/glwidget.py b/examples/opengl/threadedqopenglwidget/glwidget.py index bb3ffdf19..d280dd3bc 100644 --- a/examples/opengl/threadedqopenglwidget/glwidget.py +++ b/examples/opengl/threadedqopenglwidget/glwidget.py @@ -105,6 +105,7 @@ class GLWidget(QOpenGLWidget): def on_resized(self): self._renderer.unlock_renderer() + @Slot() def grab_context(self): if not self._renderer: return diff --git a/examples/samplebinding/CMakeLists.txt b/examples/samplebinding/CMakeLists.txt index 6de44b6ae..665316623 100644 --- a/examples/samplebinding/CMakeLists.txt +++ b/examples/samplebinding/CMakeLists.txt @@ -42,7 +42,7 @@ set(generated_sources # ================================== Shiboken detection ====================================== # Use provided python interpreter if given. if(NOT python_interpreter) - if(WIN32 AND ${CMAKE_BUILD_TYPE} STREQUAL "Debug") + if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") find_program(python_interpreter "python_d") if(NOT python_interpreter) message(FATAL_ERROR @@ -173,7 +173,7 @@ set_property(TARGET ${bindings_library} PROPERTY PREFIX "") set_property(TARGET ${bindings_library} PROPERTY OUTPUT_NAME "${bindings_library}${PYTHON_EXTENSION_SUFFIX}") if(WIN32) - if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set_property(TARGET ${bindings_library} PROPERTY SUFFIX "_d.pyd") else() set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd") diff --git a/examples/scriptableapplication/CMakeLists.txt b/examples/scriptableapplication/CMakeLists.txt index ff1cda25e..430932815 100644 --- a/examples/scriptableapplication/CMakeLists.txt +++ b/examples/scriptableapplication/CMakeLists.txt @@ -18,7 +18,7 @@ find_package(Qt6 COMPONENTS Widgets) # Use provided python interpreter if given. if(NOT python_interpreter) - if(WIN32 AND ${CMAKE_BUILD_TYPE} STREQUAL "Debug") + if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") find_program(python_interpreter "python_d") if(NOT python_interpreter) message(FATAL_ERROR diff --git a/examples/texttospeech/hello_speak/hello_speak.py b/examples/texttospeech/hello_speak/hello_speak.py index 97a46121d..2d1fcc882 100644 --- a/examples/texttospeech/hello_speak/hello_speak.py +++ b/examples/texttospeech/hello_speak/hello_speak.py @@ -42,7 +42,7 @@ """PySide6 QTextToSpeech example""" import sys -from PySide6.QtCore import Qt +from PySide6.QtCore import Qt, Slot from PySide6.QtWidgets import (QApplication, QComboBox, QFormLayout, QHBoxLayout, QLineEdit, QMainWindow, QPushButton, QSlider, QWidget) @@ -91,12 +91,14 @@ class MainWindow(QMainWindow): self.setWindowTitle('QTextToSpeech Example (no engines available)') self.sayButton.setEnabled(False) + @Slot() def say(self): self.sayButton.setEnabled(False) self.engine.setVoice(self.voices[self.voiceCombo.currentIndex()]) self.engine.setVolume(float(self.volumeSlider.value()) / 100) self.engine.say(self.text.text()) + @Slot("QTextToSpeech::State") def stateChanged(self, state): if (state == QTextToSpeech.State.Ready): self.sayButton.setEnabled(True) diff --git a/examples/webenginequick/nanobrowser/quicknanobrowser.py b/examples/webenginequick/nanobrowser/quicknanobrowser.py index 393bf5808..119bea213 100644 --- a/examples/webenginequick/nanobrowser/quicknanobrowser.py +++ b/examples/webenginequick/nanobrowser/quicknanobrowser.py @@ -48,8 +48,8 @@ from PySide6.QtWebEngineQuick import QtWebEngineQuick def main(): - app = QApplication([]) QtWebEngineQuick.initialize() + app = QApplication([]) engine = QQmlApplicationEngine() qml_file_path = os.path.join(os.path.dirname(__file__), 'browser.qml') qml_url = QUrl.fromLocalFile(os.path.abspath(qml_file_path)) diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.py b/examples/webenginewidgets/markdowneditor/mainwindow.py index 5bf455b96..ff5eb9c19 100644 --- a/examples/webenginewidgets/markdowneditor/mainwindow.py +++ b/examples/webenginewidgets/markdowneditor/mainwindow.py @@ -84,7 +84,7 @@ class MainWindow(QMainWindow): data = defaultTextFile.readAll() self._ui.editor.setPlainText(data.data().decode('utf8')) - @Slot(str) + @Slot() def plainTextEditChanged(self): self.m_content.setText(self._ui.editor.toPlainText()) diff --git a/examples/webenginewidgets/simplebrowser/simplebrowser.py b/examples/webenginewidgets/simplebrowser/simplebrowser.py index f5d550439..557f9fec6 100644 --- a/examples/webenginewidgets/simplebrowser/simplebrowser.py +++ b/examples/webenginewidgets/simplebrowser/simplebrowser.py @@ -42,7 +42,7 @@ """PySide6 WebEngineWidgets Example""" import sys -from PySide6.QtCore import QUrl +from PySide6.QtCore import QUrl, Slot from PySide6.QtGui import QIcon from PySide6.QtWidgets import (QApplication, QLineEdit, QMainWindow, QPushButton, QToolBar) @@ -80,17 +80,21 @@ class MainWindow(QMainWindow): self.webEngineView.page().titleChanged.connect(self.setWindowTitle) self.webEngineView.page().urlChanged.connect(self.urlChanged) + @Slot() def load(self): url = QUrl.fromUserInput(self.addressLineEdit.text()) if url.isValid(): self.webEngineView.load(url) + @Slot() def back(self): self.webEngineView.page().triggerAction(QWebEnginePage.Back) + @Slot() def forward(self): self.webEngineView.page().triggerAction(QWebEnginePage.Forward) + @Slot(QUrl) def urlChanged(self, url): self.addressLineEdit.setText(url.toString()) diff --git a/examples/webenginewidgets/tabbedbrowser/browsertabwidget.py b/examples/webenginewidgets/tabbedbrowser/browsertabwidget.py index 1fb7ead45..5930902b6 100644 --- a/examples/webenginewidgets/tabbedbrowser/browsertabwidget.py +++ b/examples/webenginewidgets/tabbedbrowser/browsertabwidget.py @@ -43,8 +43,8 @@ from functools import partial from bookmarkwidget import BookmarkWidget from webengineview import WebEngineView from historywindow import HistoryWindow -from PySide6 import QtCore -from PySide6.QtCore import Qt, QUrl +from PySide6.QtCore import Qt, QUrl, Signal, Slot +from PySide6.QtGui import QIcon from PySide6.QtWidgets import QMenu, QTabBar, QTabWidget from PySide6.QtWebEngineCore import QWebEngineDownloadRequest, QWebEnginePage @@ -52,9 +52,9 @@ from PySide6.QtWebEngineCore import QWebEngineDownloadRequest, QWebEnginePage class BrowserTabWidget(QTabWidget): """Enables having several tabs with QWebEngineView.""" - url_changed = QtCore.Signal(QUrl) - enabled_changed = QtCore.Signal(QWebEnginePage.WebAction, bool) - download_requested = QtCore.Signal(QWebEngineDownloadRequest) + url_changed = Signal(QUrl) + enabled_changed = Signal(QWebEnginePage.WebAction, bool) + download_requested = Signal(QWebEngineDownloadRequest) def __init__(self, window_factory_function): super().__init__() @@ -104,21 +104,25 @@ class BrowserTabWidget(QTabWidget): index = self.currentIndex() return self._webengineviews[index].url() if index >= 0 else QUrl() + @Slot(QUrl) def _url_changed(self, url): index = self.currentIndex() if index >= 0 and self._webengineviews[index] == self.sender(): self.url_changed.emit(url) + @Slot(str) def _title_changed(self, title): index = self._index_of_page(self.sender()) if (index >= 0): self.setTabText(index, BookmarkWidget.short_title(title)) + @Slot(QIcon) def _icon_changed(self, icon): index = self._index_of_page(self.sender()) if (index >= 0): self.setTabIcon(index, icon) + @Slot(object,bool) def _enabled_changed(self, web_action, enabled): index = self.currentIndex() if index >= 0 and self._webengineviews[index] == self.sender(): @@ -240,5 +244,6 @@ class BrowserTabWidget(QTabWidget): return p return -1 + @Slot(QWebEngineDownloadRequest) def _download_requested(self, item): self.download_requested.emit(item) diff --git a/examples/webenginewidgets/tabbedbrowser/webengineview.py b/examples/webenginewidgets/tabbedbrowser/webengineview.py index 185be0a31..47b3598c2 100644 --- a/examples/webenginewidgets/tabbedbrowser/webengineview.py +++ b/examples/webenginewidgets/tabbedbrowser/webengineview.py @@ -41,7 +41,7 @@ from PySide6.QtWebEngineCore import QWebEnginePage from PySide6.QtWebEngineWidgets import QWebEngineView -from PySide6 import QtCore +from PySide6.QtCore import Signal, Slot _web_actions = [QWebEnginePage.Back, QWebEnginePage.Forward, QWebEnginePage.Reload, @@ -52,7 +52,7 @@ _web_actions = [QWebEnginePage.Back, QWebEnginePage.Forward, class WebEngineView(QWebEngineView): - enabled_changed = QtCore.Signal(QWebEnginePage.WebAction, bool) + enabled_changed = Signal(QWebEnginePage.WebAction, bool) @staticmethod def web_actions(): @@ -86,6 +86,7 @@ class WebEngineView(QWebEngineView): return self._tab_factory_func() return self._window_factory_func() + @Slot() def _enabled_changed(self): action = self.sender() web_action = self._actions[action] diff --git a/examples/widgetbinding/CMakeLists.txt b/examples/widgetbinding/CMakeLists.txt index 2fe1ddcb0..c51f47620 100644 --- a/examples/widgetbinding/CMakeLists.txt +++ b/examples/widgetbinding/CMakeLists.txt @@ -52,7 +52,7 @@ set(generated_sources # ================================== Shiboken detection ====================================== # Use provided python interpreter if given. if(NOT python_interpreter) - if(WIN32 AND ${CMAKE_BUILD_TYPE} STREQUAL "Debug") + if(WIN32 AND "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") find_program(python_interpreter "python_d") if(NOT python_interpreter) message(FATAL_ERROR @@ -218,7 +218,7 @@ set_property(TARGET ${bindings_library} PROPERTY PREFIX "") set_property(TARGET ${bindings_library} PROPERTY OUTPUT_NAME "${bindings_library}${PYTHON_EXTENSION_SUFFIX}") if(WIN32) - if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set_property(TARGET ${bindings_library} PROPERTY SUFFIX "_d.pyd") else() set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd") diff --git a/examples/widgets/codeeditor/codeeditor.py b/examples/widgets/codeeditor/codeeditor.py index 25290c63f..1961b2f4b 100644 --- a/examples/widgets/codeeditor/codeeditor.py +++ b/examples/widgets/codeeditor/codeeditor.py @@ -106,11 +106,11 @@ class CodeEditor(QPlainTextEdit): bottom = top + self.blockBoundingRect(block).height() block_number += 1 - @Slot() + @Slot(int) def update_line_number_area_width(self, newBlockCount): self.setViewportMargins(self.line_number_area_width(), 0, 0, 0) - @Slot() + @Slot(QRect, int) def update_line_number_area(self, rect, dy): if dy: self.line_number_area.scroll(0, dy) diff --git a/examples/widgets/desktop/screenshot/screenshot.py b/examples/widgets/desktop/screenshot/screenshot.py index 19aa4c354..529f35bba 100644 --- a/examples/widgets/desktop/screenshot/screenshot.py +++ b/examples/widgets/desktop/screenshot/screenshot.py @@ -42,7 +42,8 @@ import sys -from PySide6.QtCore import QDir, QPoint, QRect, QStandardPaths, Qt, QTimer +from PySide6.QtCore import (QDir, QPoint, QRect, QStandardPaths, Qt, QTimer, + Slot) from PySide6.QtGui import QGuiApplication, QImageWriter from PySide6.QtWidgets import (QApplication, QCheckBox, QDialog, QFileDialog, QGridLayout, QGroupBox, QHBoxLayout, QLabel, @@ -109,6 +110,7 @@ class Screenshot(QWidget): if scaled_size != self.screenshot_label.pixmap().size(): self.update_screenshot_label() + @Slot() def new_screenshot(self): if self.hide_this_window_checkbox.isChecked(): self.hide() @@ -116,6 +118,7 @@ class Screenshot(QWidget): QTimer.singleShot(self.delay_spinbox.value() * 1000, self.shoot_screen) + @Slot() def save_screenshot(self): fmt = "png" # In order to avoid shadowing built-in format initial_path = QStandardPaths.writableLocation(QStandardPaths.PicturesLocation) @@ -164,6 +167,7 @@ class Screenshot(QWidget): if self.hide_this_window_checkbox.isChecked(): self.show() + @Slot() def update_checkbox(self): if self.delay_spinbox.value() == 0: self.hide_this_window_checkbox.setDisabled(True) diff --git a/examples/widgets/dialogs/standarddialogs/standarddialogs.py b/examples/widgets/dialogs/standarddialogs/standarddialogs.py index e456893e3..4cc324ef0 100644 --- a/examples/widgets/dialogs/standarddialogs/standarddialogs.py +++ b/examples/widgets/dialogs/standarddialogs/standarddialogs.py @@ -43,7 +43,7 @@ """PySide6 port of the widgets/dialogs/standarddialogs example from Qt v5.x""" import sys -from PySide6.QtCore import QDir, QRect, Qt +from PySide6.QtCore import QDir, QRect, Qt, Slot from PySide6.QtGui import QFont, QPalette, QScreen from PySide6.QtWidgets import (QApplication, QColorDialog, QCheckBox, QDialog, QErrorMessage, QFontDialog, QFileDialog, QFrame, @@ -275,18 +275,21 @@ class Dialog(QDialog): self.setWindowTitle("Standard Dialogs") + @Slot() def set_integer(self): i, ok = QInputDialog.getInt(self, "QInputDialog.getInteger()", "Percentage:", 25, 0, 100, 1) if ok: self._integer_label.setText(f"{i}%") + @Slot() def set_double(self): d, ok = QInputDialog.getDouble(self, "QInputDialog.getDouble()", "Amount:", 37.56, -10000, 10000, 2) if ok: self._double_label.setText(f"${d:g}") + @Slot() def set_item(self): items = ("Spring", "Summer", "Fall", "Winter") @@ -295,6 +298,7 @@ class Dialog(QDialog): if ok and item: self._item_label.setText(item) + @Slot() def set_text(self): text, ok = QInputDialog.getText(self, "QInputDialog.getText()", "User name:", QLineEdit.Normal, @@ -302,12 +306,14 @@ class Dialog(QDialog): if ok and text != '': self._text_label.setText(text) + @Slot() def set_multiline_text(self): text, ok = QInputDialog.getMultiLineText(self, "QInputDialog::getMultiLineText()", "Address:", "John Doe\nFreedom Street") if ok and text != '': self._multiline_text_label.setText(text) + @Slot() def set_color(self): options_value = self._color_options.value() options = QColorDialog.ColorDialogOptions(options_value) @@ -318,6 +324,7 @@ class Dialog(QDialog): self._color_label.setPalette(QPalette(color)) self._color_label.setAutoFillBackground(True) + @Slot() def set_font(self): options_value = self._font_options.value() options = QFontDialog.FontDialogOptions(options_value) @@ -332,6 +339,7 @@ class Dialog(QDialog): self._font_label.setText(font.key()) self._font_label.setFont(font) + @Slot() def set_existing_directory(self): options_value = self._file_options.value() options = QFileDialog.Options(options_value) | QFileDialog.ShowDirsOnly @@ -342,6 +350,7 @@ class Dialog(QDialog): if directory: self._directory_label.setText(directory) + @Slot() def set_open_file_name(self): options_value = self._file_options.value() options = QFileDialog.Options(options_value) @@ -353,6 +362,7 @@ class Dialog(QDialog): if fileName: self._open_file_name_label.setText(fileName) + @Slot() def set_open_file_names(self): options_value = self._file_options.value() options = QFileDialog.Options(options_value) @@ -365,6 +375,7 @@ class Dialog(QDialog): file_list = ', '.join(files) self._open_file_names_label.setText(f"[{file_list}]") + @Slot() def set_save_file_name(self): options_value = self._file_options.value() options = QFileDialog.Options(options_value) @@ -376,6 +387,7 @@ class Dialog(QDialog): if fileName: self._save_file_name_label.setText(fileName) + @Slot() def critical_message(self): reply = QMessageBox.critical(self, "QMessageBox.critical()", Dialog.MESSAGE, @@ -387,6 +399,7 @@ class Dialog(QDialog): else: self._critical_label.setText("Ignore") + @Slot() def information_message(self): reply = QMessageBox.information(self, "QMessageBox.information()", Dialog.MESSAGE) @@ -395,6 +408,7 @@ class Dialog(QDialog): else: self._information_label.setText("Escape") + @Slot() def question_message(self): reply = QMessageBox.question(self, "QMessageBox.question()", Dialog.MESSAGE, @@ -406,6 +420,7 @@ class Dialog(QDialog): else: self._question_label.setText("Cancel") + @Slot() def warning_message(self): msg_box = QMessageBox(QMessageBox.Warning, "QMessageBox.warning()", Dialog.MESSAGE, @@ -417,6 +432,7 @@ class Dialog(QDialog): else: self._warning_label.setText("Continue") + @Slot() def error_message(self): self._error_message_dialog.showMessage("This dialog shows and remembers " "error messages. If the checkbox is checked (as it is by " diff --git a/examples/widgets/graphicsview/diagramscene/diagramscene.py b/examples/widgets/graphicsview/diagramscene/diagramscene.py index b56e8d6fe..6f473d75a 100644 --- a/examples/widgets/graphicsview/diagramscene/diagramscene.py +++ b/examples/widgets/graphicsview/diagramscene/diagramscene.py @@ -44,10 +44,11 @@ import math import sys from PySide6.QtCore import (QLineF, QPointF, QRect, QRectF, QSize, QSizeF, Qt, - Signal) + Signal, Slot) from PySide6.QtGui import (QAction, QColor, QFont, QIcon, QIntValidator, QPainter, QPainterPath, QPen, QPixmap, QPolygonF) -from PySide6.QtWidgets import (QApplication, QButtonGroup, QComboBox, +from PySide6.QtWidgets import (QAbstractButton, QApplication, QButtonGroup, + QComboBox, QFontComboBox, QGraphicsAnchorLayout, QGraphicsItem, QGraphicsLineItem, QGraphicsPolygonItem, QGraphicsTextItem, @@ -420,6 +421,7 @@ class MainWindow(QMainWindow): self.setCentralWidget(self.widget) self.setWindowTitle("Diagramscene") + @Slot(QAbstractButton) def background_button_group_clicked(self, button): buttons = self._background_button_group.buttons() for myButton in buttons: @@ -439,6 +441,7 @@ class MainWindow(QMainWindow): self.scene.update() self.view.update() + @Slot(int) def button_group_clicked(self, idx): buttons = self._button_group.buttons() for button in buttons: @@ -451,15 +454,18 @@ class MainWindow(QMainWindow): self.scene.set_item_type(idx) self.scene.set_mode(DiagramScene.InsertItem) + @Slot() def delete_item(self): for item in self.scene.selectedItems(): if isinstance(item, DiagramItem): item.remove_arrows() self.scene.removeItem(item) + @Slot(int) def pointer_group_clicked(self, i): self.scene.set_mode(self._pointer_type_group.checkedId()) + @Slot() def bring_to_front(self): if not self.scene.selectedItems(): return @@ -473,6 +479,7 @@ class MainWindow(QMainWindow): z_value = item.zValue() + 0.1 selected_item.setZValue(z_value) + @Slot() def send_to_back(self): if not self.scene.selectedItems(): return @@ -486,21 +493,26 @@ class MainWindow(QMainWindow): z_value = item.zValue() - 0.1 selected_item.setZValue(z_value) + @Slot(QGraphicsPolygonItem) def item_inserted(self, item): self._pointer_type_group.button(DiagramScene.MoveItem).setChecked(True) self.scene.set_mode(self._pointer_type_group.checkedId()) self._button_group.button(item.diagram_type).setChecked(False) + @Slot(QGraphicsTextItem) def text_inserted(self, item): self._button_group.button(self.insert_text_button).setChecked(False) self.scene.set_mode(self._pointer_type_group.checkedId()) + @Slot(QFont) def current_font_changed(self, font): self.handle_font_change() + @Slot(int) def font_size_changed(self, font): self.handle_font_change() + @Slot(str) def scene_scale_changed(self, scale): new_scale = int(scale[:-1]) / 100.0 old_matrix = self.view.transform() @@ -508,6 +520,7 @@ class MainWindow(QMainWindow): self.view.translate(old_matrix.dx(), old_matrix.dy()) self.view.scale(new_scale, new_scale) + @Slot() def text_color_changed(self): self._text_action = self.sender() self._font_color_tool_button.setIcon(self.create_color_tool_button_icon( @@ -515,6 +528,7 @@ class MainWindow(QMainWindow): QColor(self._text_action.data()))) self.text_button_triggered() + @Slot() def item_color_changed(self): self._fill_action = self.sender() self._fill_color_tool_button.setIcon(self.create_color_tool_button_icon( @@ -522,6 +536,7 @@ class MainWindow(QMainWindow): QColor(self._fill_action.data()))) self.fill_button_triggered() + @Slot() def line_color_changed(self): self._line_action = self.sender() self._line_color_tool_button.setIcon(self.create_color_tool_button_icon( @@ -529,15 +544,19 @@ class MainWindow(QMainWindow): QColor(self._line_action.data()))) self.line_button_triggered() + @Slot() def text_button_triggered(self): self.scene.set_text_color(QColor(self._text_action.data())) + @Slot() def fill_button_triggered(self): self.scene.set_item_color(QColor(self._fill_action.data())) + @Slot() def line_button_triggered(self): self.scene.set_line_color(QColor(self._line_action.data())) + @Slot() def handle_font_change(self): font = self._font_combo.currentFont() font.setPointSize(int(self._font_size_combo.currentText())) @@ -550,6 +569,7 @@ class MainWindow(QMainWindow): self.scene.set_font(font) + @Slot(QGraphicsItem) def item_selected(self, item): font = item.font() color = item.defaultTextColor() @@ -559,6 +579,7 @@ class MainWindow(QMainWindow): self._italic_action.setChecked(font.italic()) self._underline_action.setChecked(font.underline()) + @Slot() def about(self): QMessageBox.about(self, "About Diagram Scene", "The <b>Diagram Scene</b> example shows use of the graphics framework.") diff --git a/examples/widgets/graphicsview/elasticnodes/elasticnodes.py b/examples/widgets/graphicsview/elasticnodes/elasticnodes.py index 8d0fcf0f3..201c35f0a 100644 --- a/examples/widgets/graphicsview/elasticnodes/elasticnodes.py +++ b/examples/widgets/graphicsview/elasticnodes/elasticnodes.py @@ -167,7 +167,7 @@ class Node(QGraphicsItem): self._new_pos = QPointF() self.setFlag(QGraphicsItem.ItemIsMovable) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) - self.setCacheMode(self.DeviceCoordinateCache) + self.setCacheMode(QGraphicsItem.DeviceCoordinateCache) self.setZValue(-1) def item_type(self): diff --git a/examples/widgets/itemviews/address_book/address_book.py b/examples/widgets/itemviews/address_book/address_book.py index e00664974..77f63437f 100644 --- a/examples/widgets/itemviews/address_book/address_book.py +++ b/examples/widgets/itemviews/address_book/address_book.py @@ -40,6 +40,7 @@ ## ############################################################################# +from PySide6.QtCore import Slot from PySide6.QtGui import QAction from PySide6.QtWidgets import (QMainWindow, QFileDialog, QApplication) @@ -98,11 +99,13 @@ class MainWindow(QMainWindow): # # In PySide6, these functions return a tuple: (filename, filter) + @Slot() def open_file(self): filename, _ = QFileDialog.getOpenFileName(self) if filename: self._address_widget.read_from_file(filename) + @Slot() def save_file(self): filename, _ = QFileDialog.getSaveFileName(self) if filename: diff --git a/examples/widgets/itemviews/address_book/addresswidget.py b/examples/widgets/itemviews/address_book/addresswidget.py index 3dec400c6..2a8db4366 100644 --- a/examples/widgets/itemviews/address_book/addresswidget.py +++ b/examples/widgets/itemviews/address_book/addresswidget.py @@ -45,7 +45,7 @@ try: except ImportError: import pickle -from PySide6.QtCore import (Qt, Signal, QRegularExpression, QModelIndex, +from PySide6.QtCore import (Qt, Signal, Slot, QRegularExpression, QModelIndex, QItemSelection, QSortFilterProxyModel) from PySide6.QtWidgets import QTabWidget, QMessageBox, QTableView, QAbstractItemView @@ -73,6 +73,7 @@ class AddressWidget(QTabWidget): self.setup_tabs() + @Slot() def add_entry(self, name=None, address=None): """ Add an entry to the addressbook. """ if name is None and address is None: @@ -121,6 +122,7 @@ class AddressWidget(QTabWidget): table_view = self.currentWidget() table_view.resizeRowToContents(ix.row()) + @Slot() def edit_entry(self): """ Edit an entry in the addressbook. """ table_view = self.currentWidget() @@ -153,6 +155,7 @@ class AddressWidget(QTabWidget): ix = self._table_model.index(row, 1, QModelIndex()) self._table_model.setData(ix, new_address, Qt.EditRole) + @Slot() def remove_entry(self): """ Remove an entry from the addressbook. """ table_view = self.currentWidget() diff --git a/examples/widgets/itemviews/basicfiltermodel/basicsortfiltermodel.py b/examples/widgets/itemviews/basicfiltermodel/basicsortfiltermodel.py index d229f84b4..fa44337d2 100644 --- a/examples/widgets/itemviews/basicfiltermodel/basicsortfiltermodel.py +++ b/examples/widgets/itemviews/basicfiltermodel/basicsortfiltermodel.py @@ -42,7 +42,7 @@ import sys from PySide6.QtCore import (QDate, QDateTime, QRegularExpression, - QSortFilterProxyModel, QTime, Qt) + QSortFilterProxyModel, QTime, Qt, Slot) from PySide6.QtGui import QStandardItemModel from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit, @@ -140,6 +140,7 @@ class Window(QWidget): self._proxy_model.setSourceModel(model) self._source_view.setModel(model) + @Slot() def filter_reg_exp_changed(self): syntax_nr = self._filter_syntax_combo_box.currentData() pattern = self._filter_pattern_line_edit.text() @@ -155,9 +156,11 @@ class Window(QWidget): reg_exp.setPatternOptions(options) self._proxy_model.setFilterRegularExpression(reg_exp) + @Slot() def filter_column_changed(self): self._proxy_model.setFilterKeyColumn(self._filter_column_combo_box.currentIndex()) + @Slot() def sort_changed(self): if self._sort_case_sensitivity_check_box.isChecked(): case_sensitivity = Qt.CaseSensitive diff --git a/examples/widgets/itemviews/fetchmore/fetchmore.py b/examples/widgets/itemviews/fetchmore/fetchmore.py index 75c5c226e..5e53f2c2f 100644 --- a/examples/widgets/itemviews/fetchmore/fetchmore.py +++ b/examples/widgets/itemviews/fetchmore/fetchmore.py @@ -151,7 +151,7 @@ class Window(QWidget): self.setWindowTitle("Fetch More Example") - @Slot(str, int, int) + @Slot(str,int,int,int) def update_log(self, path, start, number, total): native_path = QDir.toNativeSeparators(path) last = start + number - 1 diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheet.py b/examples/widgets/itemviews/spreadsheet/spreadsheet.py index 0eb424a72..5f7d76da0 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheet.py +++ b/examples/widgets/itemviews/spreadsheet/spreadsheet.py @@ -171,7 +171,7 @@ class SpreadSheet(QMainWindow): about_menu = self.menuBar().addMenu("&Help") about_menu.addAction(self._about_spreadsheet) - @Slot() + @Slot(QTableWidgetItem) def update_status(self, item: QTableWidgetItem) -> None: if item and item == self._table.currentItem(): self.statusBar().showMessage(str(item.data(Qt.StatusTipRole)), 1000) @@ -181,7 +181,7 @@ class SpreadSheet(QMainWindow): ) ) - @Slot() + @Slot(QTableWidgetItem) def update_color(self, item: QTableWidgetItem) -> None: pix = QPixmap(16, 16) col = QColor() @@ -206,7 +206,7 @@ class SpreadSheet(QMainWindow): self._color_action.setIcon(pix) - @Slot() + @Slot(QTableWidgetItem) def update_line_edit(self, item: QTableWidgetItem) -> None: if item != self._table.currentItem(): return diff --git a/examples/widgets/mainwindows/application/application.py b/examples/widgets/mainwindows/application/application.py index 0aa1a3c86..336ce536f 100644 --- a/examples/widgets/mainwindows/application/application.py +++ b/examples/widgets/mainwindows/application/application.py @@ -44,7 +44,7 @@ from argparse import ArgumentParser, RawTextHelpFormatter import sys from PySide6.QtCore import (QByteArray, QFile, QFileInfo, QSaveFile, QSettings, - QTextStream, Qt) + QTextStream, Qt, Slot) from PySide6.QtGui import QAction, QIcon, QKeySequence from PySide6.QtWidgets import (QApplication, QFileDialog, QMainWindow, QMessageBox, QTextEdit, QWidget) @@ -80,23 +80,27 @@ class MainWindow(QMainWindow): else: event.ignore() + @Slot() def new_file(self): if self.maybe_save(): self._text_edit.clear() self.set_current_file('') + @Slot() def open(self): if self.maybe_save(): fileName, filtr = QFileDialog.getOpenFileName(self) if fileName: self.load_file(fileName) + @Slot() def save(self): if self._cur_file: return self.save_file(self._cur_file) return self.save_as() + @Slot() def save_as(self): fileName, filtr = QFileDialog.getSaveFileName(self) if fileName: @@ -104,12 +108,14 @@ class MainWindow(QMainWindow): return False + @Slot() def about(self): QMessageBox.about(self, "About Application", "The <b>Application</b> example demonstrates how to write " "modern GUI applications using Qt, with a menu bar, " "toolbars, and a status bar.") + @Slot() def document_was_modified(self): self.setWindowModified(self._text_edit.document().isModified()) diff --git a/examples/widgets/mainwindows/mdi/mdi.py b/examples/widgets/mainwindows/mdi/mdi.py index e8ed8792f..a5afc18f3 100644 --- a/examples/widgets/mainwindows/mdi/mdi.py +++ b/examples/widgets/mainwindows/mdi/mdi.py @@ -47,7 +47,7 @@ from functools import partial import sys from PySide6.QtCore import (QByteArray, QFile, QFileInfo, QPoint, QSettings, - QSaveFile, QSize, QTextStream, Qt) + QSaveFile, QSize, QTextStream, Qt, Slot) from PySide6.QtGui import QAction, QIcon, QKeySequence from PySide6.QtWidgets import (QApplication, QFileDialog, QMainWindow, QMdiArea, QMessageBox, QTextEdit, QWidget) @@ -194,11 +194,13 @@ class MainWindow(QMainWindow): self.write_settings() event.accept() + @Slot() def new_file(self): child = self.create_mdi_child() child.new_file() child.show() + @Slot() def open(self): file_name, _ = QFileDialog.getOpenFileName(self) if file_name: @@ -216,31 +218,38 @@ class MainWindow(QMainWindow): else: child.close() + @Slot() def save(self): if self.active_mdi_child() and self.active_mdi_child().save(): self.statusBar().showMessage("File saved", 2000) + @Slot() def save_as(self): if self.active_mdi_child() and self.active_mdi_child().save_as(): self.statusBar().showMessage("File saved", 2000) + @Slot() def cut(self): if self.active_mdi_child(): self.active_mdi_child().cut() + @Slot() def copy(self): if self.active_mdi_child(): self.active_mdi_child().copy() + @Slot() def paste(self): if self.active_mdi_child(): self.active_mdi_child().paste() + @Slot() def about(self): QMessageBox.about(self, "About MDI", "The <b>MDI</b> example demonstrates how to write multiple " "document interface applications using Qt.") + @Slot() def update_menus(self): has_mdi_child = (self.active_mdi_child() is not None) self._save_act.setEnabled(has_mdi_child) @@ -259,6 +268,7 @@ class MainWindow(QMainWindow): self._cut_act.setEnabled(has_selection) self._copy_act.setEnabled(has_selection) + @Slot() def update_window_menu(self): self._window_menu.clear() self._window_menu.addAction(self._close_act) @@ -440,6 +450,7 @@ class MainWindow(QMainWindow): return window return None + @Slot() def switch_layout_direction(self): if self.layoutDirection() == Qt.LeftToRight: QApplication.setLayoutDirection(Qt.RightToLeft) diff --git a/examples/widgets/richtext/orderform/orderform.py b/examples/widgets/richtext/orderform/orderform.py index 10cb64dc3..313d2009e 100644 --- a/examples/widgets/richtext/orderform/orderform.py +++ b/examples/widgets/richtext/orderform/orderform.py @@ -194,6 +194,7 @@ class MainWindow(QMainWindow): '12 High Street\nSmall Town\nThis country', dialog.order_items(), True) + @Slot() def open_dialog(self): dialog = DetailsDialog("Enter Customer Details", self) @@ -201,6 +202,7 @@ class MainWindow(QMainWindow): self.create_letter(dialog.sender_name(), dialog.sender_address(), dialog.order_items(), dialog.send_offers()) + @Slot() def print_file(self): editor = self.letters.currentWidget() printer = QPrinter() @@ -279,6 +281,7 @@ class DetailsDialog(QDialog): def send_offers(self): return self._offers_check_box.isChecked() + @Slot() def verify(self): if self._name_edit.text() and self._address_edit.toPlainText(): self.accept() diff --git a/examples/widgets/richtext/textobject/textobject.py b/examples/widgets/richtext/textobject/textobject.py index db32d24e6..b8daabd2c 100644 --- a/examples/widgets/richtext/textobject/textobject.py +++ b/examples/widgets/richtext/textobject/textobject.py @@ -46,7 +46,7 @@ import os from pathlib import Path import sys -from PySide6.QtCore import QFile, QIODevice, QObject, QSizeF, Qt +from PySide6.QtCore import QFile, QIODevice, QObject, QSizeF, Qt, Slot from PySide6.QtGui import (QTextCharFormat, QTextFormat, QTextObjectInterface, QPyTextObject) from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QLineEdit, @@ -89,6 +89,7 @@ class Window(QWidget): self.setWindowTitle(self.tr("Text Object Example")) + @Slot() def insert_text_object(self): file_name = self._file_name_line_edit.text() file = QFile(file_name) diff --git a/examples/widgets/tetrix/tetrix.py b/examples/widgets/tetrix/tetrix.py index 54536c2ae..621a81ac9 100644 --- a/examples/widgets/tetrix/tetrix.py +++ b/examples/widgets/tetrix/tetrix.py @@ -178,6 +178,7 @@ class TetrixBoard(QFrame): return QSize(TetrixBoard.board_width * 5 + self.frameWidth() * 2, TetrixBoard.board_height * 5 + self.frameWidth() * 2) + @Slot() def start(self): if self._is_paused: return @@ -197,6 +198,7 @@ class TetrixBoard(QFrame): self.new_piece() self.timer.start(self.timeout_time(), self) + @Slot() def pause(self): if not self._is_started: return diff --git a/examples/widgets/tools/regularexpression/regularexpressiondialog.py b/examples/widgets/tools/regularexpression/regularexpressiondialog.py index a21a4365c..fd654c7c8 100644 --- a/examples/widgets/tools/regularexpression/regularexpressiondialog.py +++ b/examples/widgets/tools/regularexpression/regularexpressiondialog.py @@ -113,6 +113,7 @@ class PatternLineEdit(QLineEdit): self.copyToCodeAction.triggered.connect(self.copyToCode) self.pasteFromCodeAction.triggered.connect(self.pasteFromCode) + @Slot() def escapeSelection(self): selection = self.selectedText() selection_start = self.selectionStart() @@ -126,9 +127,11 @@ class PatternLineEdit(QLineEdit): ) self.setText(t) + @Slot() def copyToCode(self): QGuiApplication.clipboard().setText(patternToCode(self.text())) + @Slot() def pasteFromCode(self): self.setText(codeToPattern(QGuiApplication.clipboard().text())) @@ -202,6 +205,7 @@ class RegularExpressionDialog(QDialog): self.palette.setColor(QPalette.Text, color) widget.setPalette(self.palette) + @Slot() def refresh(self): self.setUpdatesEnabled(False) self.pattern = self.patternLineEdit.text() diff --git a/examples/widgets/tutorials/addressbook/part3.py b/examples/widgets/tutorials/addressbook/part3.py index 686a1c530..fae65c156 100644 --- a/examples/widgets/tutorials/addressbook/part3.py +++ b/examples/widgets/tutorials/addressbook/part3.py @@ -148,6 +148,7 @@ class AddressBook(QWidget): self._submit_button.show() self._cancel_button.show() + @Slot() def submit_contact(self): name = self._name_line.text() address = self._address_text.toPlainText() @@ -181,6 +182,7 @@ class AddressBook(QWidget): self._submit_button.hide() self._cancel_button.hide() + @Slot() def cancel(self): self._name_line.setText(self._old_name) self._address_text.setText(self._old_address) @@ -200,6 +202,7 @@ class AddressBook(QWidget): self._submit_button.hide() self._cancel_button.hide() + @Slot() def next(self): name = self._name_line.text() it = iter(self.contacts) @@ -217,6 +220,7 @@ class AddressBook(QWidget): self._name_line.setText(next_name) self._address_text.setText(next_address) + @Slot() def previous(self): name = self._name_line.text() diff --git a/examples/widgets/tutorials/addressbook/part4.py b/examples/widgets/tutorials/addressbook/part4.py index b12f1c010..c13908f98 100644 --- a/examples/widgets/tutorials/addressbook/part4.py +++ b/examples/widgets/tutorials/addressbook/part4.py @@ -143,6 +143,7 @@ class AddressBook(QWidget): self.setLayout(main_layout) self.setWindowTitle("Simple Address Book") + @Slot() def add_contact(self): self._old_name = self._name_line.text() self._old_address = self._address_text.toPlainText() @@ -152,12 +153,14 @@ class AddressBook(QWidget): self.update_interface(self.AddingMode) + @Slot() def edit_contact(self): self._old_name = self._name_line.text() self._old_address = self._address_text.toPlainText() self.update_interface(self.EditingMode) + @Slot() def submit_contact(self): name = self._name_line.text() address = self._address_text.toPlainText() @@ -195,11 +198,13 @@ class AddressBook(QWidget): self.update_interface(self.NavigationMode) + @Slot() def cancel(self): self._name_line.setText(self._old_name) self._address_text.setText(self._old_address) self.update_interface(self.NavigationMode) + @Slot() def remove_contact(self): name = self._name_line.text() address = self._address_text.toPlainText() @@ -218,6 +223,7 @@ class AddressBook(QWidget): self.update_interface(self.NavigationMode) + @Slot() def next(self): name = self._name_line.text() it = iter(self.contacts) @@ -235,6 +241,7 @@ class AddressBook(QWidget): self._name_line.setText(next_name) self._address_text.setText(next_address) + @Slot() def previous(self): name = self._name_line.text() diff --git a/examples/widgets/tutorials/addressbook/part5.py b/examples/widgets/tutorials/addressbook/part5.py index 7da3a8322..a8259fa76 100644 --- a/examples/widgets/tutorials/addressbook/part5.py +++ b/examples/widgets/tutorials/addressbook/part5.py @@ -150,6 +150,7 @@ class AddressBook(QWidget): self.setLayout(main_layout) self.setWindowTitle("Simple Address Book") + @Slot() def add_contact(self): self._old_name = self._name_line.text() self._old_address = self._address_text.toPlainText() @@ -159,12 +160,14 @@ class AddressBook(QWidget): self.update_interface(self.AddingMode) + @Slot() def edit_contact(self): self._old_name = self._name_line.text() self._old_address = self._address_text.toPlainText() self.update_interface(self.EditingMode) + @Slot() def submit_contact(self): name = self._name_line.text() address = self._address_text.toPlainText() @@ -202,11 +205,13 @@ class AddressBook(QWidget): self.update_interface(self.NavigationMode) + @Slot() def cancel(self): self._name_line.setText(self._old_name) self._address_text.setText(self._old_address) self.update_interface(self.NavigationMode) + @Slot() def remove_contact(self): name = self._name_line.text() address = self._address_text.toPlainText() @@ -225,6 +230,7 @@ class AddressBook(QWidget): self.update_interface(self.NavigationMode) + @Slot() def next(self): name = self._name_line.text() it = iter(self.contacts) @@ -242,6 +248,7 @@ class AddressBook(QWidget): self._name_line.setText(next_name) self._address_text.setText(next_address) + @Slot() def previous(self): name = self._name_line.text() diff --git a/examples/widgets/tutorials/addressbook/part6.py b/examples/widgets/tutorials/addressbook/part6.py index eb0cec30e..ad5aa04bd 100644 --- a/examples/widgets/tutorials/addressbook/part6.py +++ b/examples/widgets/tutorials/addressbook/part6.py @@ -160,6 +160,7 @@ class AddressBook(QWidget): self.setLayout(main_layout) self.setWindowTitle("Simple Address Book") + @Slot() def add_contact(self): self._old_name = self._name_line.text() self._old_address = self._address_text.toPlainText() @@ -169,12 +170,14 @@ class AddressBook(QWidget): self.update_interface(self.AddingMode) + @Slot() def edit_contact(self): self._old_name = self._name_line.text() self._old_address = self._address_text.toPlainText() self.update_interface(self.EditingMode) + @Slot() def submit_contact(self): name = self._name_line.text() address = self._address_text.toPlainText() @@ -212,11 +215,13 @@ class AddressBook(QWidget): self.update_interface(self.NavigationMode) + @Slot() def cancel(self): self._name_line.setText(self._old_name) self._address_text.setText(self._old_address) self.update_interface(self.NavigationMode) + @Slot() def remove_contact(self): name = self._name_line.text() address = self._address_text.toPlainText() @@ -235,6 +240,7 @@ class AddressBook(QWidget): self.update_interface(self.NavigationMode) + @Slot() def next(self): name = self._name_line.text() it = iter(self.contacts) @@ -252,6 +258,7 @@ class AddressBook(QWidget): self._name_line.setText(next_name) self._address_text.setText(next_address) + @Slot() def previous(self): name = self._name_line.text() diff --git a/examples/widgets/tutorials/addressbook/part7.py b/examples/widgets/tutorials/addressbook/part7.py index 817a54219..22e949663 100644 --- a/examples/widgets/tutorials/addressbook/part7.py +++ b/examples/widgets/tutorials/addressbook/part7.py @@ -166,6 +166,7 @@ class AddressBook(QWidget): self.setLayout(main_layout) self.setWindowTitle("Simple Address Book") + @Slot() def add_contact(self): self._old_name = self._name_line.text() self._old_address = self._address_text.toPlainText() @@ -175,12 +176,14 @@ class AddressBook(QWidget): self.update_interface(self.AddingMode) + @Slot() def edit_contact(self): self._old_name = self._name_line.text() self._old_address = self._address_text.toPlainText() self.update_interface(self.EditingMode) + @Slot() def submit_contact(self): name = self._name_line.text() address = self._address_text.toPlainText() @@ -218,11 +221,13 @@ class AddressBook(QWidget): self.update_interface(self.NavigationMode) + @Slot() def cancel(self): self._name_line.setText(self._old_name) self._address_text.setText(self._old_address) self.update_interface(self.NavigationMode) + @Slot() def remove_contact(self): name = self._name_line.text() address = self._address_text.toPlainText() @@ -241,6 +246,7 @@ class AddressBook(QWidget): self.update_interface(self.NavigationMode) + @Slot() def next(self): name = self._name_line.text() it = iter(self.contacts) @@ -258,6 +264,7 @@ class AddressBook(QWidget): self._name_line.setText(next_name) self._address_text.setText(next_address) + @Slot() def previous(self): name = self._name_line.text() diff --git a/examples/widgets/widgetsgallery/widgetgallery.py b/examples/widgets/widgetsgallery/widgetgallery.py index c0bb392e2..f2a63262a 100644 --- a/examples/widgets/widgetsgallery/widgetgallery.py +++ b/examples/widgets/widgetsgallery/widgetgallery.py @@ -45,7 +45,7 @@ from PySide6.QtGui import (QCursor, QDesktopServices, QGuiApplication, QIcon, QKeySequence, QShortcut, QStandardItem, QStandardItemModel, QScreen, QWindow) from PySide6.QtCore import (QDateTime, QDir, QLibraryInfo, QMetaObject, - QSysInfo, QTextStream, QTimer, Qt, qVersion) + QSysInfo, QTextStream, QTimer, Qt, qVersion, Slot) POEM = """Twinkle, twinkle, little star, @@ -217,9 +217,11 @@ class WidgetGallery(QDialog): self.windowHandle().screenChanged.connect(self.update_systeminfo) self.update_systeminfo() + @Slot(str) def change_style(self, style_name): QApplication.setStyle(QStyleFactory.create(style_name)) + @Slot() def advance_progressbar(self): cur_val = self._progress_bar.value() max_val = self._progress_bar.maximum() @@ -416,6 +418,7 @@ class WidgetGallery(QDialog): timer.start(1000) return result + @Slot() def update_systeminfo(self): """Display system information""" system_info = SYSTEMINFO.format(sys.version, @@ -424,6 +427,7 @@ class WidgetGallery(QDialog): screen_info(self)) self._systeminfo_textbrowser.setHtml(system_info) + @Slot() def help_on_current_widget(self): """Display help on widget under mouse""" w = QApplication.widgetAt(QCursor.pos(self.screen())) diff --git a/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml b/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml index 165cd310f..7c260bfc0 100644 --- a/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml +++ b/sources/pyside6/PySide6/QtBluetooth/typesystem_bluetooth.xml @@ -53,7 +53,7 @@ <enum-type name="Pairing"/> </object-type> <object-type name="QBluetoothDeviceDiscoveryAgent"> - <enum-type name="DiscoveryMethod"/> + <enum-type name="DiscoveryMethod" flags="DiscoveryMethods"/> <enum-type name="Error"/> </object-type> <value-type name="QBluetoothDeviceInfo"> diff --git a/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt b/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt index 3f960bcff..85d4cdfd2 100644 --- a/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt +++ b/sources/pyside6/PySide6/QtWidgets/CMakeLists.txt @@ -37,6 +37,7 @@ ${QtWidgets_GEN_DIR}/qfocusframe_wrapper.cpp ${QtWidgets_GEN_DIR}/qfontcombobox_wrapper.cpp ${QtWidgets_GEN_DIR}/qfontdialog_wrapper.cpp ${QtWidgets_GEN_DIR}/qformlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qformlayout_takerowresult_wrapper.cpp ${QtWidgets_GEN_DIR}/qframe_wrapper.cpp ${QtWidgets_GEN_DIR}/qgesture_wrapper.cpp ${QtWidgets_GEN_DIR}/qgestureevent_wrapper.cpp diff --git a/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml index 1df831d72..384b03b27 100644 --- a/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml +++ b/sources/pyside6/PySide6/QtWidgets/typesystem_widgets_common.xml @@ -2295,10 +2295,19 @@ <include file-name="QPixmap" location="global"/> </extra-includes> + <!-- FIXME PYSIDE-7: Remove deprecated overloads --> <modify-function signature="critical(QWidget*,const QString&,const QString&,QFlags<QMessageBox::StandardButton>,QMessageBox::StandardButton)" allow-thread="yes"/> + <modify-function signature="critical(QWidget*,const QString&,const QString&,QMessageBox::StandardButton,QMessageBox::StandardButton)" + allow-thread="yes"/> <modify-function signature="information(QWidget*,const QString&,const QString&,QFlags<QMessageBox::StandardButton>,QMessageBox::StandardButton)" allow-thread="yes"/> + <modify-function signature="information(QWidget*,const QString&,const QString&,QMessageBox::StandardButton,QMessageBox::StandardButton)" + allow-thread="yes"/> <modify-function signature="question(QWidget*,const QString&,const QString&,QFlags<QMessageBox::StandardButton>,QMessageBox::StandardButton)" allow-thread="yes"/> + <modify-function signature="question(QWidget*,const QString&,const QString&,QMessageBox::StandardButton,QMessageBox::StandardButton)" + allow-thread="yes"/> <modify-function signature="warning(QWidget*,const QString&,const QString&,QFlags<QMessageBox::StandardButton>,QMessageBox::StandardButton)" allow-thread="yes"/> + <modify-function signature="warning(QWidget*,const QString&,const QString&,QMessageBox::StandardButton,QMessageBox::StandardButton)" + allow-thread="yes"/> <modify-function signature="QMessageBox(const QString&,const QString&,QMessageBox::Icon,int,int,int,QWidget*,QFlags<Qt::WindowType>)" remove="all"/> <modify-function signature="critical(QWidget*,const QString&,const QString&,int,int,int)" remove="all"/> <modify-function signature="critical(QWidget*,const QString&,const QString&,const QString&,const QString&,const QString&,int,int)" remove="all"/> @@ -2912,6 +2921,9 @@ <enum-type name="ItemRole"/> <enum-type name="RowWrapPolicy"/> + <value-type name="TakeRowResult"> + <include file-name="QFormLayout" location="global"/> + </value-type> <modify-function signature="getLayoutPosition(QLayout*,int*,QFormLayout::ItemRole*)const"> <modify-argument index="0"> diff --git a/sources/pyside6/PySide6/glue/qtwidgets.cpp b/sources/pyside6/PySide6/glue/qtwidgets.cpp index b355f41cb..f95db9ee5 100644 --- a/sources/pyside6/PySide6/glue/qtwidgets.cpp +++ b/sources/pyside6/PySide6/glue/qtwidgets.cpp @@ -96,6 +96,11 @@ QFormLayout::ItemRole _role; %CPPSELF->%FUNCTION_NAME(%ARGUMENT_NAMES, &_row, &_role); %PYARG_0 = PyTuple_New(2); PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](_row)); +// On the C++ side, *rolePtr is not set if row == -1, in which case on +// the Python side this gets converted to a random value outside the +// enum range. Fix this by setting _role to a default value here. +if (_row == -1) + _role = QFormLayout::LabelRole; PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QFormLayout::ItemRole](_role)); // @snippet qformlayout-fix-args diff --git a/sources/pyside6/PySide6/qtguihelper.h b/sources/pyside6/PySide6/qtguihelper.h index 4fee6c53e..acc0de6a8 100644 --- a/sources/pyside6/PySide6/qtguihelper.h +++ b/sources/pyside6/PySide6/qtguihelper.h @@ -50,7 +50,7 @@ namespace QtGuiHelper { Q_DISABLE_COPY_MOVE(QOverrideCursorGuard) QOverrideCursorGuard() = default; - ~QOverrideCursorGuard() { restoreOverrideCursor(); } + ~QOverrideCursorGuard() = default; void restoreOverrideCursor() { diff --git a/sources/pyside6/doc/modules.rst b/sources/pyside6/doc/modules.rst index 9b20d6906..7134c2638 100644 --- a/sources/pyside6/doc/modules.rst +++ b/sources/pyside6/doc/modules.rst @@ -1,5 +1,5 @@ -Qt Modules -=========== +Qt Modules Supported by Qt for Python +===================================== .. toctree:: :hidden: diff --git a/sources/pyside6/tests/QtWidgets/qformlayout_test.py b/sources/pyside6/tests/QtWidgets/qformlayout_test.py index 55348daaa..7cd59b63f 100644 --- a/sources/pyside6/tests/QtWidgets/qformlayout_test.py +++ b/sources/pyside6/tests/QtWidgets/qformlayout_test.py @@ -35,7 +35,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) from init_paths import init_test_paths init_test_paths(False) -from PySide6.QtWidgets import QFormLayout, QWidget +from PySide6.QtWidgets import QFormLayout, QWidget, QLabel, QMainWindow from helper.usesqapplication import UsesQApplication @@ -44,12 +44,11 @@ class QFormLayoutTest(UsesQApplication): def testGetItemPosition(self): formlayout = QFormLayout() - if not sys.pyside63_option_python_enum: - # PYSIDE-1735: This gives random values if no row exists. - row, role = formlayout.getItemPosition(0) - self.assertTrue(isinstance(row, int)) - self.assertTrue(isinstance(role, QFormLayout.ItemRole)) - self.assertEqual(row, -1) + + row, role = formlayout.getItemPosition(0) + self.assertTrue(isinstance(row, int)) + self.assertTrue(isinstance(role, QFormLayout.ItemRole)) + self.assertEqual(row, -1) widget = QWidget() formlayout.addRow(widget) @@ -62,12 +61,11 @@ class QFormLayoutTest(UsesQApplication): def testGetWidgetPosition(self): formlayout = QFormLayout() widget = QWidget() - if not sys.pyside63_option_python_enum: - # PYSIDE-1735: This gives random values if no row exists. - row, role = formlayout.getWidgetPosition(widget) - self.assertTrue(isinstance(row, int)) - self.assertTrue(isinstance(role, QFormLayout.ItemRole)) - self.assertEqual(row, -1) + + row, role = formlayout.getWidgetPosition(widget) + self.assertTrue(isinstance(row, int)) + self.assertTrue(isinstance(role, QFormLayout.ItemRole)) + self.assertEqual(row, -1) formlayout.addRow(widget) row, role = formlayout.getWidgetPosition(widget) @@ -79,12 +77,11 @@ class QFormLayoutTest(UsesQApplication): def testGetLayoutPosition(self): formlayout = QFormLayout() layout = QFormLayout() - if not sys.pyside63_option_python_enum: - # PYSIDE-1735: This gives random values if no row exists. - row, role = formlayout.getLayoutPosition(layout) - self.assertTrue(isinstance(row, int)) - self.assertTrue(isinstance(role, QFormLayout.ItemRole)) - self.assertEqual(row, -1) + + row, role = formlayout.getLayoutPosition(layout) + self.assertTrue(isinstance(row, int)) + self.assertTrue(isinstance(role, QFormLayout.ItemRole)) + self.assertEqual(row, -1) formlayout.addRow(layout) row, role = formlayout.getLayoutPosition(layout) @@ -93,7 +90,35 @@ class QFormLayoutTest(UsesQApplication): self.assertEqual(row, 0) self.assertEqual(role, QFormLayout.SpanningRole) + def testTakeRow(self): + window = QMainWindow() + window.setCentralWidget(QWidget()) + formlayout = QFormLayout(window.centralWidget()) + + widget_label = "blub" + widget = QLabel(widget_label) + + self.assertEqual(formlayout.count(), 0) + formlayout.addRow(widget) + self.assertEqual(formlayout.count(), 1) + self.assertEqual(formlayout.itemAt(0).widget(), widget) + + widget_id = id(widget) + + # Now there are no more references to the original widget on the + # Python side. Assert that this does not break the references to + # the widget on the C++ side so that "taking" the row will work. + del widget + + takeRowResult = formlayout.takeRow(0) + self.assertEqual(formlayout.count(), 0) + + widget = takeRowResult.fieldItem.widget() + + self.assertIsNotNone(widget) + self.assertEqual(widget_id, id(widget)) + self.assertEqual(widget.text(), widget_label) + if __name__ == "__main__": unittest.main() - diff --git a/sources/pyside6/tests/registry/existence_test.py b/sources/pyside6/tests/registry/existence_test.py index 2ab18152a..fa6cdde34 100644 --- a/sources/pyside6/tests/registry/existence_test.py +++ b/sources/pyside6/tests/registry/existence_test.py @@ -72,8 +72,8 @@ import unittest from pathlib import Path sys.path.append(os.fspath(Path(__file__).resolve().parents[1])) -from init_paths import init_all_test_paths -init_all_test_paths() +from init_paths import init_test_paths +init_test_paths(True) from init_platform import enum_all, generate_all from util import (isolate_warnings, check_warnings, suppress_warnings, warn, @@ -119,6 +119,19 @@ if have_refmodule and not hasattr(sig_exists, dict_name): have_refmodule = False +class TestUnrecognizedOffending(unittest.TestCase): + """ + We run the signature generation on all modules and raise an error + if a warning was issued. This is better than turning warnings into + errors because that would stop early before we have all warnings. + """ + def test_signatures_recognized(self): + with isolate_warnings(): + found_sigs = enum_all() + if check_warnings(): + raise RuntimeError("There are errors, see above.") + + @unittest.skipIf(not have_refmodule, "not activated for this platform or version") class TestSignaturesExists(unittest.TestCase): diff --git a/sources/pyside6/tests/registry/init_platform.py b/sources/pyside6/tests/registry/init_platform.py index 06c488ee3..e22d2c9b8 100644 --- a/sources/pyside6/tests/registry/init_platform.py +++ b/sources/pyside6/tests/registry/init_platform.py @@ -1,6 +1,6 @@ ############################################################################# ## -## Copyright (C) 2019 The Qt Company Ltd. +## Copyright (C) 2022 The Qt Company Ltd. ## Contact: https://www.qt.io/licensing/ ## ## This file is part of Qt for Python. @@ -113,13 +113,7 @@ def set_ospaths(build_dir): ps = os.pathsep ospath_var = "PATH" if sys.platform == "win32" else "LD_LIBRARY_PATH" old_val = os.environ.get(ospath_var, "") - lib_path = [os.path.join(build_dir, "pyside6", "libpyside"), - os.path.join(build_dir, "pyside6", "tests", "pysidetest"), - os.path.join(build_dir, "shiboken6", "tests", "libminimal"), - os.path.join(build_dir, "shiboken6", "tests", "libsample"), - os.path.join(build_dir, "shiboken6", "tests", "libother"), - os.path.join(build_dir, "shiboken6", "tests", "libsmart"), - os.path.join(build_dir, "shiboken6", "libshiboken")] + lib_path = [os.path.join(build_dir, "pyside6", "tests", "pysidetest"),] ospath = ps.join(lib_path + old_val.split(ps)) os.environ[ospath_var] = ospath @@ -139,12 +133,6 @@ all_modules.append("testbinding") from shiboken6 import Shiboken all_modules.append("shiboken6.Shiboken") -# 'sample/smart' are needed by 'other', so import them first. -for modname in "minimal sample smart other".split(): - sys.path.insert(0, os.path.join(shiboken_build_dir, "tests", modname + "binding")) - __import__(modname) - all_modules.append(modname) - from shibokensupport.signature.lib.enum_sig import SimplifyingEnumerator # Make sure not to get .pyc in Python2. @@ -208,6 +196,48 @@ def enum_all(): return ret +LICENSE_TEXT = """ +############################################################################# +## +## Copyright (C) 2022 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# +""" + + def generate_all(): refPath = get_refpath() module = os.path.basename(os.path.splitext(refPath)[0]) @@ -218,7 +248,7 @@ def generate_all(): license_line = next((lno for lno, line in enumerate(lines) if "$QT_END_LICENSE$" in line)) fmt.print("#recreate # uncomment this to enforce generation") - fmt.print("".join(lines[:license_line + 3])) + fmt.print(LICENSE_TEXT) version = sys.version.replace('\n', ' ') build = qt_build() fmt.print(dedent(f'''\ diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp index 44f3e97c4..7f9fb42b8 100644 --- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp +++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp @@ -676,8 +676,11 @@ QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &c if (equalSign == std::string::npos) return QString(); ++equalSign; - return QString::fromLocal8Bit(snippet.data() + equalSign, - qsizetype(snippet.size() - equalSign)).trimmed(); + QString result = QString::fromLocal8Bit(snippet.data() + equalSign, + qsizetype(snippet.size() - equalSign)); + // Fix a default expression as read from code. Simplify white space + result.remove(u'\r'); + return result.contains(u'"') ? result.trimmed() : result.simplified(); } // Resolve a type (loop over aliases/typedefs), for example for base classes diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py index 2fd2b6c4f..94e2143f2 100644 --- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py +++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py @@ -236,7 +236,7 @@ def create_signature(props, key): # parser. pass else: - if varnames[0] in ("self", "cls"): + if varnames and varnames[0] in ("self", "cls"): varnames = varnames[1:] # calculate the modifications diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py index 63cb423c1..f1148eaaf 100644 --- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py +++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py @@ -61,7 +61,7 @@ class ellipsis(object): return "..." ellipsis = ellipsis() -Point = typing.Tuple[float, float] +Point = typing.Tuple[int, int] Variant = typing.Any QImageCleanupFunction = typing.Callable @@ -318,6 +318,8 @@ type_map.update({ "zero(str)": "", "zero(typing.Any)": None, "zero(Any)": None, + # This can be refined by importing numpy.typing optionally, but better than nothing. + "numpy.ndarray": typing.List[typing.Any], }) type_map.update({ @@ -692,9 +694,20 @@ def init_PySide6_QtBluetooth(): return locals() +def init_PySide6_QtHttpServer(): + type_map.update({ + "qMakePair(1u, 1u)": (1, 1), + }) + return locals() + + def init_testbinding(): type_map.update({ "testbinding.PySideCPP2.TestObjectWithoutNamespace": testbinding.TestObjectWithoutNamespace, + "testbinding.FlagsNamespace.Options": testbinding.Option, + "FlagsNamespace.Option.NoOptions": 0, + "StdIntList": typing.List[int], + 'Str("")': str(""), }) return locals() diff --git a/tools/snippets_translate/converter.py b/tools/snippets_translate/converter.py index 01df94505..77250a857 100644 --- a/tools/snippets_translate/converter.py +++ b/tools/snippets_translate/converter.py @@ -46,7 +46,7 @@ from handlers import (handle_array_declarations, handle_casts, handle_class, handle_inc_dec, handle_include, handle_keywords, handle_methods_return_type, handle_negate, handle_type_var_declaration, handle_useless_qt_classes, - handle_void_functions) + handle_void_functions, handle_qt_connects) from parse_utils import dstrip, get_indent, remove_ref @@ -76,6 +76,10 @@ def snippet_translate(x): x = x.replace("//", "#", 1) return x + qt_connects = handle_qt_connects(x) + if qt_connects: + return qt_connects + # Handle "->" if "->" in x: x = x.replace("->", ".") diff --git a/tools/snippets_translate/handlers.py b/tools/snippets_translate/handlers.py index 40ba71841..72c70eef8 100644 --- a/tools/snippets_translate/handlers.py +++ b/tools/snippets_translate/handlers.py @@ -545,3 +545,49 @@ def handle_useless_qt_classes(x): if content: x = x.replace(content.group(0), content.group(1)) return x + + +# The code below handles pairs of instance/pointer to member functions (PMF) +# which appear in Qt in connect statements like: +# "connect(fontButton, &QAbstractButton::clicked, this, &Dialog::setFont)". +# In a first pass, these pairs are replaced by: +# "connect(fontButton.clicked, self.setFont)" to be able to handle statements +# spanning lines. A 2nd pass then checks for the presence of a connect +# statement and replaces it by: +# "fontButton.clicked.connect(self.setFont)". +# To be called right after checking for comments. + + +INSTANCE_PMF_RE = re.compile(r"&?(\w+),\s*&\w+::(\w+)") + + +CONNECT_RE = re.compile(r"^(\s*)(QObject::)?connect\((\w+\.\w+),\s*") + + +def handle_qt_connects(line): + if not INSTANCE_PMF_RE.search(line): + return None + # 1st pass, "fontButton, &QAbstractButton::clicked" -> "fontButton.clicked" + last_pos = 0 + result = "" + for match in INSTANCE_PMF_RE.finditer(line): + instance = match.group(1) + if instance == "this": + instance = "self" + member_fun = match.group(2) + next_pos = match.start() + result += line[last_pos:next_pos] + last_pos = match.end() + result += f"{instance}.{member_fun}" + result += line[last_pos:] + + # 2nd pass, reorder connect. + connect_match = CONNECT_RE.match(result) + if not connect_match: + return result + + space = connect_match.group(1) + signal_ = connect_match.group(3) + connect_stmt = f"{space}{signal_}.connect(" + connect_stmt += result[connect_match.end():] + return connect_stmt diff --git a/tools/snippets_translate/tests/test_converter.py b/tools/snippets_translate/tests/test_converter.py index b2d6468d8..2c127a7ba 100644 --- a/tools/snippets_translate/tests/test_converter.py +++ b/tools/snippets_translate/tests/test_converter.py @@ -137,7 +137,7 @@ def test_double_colon(): # multiline statement connect statement # eg: connect(reply, &QNetworkReply::errorOccurred, # this, &MyClass::slotError); - assert st("this, &MyClass::slotError);") == "self, MyClass.slotError)" + assert st("this, &MyClass::slotError);") == "self.slotError)" def test_cout_endl(): @@ -411,7 +411,7 @@ def test_special_cases(): ) assert ( st("QObject::connect(&window1, &Window::messageSent,") - == "QObject.connect(window1, Window.messageSent," + == "window1.messageSent.connect(" ) assert st("double num;") == "num = float()" |