[PyQt] Cannot connect to the clicked signal of a QPieSeries

Tony Arnold tony.arnold at manchester.ac.uk
Wed Mar 21 16:48:58 GMT 2018


Joseba,

Having tried it, I can't get it ot work either. I believe the
decorator, pyqtSlot, is also only valid in a class derived from
QtQtwidgets, so I restructured your code, but it still did not work.

This looks like a bug to me.

As an alternative, you could connect your slot to the clicked signal of
each slice in the pie and use sender() to find which slice sent the
signal.

Here is my modified version, which works for me:

import sys
from PyQt5.QtCore import pyqtSlot
from PyQt5 import QtWidgets, QtChart, QtGui
from PyQt5.QtChart import QPieSlice

class main(QtWidgets.QMainWindow):
    def __init__(self):
        super(QtWidgets.QMainWindow, self).__init__()

# Create the QChart object and set a few options
        chart = QtChart.QChart()
        chart.legend().hide()
        chart.setAnimationOptions(QtChart.QChart.SeriesAnimations)
        chart.setTitle('My precious')
# Create the series with the plot data with some silly data in it.
        series = QtChart.QPieSeries()
        series.setObjectName('series')
        series.setUseOpenGL(enable=True)
        series.append('Gandalf', 3)
        series.append('Frodo', 1)
# Show the labels in each of the slices
        for i, pie_slice in enumerate(series.slices()):
            pie_slice.setLabelVisible()
            pie_slice.clicked.connect(self.slice_clicked)
# Add the series to the chart, create the view and add some more
options
        chart.addSeries(series)
        view = QtChart.QChartView(chart)
        view.setRenderHint(QtGui.QPainter.Antialiasing)
        self.setCentralWidget(view)
        
    @pyqtSlot()
    def slice_clicked(self):
        clicked_slice=self.sender()
        print('Slice clicked!')
        print(clicked_slice.percentage())


# Create the PyQt app and main window
app = QtWidgets.QApplication(sys.argv)
window = main()
window.resize(640, 480)
window.show()


# It's exec_ because exec is a reserved word in Python
sys.exit(app.exec_())



Regards,
Tony.

On Wed, 2018-03-21 at 16:05 +0100, Joseba Echevarria García wrote:
> Good evening to all,
> 
> Thank you very much for your quick responses!
> I have not been able to make your suggestion work, Tony. I believe I
> have adapted your suggestion but connecting the signal still raises
> TypeError (in fact, even doing `print(series.clicked)` raises the
> TypeError).
> 
> I have been able to make Maurizio's suggestion work, although I'd
> rather go with a more elegant solution if possible.
> 
> Looking at the development snapshot changelogs of sip & PyQt I've
> seen some changes regarding PieSlices; maybe it's just unsupported as
> of now.
> I'm trying to get the pie slice object with QObject.sender(); If that
> does not work I'll probably go with Maurizio's solution.
> 
> The code modified as per Tony's suggestion is shown below:
> import sys
> from PyQt5.QtCore import pyqtSlot, QObject
> from PyQt5 import QtWidgets, QtChart, QtGui
> 
> @pyqtSlot(QtChart.QPieSlice)
> def series_clicked(clicked_slice):
>     print('Slice clicked!')
>     print(clicked_slice.pieSize)
> 
> # Create the PyQt app and main window
> app = QtWidgets.QApplication(sys.argv)
> window = QtWidgets.QMainWindow()
> # Create the QChart object and set a few options
> chart = QtChart.QChart()
> chart.legend().hide()
> chart.setAnimationOptions(QtChart.QChart.SeriesAnimations)
> chart.setTitle('My precious')
> # Create the series with the plot data with some silly data in it.
> series = QtChart.QPieSeries()
> series.setObjectName('series')
> series.setUseOpenGL(enable=True)
> series.append('Gandalf', 3)
> series.append('Frodo', 1)
> # Show the labels in each of the slices
> for i, pie_slice in enumerate(series.slices()):
>     pie_slice.setLabelVisible()
> # Connect the slice clicked signal to the slot
> #     Traceback (most recent call last):
> #       File
> "C:/Users/jechevarria/.PyCharm2017.3/config/scratches/scratch_5.py",
> line 32, in <module>
> #         series.clicked.connect(series_clicked)
> #     TypeError: C++ type 'QPieSlice*' is not supported as a signal
> argument type
> series.clicked.connect(series_clicked)
> # Add the series to the chart, create the view and add some more
> options
> chart.addSeries(series)
> view = QtChart.QChartView(chart)
> view.setRenderHint(QtGui.QPainter.Antialiasing)
> 
> window.resize(640, 480)
> window.setCentralWidget(view)
> window.show()
> 
> # It's exec_ because exec is a reserved word in Python
> sys.exit(app.exec_())
> 
> Regards,
> Joseba
> 
> On Wed, Mar 21, 2018 at 3:05 PM, Tony Arnold <tony.arnold at manchester.
> ac.uk> wrote:
> > Joseba,
> > 
> > On Wed, 2018-03-21 at 12:45 +0100, Joseba Echevarria García wrote:
> > 
> > >
> > I'm trying to create a dynamic QChart plot based on QPieSeries. In
> > > this context I want to be able to detect which pie slice was
> > > clicked.and to do so I have set up a basic example (shown below).
> > >
> > > My problem is that I am unable to detect which slice was clicked;
> > > when connecting the `clicked` signal of a Series I get a
> > TypeError
> > > exception stating:
> > > TypeError: C++ type 'QPieSlice*' is not supported as a signal
> > > argument type
> > >
> > > I'm guessing the feature is not yet implemented? I have
> > > unsuccessfully tried to connect each slice's `clicked` signal to
> > the
> > > slot, but I'm always getting the latest value in the series (
> > > slice_clicked  always sees i=1 always in the example below).
> > >
> > > I'm getting the same exception when trying to connect the hovered
> > > signal. I have also tried passing the type name as a string by
> > using
> > > the @pyqtSlot decorator, to no success.
> > >
> > > Is there anything I can do to be able to connect the `clicked`
> > signal
> > > for the QPieSeries?
> > >
> > > I'm using Python 3.6.3 as bundled with Anaconda, Qt5.10.0, PyQt
> > 5.10
> > > and PyQtChart 5.10 as downloaded from pip on Windows 7 64 bits.
> > >
> > > Sample code:
> > > import sys
> > > from PyQt5 import QtWidgets, QtChart, QtGui
> > 
> > I would add a PyQtSlot decorator for this signal and specify the
> > argument type, viz.,
> > 
> > from PyQt5.QtChart import QPieSlice
> > 
> > @pyqtSlot(QPieSlice)
> > def slice_clicked(slice):
> >     print('Slice clicked!')
> >     print(slice.pieSize)
> > 
> > Hope this helps.
> > 
> > Regards,
> > Tony.
> > --
> > Tony Arnold MBCS, CITP | Senior IT Security Analyst | Directorate
> > of IT Services | G64, Kilburn Building | The University of
> > Manchester | Manchester M13 9PL | T: +44 161 275 6093 | M: +44 773
> > 330 0039
-- 
Tony Arnold MBCS, CITP | Senior IT Security Analyst | Directorate of IT Services | G64, Kilburn Building | The University of Manchester | Manchester M13 9PL | T: +44 161 275 6093 | M: +44 773 330 0039


More information about the PyQt mailing list