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

List:       pykde
Subject:    Re: [PyQt] QTabWidget tab movement?
From:       Matic Kukovec <kukovecmatic () hotmail ! com>
Date:       2019-04-11 20:55:24
Message-ID: VI1PR01MB5344AF95363EDD2F9FC2B26CD72F0 () VI1PR01MB5344 ! eurprd01 ! prod ! exchangelabs ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Excellent, I can work with that.
Great starting point example and suggestions!

Thanks Maurizio
________________________________
From: Maurizio Berti <maurizio.berti@gmail.com>
Sent: Thursday, April 11, 2019 10:10 PM
To: Matic Kukovec
Cc: pyqt@riverbankcomputing.com
Subject: Re: [PyQt] QTabWidget tab movement?

This should do the trick:

class TabWidget(QtWidgets.QTabWidget):
    moveRange = None

    def setMovable(self, movable):
        if movable == self.isMovable():
            return
        QtWidgets.QTabWidget.setMovable(self, movable)
        if movable:
            self.tabBar().installEventFilter(self)
        else:
            self.tabBar().removeEventFilter(self)

    def eventFilter(self, source, event):
        if source == self.tabBar():
            if event.type() == QtCore.QEvent.MouseButtonPress and event.buttons() == \
QtCore.Qt.LeftButton:  QtCore.QTimer.singleShot(0, self.setMoveRange)
            elif event.type() == QtCore.QEvent.MouseButtonRelease:
                self.moveRange = None
            elif event.type() == QtCore.QEvent.MouseMove and self.moveRange is not \
                None:
                if event.x() < self.moveRange[0] or event.x() > self.tabBar().width() \
- self.moveRange[1]:  return True
        return QtWidgets.QTabWidget.eventFilter(self, source, event)

    def setMoveRange(self):
        tabRect = self.tabBar().tabRect(self.currentIndex())
        pos = self.tabBar().mapFromGlobal(QtGui.QCursor.pos())
        self.moveRange = pos.x() - tabRect.left(), tabRect.right() - pos.x()

The delayed setMoveRange() is required since the position of the tab might change if \
you have tabs that would take more space than available for the QTabBar and the \
clicked tab is not fully visible. Keep also in mind that, if that's the case, it \
might create some issues while moving tabs beyond the limit. Also, if you move the \
mouse too fast beyond the limit, the selected bar will be "stuck" according to the \
last accepted mouseMoveEvent. Maybe this could be fixed by sending a fake \
QMouseEvent, but I'm not that sure it would make things "easier" (you should ensure \
that the tabRect is not yet at the edge of the QTabBar before). To avoid all that you \
should probably work harder by subclassing your own QTabBar and then implement \
mouseMoveEvent all by yourself, but this would also require some very difficult \
management of the paintEvent too. Also, remember that I didn't take into account \
margins added by styles, nor the possibility of cornerWidget(s).

Maurizio


Il giorno gio 11 apr 2019 alle ore 21:23 Matic Kukovec \
<kukovecmatic@hotmail.com<mailto:kukovecmatic@hotmail.com>> ha scritto: Hi,

Is there a way to change the behavior and animation of a QTabWidgets tab bar drag \
functionality? [cid:16a0dfa0c4264cee6f1]
In the above image you can see that the dragged tab disappears outside the bounds of \
the tab bar. I would like to remove the movement of tabs outside the tab bar space.

Can anyone suggest of where to begin in changing this behavior?

Thanks,
Matic
_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com<mailto:PyQt@riverbankcomputing.com>
https://www.riverbankcomputing.com/mailman/listinfo/pyqt


--
È difficile avere una convinzione precisa quando si parla delle ragioni del cuore. - \
"Sostiene Pereira", Antonio Tabucchi http://www.jidesk.net


[Attachment #5 (text/html)]

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} \
</style> </head>
<body dir="ltr">
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: \
rgb(0, 0, 0);"> Excellent, I can work with that.</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: \
rgb(0, 0, 0);"> Great starting point example and suggestions!</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: \
rgb(0, 0, 0);"> <br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: \
rgb(0, 0, 0);"> Thanks Maurizio<br>
</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" \
style="font-size:11pt" color="#000000"><b>From:</b> Maurizio Berti \
&lt;maurizio.berti@gmail.com&gt;<br> <b>Sent:</b> Thursday, April 11, 2019 10:10 \
PM<br> <b>To:</b> Matic Kukovec<br>
<b>Cc:</b> pyqt@riverbankcomputing.com<br>
<b>Subject:</b> Re: [PyQt] QTabWidget tab movement?</font>
<div>&nbsp;</div>
</div>
<div>
<div dir="ltr">
<div dir="ltr">This should do the trick:
<div><br>
</div>
<div>
<div><font face="monospace, monospace">class \
TabWidget(QtWidgets.QTabWidget):</font></div> <div><font face="monospace, \
monospace">&nbsp; &nbsp; moveRange = None</font></div> <div><font face="monospace, \
monospace"><br> </font></div>
<div><font face="monospace, monospace">&nbsp; &nbsp; def setMovable(self, \
movable):</font></div> <div><font face="monospace, monospace">&nbsp; &nbsp; &nbsp; \
&nbsp; if movable == self.isMovable():</font></div> <div><font face="monospace, \
monospace">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return</font></div> <div><font \
face="monospace, monospace">&nbsp; &nbsp; &nbsp; &nbsp; \
QtWidgets.QTabWidget.setMovable(self, movable)</font></div> <div><font \
face="monospace, monospace">&nbsp; &nbsp; &nbsp; &nbsp; if movable:</font></div> \
<div><font face="monospace, monospace">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
self.tabBar().installEventFilter(self)</font></div> <div><font face="monospace, \
monospace">&nbsp; &nbsp; &nbsp; &nbsp; else:</font></div> <div><font face="monospace, \
monospace">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
self.tabBar().removeEventFilter(self)</font></div> <div><font face="monospace, \
monospace"><br> </font></div>
<div><font face="monospace, monospace">&nbsp; &nbsp; def eventFilter(self, source, \
event):</font></div> <div><font face="monospace, monospace">&nbsp; &nbsp; &nbsp; \
&nbsp; if source == self.tabBar():</font></div> <div><font face="monospace, \
monospace">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if event.type() == \
QtCore.QEvent.MouseButtonPress and event.buttons() == \
QtCore.Qt.LeftButton:</font></div> <div><font face="monospace, monospace">&nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QtCore.QTimer.singleShot(0, \
self.setMoveRange)</font></div> <div><font face="monospace, monospace">&nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; elif event.type() == \
QtCore.QEvent.MouseButtonRelease:</font></div> <div><font face="monospace, \
monospace">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.moveRange = \
None</font></div> <div><font face="monospace, monospace">&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; elif event.type() == QtCore.QEvent.MouseMove and self.moveRange is not \
None:</font></div> <div><font face="monospace, monospace">&nbsp; &nbsp; &nbsp; &nbsp; \
&nbsp; &nbsp; &nbsp; &nbsp; if event.x() &lt; self.moveRange[0] or event.x() &gt; \
self.tabBar().width() - self.moveRange[1]:</font></div> <div><font face="monospace, \
monospace">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \
return True</font></div> <div><font face="monospace, monospace">&nbsp; &nbsp; &nbsp; \
&nbsp; return QtWidgets.QTabWidget.eventFilter(self, source, event)</font></div> \
<div><font face="monospace, monospace"><br> </font></div>
<div><font face="monospace, monospace">&nbsp; &nbsp; def \
setMoveRange(self):</font></div> <div><font face="monospace, monospace">&nbsp; &nbsp; \
&nbsp; &nbsp; tabRect = self.tabBar().tabRect(self.currentIndex())</font></div> \
<div><font face="monospace, monospace">&nbsp; &nbsp; &nbsp; &nbsp; pos = \
self.tabBar().mapFromGlobal(QtGui.QCursor.pos())</font></div> <div><font \
face="monospace, monospace">&nbsp; &nbsp; &nbsp; &nbsp; self.moveRange = pos.x() - \
tabRect.left(), tabRect.right() - pos.x()</font></div> </div>
<div><br>
</div>
<div>The delayed setMoveRange() is required since the position of the tab might \
change if you have tabs that would take more space than available for the QTabBar and \
the clicked tab is not fully visible.<br> Keep also in mind that, if that's the case, \
it might create some issues while moving tabs beyond the limit.</div> <div>Also, if \
you move the mouse too fast beyond the limit, the selected bar will be \
&quot;stuck&quot; according to the last accepted mouseMoveEvent. Maybe this could be \
fixed by sending a fake QMouseEvent, but I'm not that sure it would make things \
&quot;easier&quot; (you should  ensure that the tabRect is not yet at the edge of the \
QTabBar before).<br> To avoid all that you should probably work harder by subclassing \
your own QTabBar and then implement mouseMoveEvent all by yourself, but this would \
also require some very difficult management of the paintEvent too.<br> </div>
<div>Also, remember that I didn't take into account margins added by styles, nor the \
possibility of cornerWidget(s).</div> <div><br>
</div>
<div>Maurizio</div>
<div><br>
</div>
</div>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">Il giorno gio 11 apr 2019 alle ore 21:23 Matic \
Kukovec &lt;<a href="mailto:kukovecmatic@hotmail.com">kukovecmatic@hotmail.com</a>&gt; \
ha scritto:<br> </div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px \
solid rgb(204,204,204); padding-left:1ex"> <div dir="ltr">
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; \
color:rgb(0,0,0)"> Hi,</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; \
color:rgb(0,0,0)"> <br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; \
color:rgb(0,0,0)"> Is there a way to change the behavior and animation of a \
QTabWidgets tab bar drag functionality?</div> <div \
style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)"> \
<img size="43989" style="max-width:100%" data-outlook-trace="F:1|T:1" \
src="cid:16a0dfa0c4264cee6f1"></div> <div \
style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)"> \
In the above image you can see that the dragged tab disappears outside the bounds of \
the tab bar.<br> </div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; \
color:rgb(0,0,0)"> I would like to remove the movement of tabs outside the tab bar \
space.</div> <div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; \
color:rgb(0,0,0)"> <br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; \
color:rgb(0,0,0)"> Can anyone suggest of where to begin in changing this \
behavior?</div> <div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; \
color:rgb(0,0,0)"> <br>
</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; \
color:rgb(0,0,0)"> Thanks,</div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; \
color:rgb(0,0,0)"> Matic<br>
</div>
</div>
_______________________________________________<br>
PyQt mailing list&nbsp; &nbsp; <a href="mailto:PyQt@riverbankcomputing.com" \
target="_blank"> PyQt@riverbankcomputing.com</a><br>
<a href="https://www.riverbankcomputing.com/mailman/listinfo/pyqt" rel="noreferrer" \
target="_blank">https://www.riverbankcomputing.com/mailman/listinfo/pyqt</a><br> \
</blockquote> </div>
<br clear="all">
<div><br>
</div>
-- <br>
<div dir="ltr" class="x_gmail_signature">È difficile avere una convinzione precisa \
quando si parla delle ragioni del cuore. - &quot;Sostiene Pereira&quot;, Antonio \
Tabucchi<br> <a href="http://www.jidesk.net" \
target="_blank">http://www.jidesk.net</a></div> </div>
</body>
</html>


["tab_movement.gif" (image/gif)]
[Attachment #7 (unknown)]

_______________________________________________
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