[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: [PyQt] Problem sometimes connecting signal/slot in a loop
From:       Sebastian Schleehauf <slepton () posteo ! de>
Date:       2019-05-19 9:36:29
Message-ID: 21e8d89d99582e7df2cf8e07a531f9eb12ba28e5.camel () posteo ! de
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


In the past I have used the following approach which does the trick
quite well by using a dict containing instances and colors instead of a
list with colors. With self.sender() one can obtain the corresponding
color. A functional example can be found below. 
Since the question has been solved allready, I am sending this to find
out if my approach can be considerd "good" and if it has any side
effect I am currently not aware of....
import sys

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QWidget, QPushButton, QColorDialog,
QApplication, QVBoxLayout


class ButtonColorWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        # Create  some sample buttons with color mapping
        self.button_color_dict = dict()
        for n in range(4):
            button = QPushButton('Button ' + str(n))
            self.button_color_dict[button] = QColor('black')  #
initial_color
            self.layout.addWidget(button)
            button.clicked.connect(self.start_dialog)
        # ColorDialog
        self.color_dialog = QColorDialog(self)

    @pyqtSlot()
    def start_dialog(self):
        button = self.sender()
        if button is None:
            print('Directly calling this method is ignored...')
            return
        new_color =
self.color_dialog.getColor(self.button_color_dict[button])

        if new_color.isValid():
            button.setStyleSheet('QPushButton{color: ' +
new_color.name()+'};')
            self.button_color_dict[button] = new_color
            print('Set new color ', new_color.name())
        else:
            print('Aborted...')
        return


application = QApplication(sys.argv)
widget = ButtonColorWidget()
widget.show()
sys.exit(application.exec_()) 



Am Freitag, den 17.05.2019, 06:34 -0700 schrieb Luna Tuna:
> Thanks, I'll check it out. 
> 
> I just made a local function "connectButton" and that does the
> trick.  But I like the default lambda parameter for more conciseness.
> 
> On Fri, May 17, 2019 at 1:06 AM Florian Bruhin <me@the-compiler.org>
> wrote:
> > Hi,
> > 
> > 
> > 
> > another possibility is using functools.partial instead:
> > 
> > 
> > 
> >    
> > button.clicked.connect(functools.partial(self.show_color_dialog,
> > color))
> > 
> > 
> > 
> > IMHO, this is a nice explanation of the issue and possible
> > solutions:
> > 
> > 
https://docs.python-guide.org/writing/gotchas/#late-binding-closures
> > 
> > 
> > 
> > Florian
> > 
> > 
> > 
> > _______________________________________________PyQt mailing
> > list    PyQt@riverbankcomputing.com
> > https://www.riverbankcomputing.com/mailman/listinfo/pyqt

[Attachment #5 (text/html)]

<html dir="ltr"><head></head><body style="text-align:left; \
direction:ltr;"><div><br></div><div>In the past I have used the following approach \
which does the trick quite well by using a dict containing instances and colors \
instead of a list with colors. With self.sender() one can obtain the corresponding \
color. A functional example can be found below. </div><div><br></div><div>Since the \
question has been solved allready, I am sending this to find out if my approach can \
be considerd "good" and if it has any side effect I am currently not aware \
of....</div><div><br></div><pre \
style="background-color:#2b2b2b;color:#a9b7c6;font-family:'DejaVu Sans \
Mono';font-size:9,0pt;"><span style="color:#cc7832;">import </span>sys<br><br><span \
style="color:#cc7832;">from </span>PyQt5.QtCore <span style="color:#cc7832;">import \
</span>pyqtSlot<br><span style="color:#cc7832;">from </span>PyQt5.QtGui <span \
style="color:#cc7832;">import </span>QColor<br><span style="color:#cc7832;">from \
</span>PyQt5.QtWidgets <span style="color:#cc7832;">import </span>QWidget<span \
style="color:#cc7832;">, </span>QPushButton<span style="color:#cc7832;">, \
</span>QColorDialog<span style="color:#cc7832;">, </span>QApplication<span \
style="color:#cc7832;">, </span>QVBoxLayout<br><br><br><span \
style="color:#cc7832;">class </span>ButtonColorWidget(QWidget):<br>    <span \
style="color:#cc7832;">def </span><span style="color:#b200b2;">__init__</span>(<span \
style="color:#94558d;">self</span><span style="color:#cc7832;">, </span>parent=<span \
style="color:#cc7832;">None</span>):<br>        <span \
style="color:#8888c6;">super</span>().<span \
style="color:#b200b2;">__init__</span>(<span \
style="color:#aa4926;">parent</span>=parent)<br>        <span \
style="color:#94558d;">self</span>.layout = QVBoxLayout()<br>        <span \
style="color:#94558d;">self</span>.setLayout(<span \
style="color:#94558d;">self</span>.layout)<br>        <span style="color:#808080;"># \
Create  some sample buttons with color mapping<br></span><span \
style="color:#808080;">        </span><span \
style="color:#94558d;">self</span>.button_color_dict = <span \
style="color:#8888c6;">dict</span>()<br>        <span style="color:#cc7832;">for \
</span>n <span style="color:#cc7832;">in </span><span \
style="color:#8888c6;">range</span>(<span style="color:#6897bb;">4</span>):<br>       \
button = QPushButton(<span style="color:#6a8759;">'Button ' </span>+ <span \
style="color:#8888c6;">str</span>(n))<br>            <span \
style="color:#94558d;">self</span>.button_color_dict[button] = QColor(<span \
style="color:#6a8759;">'black'</span>)  <span style="color:#808080;"># \
initial_color<br></span><span style="color:#808080;">            </span><span \
style="color:#94558d;">self</span>.layout.addWidget(button)<br>            \
button.clicked.connect(<span style="color:#94558d;">self</span>.start_dialog)<br>     \
<span style="color:#808080;"># ColorDialog<br></span><span style="color:#808080;">    \
</span><span style="color:#94558d;">self</span>.color_dialog = QColorDialog(<span \
style="color:#94558d;">self</span>)<br><br>    <span \
style="color:#bbb529;">@pyqtSlot</span>()<br>    <span style="color:#cc7832;">def \
</span><span style="color:#ffc66d;">start_dialog</span>(<span \
style="color:#94558d;">self</span>):<br>        button = <span \
style="color:#94558d;">self</span>.sender()<br>        <span \
style="color:#cc7832;">if </span>button <span style="color:#cc7832;">is \
None</span>:<br>            <span style="color:#8888c6;">print</span>(<span \
style="color:#6a8759;">'Directly calling this method is ignored...'</span>)<br>       \
<span style="color:#cc7832;">return<br></span><span style="color:#cc7832;">        \
</span>new_color = <span \
style="color:#94558d;">self</span>.color_dialog.getColor(<span \
style="color:#94558d;">self</span>.button_color_dict[button])<br><br>        <span \
style="color:#cc7832;">if </span>new_color.isValid():<br>            \
button.setStyleSheet(<span style="color:#6a8759;">'QPushButton{color: ' </span>+ \
new_color.name()+<span style="color:#6a8759;">'};'</span>)<br>            <span \
style="color:#94558d;">self</span>.button_color_dict[button] = new_color<br>          \
<span style="color:#8888c6;">print</span>(<span style="color:#6a8759;">'Set new color \
'</span><span style="color:#cc7832;">, </span>new_color.name())<br>        <span \
style="color:#cc7832;">else</span>:<br>            <span \
style="color:#8888c6;">print</span>(<span \
style="color:#6a8759;">'Aborted...'</span>)<br>        <span \
style="color:#cc7832;">return<br></span><span style="color:#cc7832;"><br></span><span \
style="color:#cc7832;"><br></span>application = QApplication(sys.argv)<br>widget = \
ButtonColorWidget()<br>widget.show()<br></pre><div><span style="color: rgb(169, 183, \
198); font-family: &quot;DejaVu Sans Mono&quot;; background-color: rgb(43, 43, \
43);">sys.exit(application.exec_())</span> \
</div><div><br></div><div><br></div><div><br></div><div><br></div><div>Am Freitag, \
den 17.05.2019, 06:34 -0700 schrieb Luna Tuna:</div><blockquote type="cite" \
style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div \
dir="ltr">Thanks, I'll check it out.&nbsp;<br><div><br></div><div>I just made a local \
function "connectButton" and that does the trick.&nbsp; But I like the default lambda \
parameter for more conciseness.</div></div><br><div class="gmail_quote"><div \
dir="ltr" class="gmail_attr">On Fri, May 17, 2019 at 1:06 AM Florian Bruhin &lt;<a \
href="mailto:me@the-compiler.org">me@the-compiler.org</a>&gt; \
wrote:<br></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px \
#729fcf solid;padding-left:1ex">Hi,<br> <br>
another possibility is using functools.partial instead:<br>
<br>
&nbsp; &nbsp; button.clicked.connect(functools.partial(self.show_color_dialog, \
color))<br> <br>
IMHO, this is a nice explanation of the issue and possible solutions:<br>
<a href="https://docs.python-guide.org/writing/gotchas/#late-binding-closures" \
rel="noreferrer" target="_blank">https://docs.python-guide.org/writing/gotchas/#late-binding-closures</a><br>
 <br>
Florian<br>
<br>
<pre>_______________________________________________</pre><pre>PyQt mailing list    \
<a href="mailto:PyQt@riverbankcomputing.com">PyQt@riverbankcomputing.com</a></pre><pre><a \
href="https://www.riverbankcomputing.com/mailman/listinfo/pyqt">https://www.riverbankc \
omputing.com/mailman/listinfo/pyqt</a></pre><pre><br></pre></blockquote></div></blockquote></body></html>



[Attachment #6 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
https://www.riverbankcomputing.com/mailman/listinfo/pyqt


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic