3

In my tool, when the user pushes a button a popup window is created. My issue is that the button that the user presses to bring up the window stays highlighted (as if I have my mouse over it) on popup creation and remains that way even after the popup is deleted. I actually like this highlight while the popup is active (it visually connects the window to the popup which is nice), but I'd like it to go away when the window is deleted.

Below is an example to clarify what's happening:

enter image description here

If I click on create asset, then click on minor save the create asset button stays highlighted

CODE:

from PySide import QtCore, QtGui
import maya.OpenMayaUI as mui
from shiboken import wrapInstance 

def get_parent():
    ptr = mui.MQtUtil.mainWindow()
    return wrapInstance( long( ptr ), QtGui.QWidget )

############################################
class Tool_Window(QtGui.QDialog):
    def __init__(self, parent = get_parent() ):
        super(Tool_Window, self).__init__(parent)

        # Commands
        self.create_gui()
        self.create_layout()
        self.create_connections()

    #-------------------------------------------
    def create_gui(self):
        self.button1 = Push_Buttons()
        self.button1.setMaximumWidth(50)
        self.button2 = Push_Buttons()
        self.button2.setMaximumWidth(50)

    #-------------------------------------------
    def create_layout(self):
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        blank_layout = QtGui.QVBoxLayout()
        main_layout = QtGui.QHBoxLayout( self )
        main_layout.addLayout(blank_layout)
        main_layout.addLayout(layout)
        self.setLayout(layout)

    #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
    def create_connections(self):
        # Left click
        self.button1.clicked.connect( self.on_left_click )
        self.button2.clicked.connect( self.on_left_click )

    #-----#-----#-----#-----#-----#-----#-----#-----#-----#    
    def on_left_click(self):

        button = self.sender()

        self.popup = Popup_Window( self, button )                   
        self.popup.show()

############################################
class Push_Buttons( QtGui.QPushButton ):
    def __init__( self ):
        super( Push_Buttons, self ).__init__()

        self.setFocusPolicy(QtCore.Qt.NoFocus)

############################################
class Popup_Window( QtGui.QWidget ):
    def __init__( self, parent, button ):
        super( Popup_Window, self ).__init__(parent)

        self.setWindowFlags(QtCore.Qt.Popup)

        self.button_pos = button       
        self.parent = parent  

        self.setAttribute( QtCore.Qt.WA_DeleteOnClose )
        self.resize(230, 100)

        self.installEventFilter(self)

        self.create_gui()
        self.create_layout()
        self.create_connections()
        self.move_UI()   
        self.line_edit.setFocus()     

    #-------------------------------------------
    def create_gui( self ):
        ''' Visible GUI stuff '''
        self.my_label = QtGui.QLabel("default text")
        self.line_edit = QtGui.QLineEdit()
        self.line_edit.setMaxLength( 30 )
        self.push_btn = QtGui.QPushButton( "push" )
        self.push_btn.setMaximumWidth( 30 )

    #-------------------------------------------
    def create_layout( self ):

        self.button_layout = QtGui.QVBoxLayout()

        self.button_layout.addWidget( self.my_label, 0, 0 )
        self.button_layout.addWidget( self.line_edit, 1, 0 )
        self.button_layout.addWidget( self.push_btn, 2, 0 )

        self.setLayout(self.button_layout)

    #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
    def create_connections( self ):

        self.line_edit.textChanged.connect( self.on_text_changed )

    #-----#-----#-----#-----#-----#-----#-----#-----#-----#
    def on_text_changed( self, text ): 

        #---- set the text in label ----
        typed_name = self.line_edit.text()
        if " " in typed_name:
            typed_name.replace(" ", "")
        self.my_label.setText(typed_name) 

    #-------------------------------------------  
    def  eventFilter(self, source, event):

        if event.type() == QtCore.QEvent.WindowDeactivate:
            self.close()
        return QtGui.QWidget.eventFilter(self, source, event)

    #-------------------------------------------
    def move_UI( self ):
        self.line_edit.setFocus()
        y_btn = self.button_pos.mapToGlobal(QtCore.QPoint(0,0)).y()  
        x_win = self.parent.mapToGlobal(QtCore.QPoint(0,0)).x()

        w_pop = self.frameGeometry().width()

        x = x_win - w_pop - 12
        y = y_btn

        self.move(QtCore.QPoint(x,y))

############################################
if __name__ == '__main__':
    # Things to fix PySide Maya bug
    try:
        test_ui.close()
        test_ui.deleteLater()
    except:
        pass

    test_ui = Tool_Window()
    test_ui.show()

    try:
        test_ui.show()
    except:
        test_ui.close()
        test_ui.deleteLater()
Mike Bourbeau
  • 481
  • 11
  • 29
  • 2
    What you are asking is not as simple to achieve as it looks like. You can completely deactivate the highlight of a button by doing `button.setFocusPolicy(QtCore.Qt.NoFocus)`. However, to be able to programattically control the highlight of the button, I think you would have to subclass `QPushButton` and paint the button yourself. I am unaware of a simpler way. I will try to put together an example to show you how this can be done. – Jean-Sébastien Jul 31 '15 at 13:30
  • In my full code I have the QPushButtons subclassed, but I have no clue how to go about utilizing contextual focus policies, so thank you for helping out! In the mean time I've tried setting my QPushButton subclass's focus policy to no focus and it doesn't seem to be having an effect. I've added an update to my code to show this – Mike Bourbeau Jul 31 '15 at 13:44
  • could you not focus on another element on `self.button1.released`? – P.R. Jul 31 '15 at 17:34
  • 1
    Changing clicked to released has the same effect as before. Something that might be worth noting is that after I close the popup and pass my mouse over the button, the button's persistent highlight is goes away and its behavior reverts back to normal. – Mike Bourbeau Jul 31 '15 at 18:07
  • Ok, I think I misunderstood the issue you had in your OP because, in the theme I use in Ubuntu, the highlights of UI elements is almost not visible. I understood what you meant when I tested your code in Windows7. I've proposed a fix in an answer below. I don't know if it will solve your issue for your setup though. – Jean-Sébastien Aug 01 '15 at 03:13
  • 1
    Have you been able to solve your problem with your QPushButton staying highlighted finally? – Jean-Sébastien Aug 06 '15 at 13:13
  • I haven't had a chance to test out the solutions, but I'll probably get around to it this week! Thanks for all the effort:D – Mike Bourbeau Aug 06 '15 at 14:13

3 Answers3

2

I was not able to reproduce your issue when the focus policy was set to the default value on both Windows 7 and Ubuntu (QtCore.Qt.FocusPolicy.StrongFocus). However, it was on both system after I've set the focus policy of the buttons to QtCore.Qt.FocusPolicy.NoFocus.

To solve this issue, I suggest, for the moment, to force a repaint of the Tool_Window instance, from the eventFilter method of the Popup_Window, when a close event is registered, as shown below:

def  eventFilter(self, source, event):

    if event.type() == QtCore.QEvent.WindowDeactivate:
        self.close()
    elif event.type() == QtCore.QEvent.Close:
        self.parent.repaint()
    return QtGui.QWidget.eventFilter(self, source, event)

It has solved the problem on both Windows7 and Ubuntu for me when the focus policity of the button was set to QtCore.Qt.FocusPolicy.NoFocus. I may investigate further to better understand what is going on, I'll keep you posted.

side note : I am not testing your code with OpenMayaUI, so maybe that is why I do not get the issue by default, but only after I explicitly set the focus policy of the buttons to NoFocus. Maybe OpenMayaUI force your buttons to have a NoFocus policy by default. It can be also because of differences between our OS and theme.

Jean-Sébastien
  • 2,649
  • 1
  • 16
  • 21
  • 1
    Hi Jean-Sebastien, thanks for your reply and sorry for the delay. I work in cycles and just started to get back into my code development again. I just wanted to let you know that I tried out your solution, but it doesn't change the button issue. – Mike Bourbeau Oct 21 '15 at 20:22
1

For some reason the highlight seems to remain when your Popup_Window class uses self.setWindowFlags(QtCore.Qt.Popup).

Instead you can remove that line and make Popup_Window class inherit from QDialog. Now the highlight won't remain when the new window appears. Though your original behavior was that you could only interact with the popup window when it's shown, so to achieve the same thing just call self.popup.exec_() instead of self.popup.show() to make it modal.

Now we have it working like it was without the button 'sticking' to a highlighted state.

Green Cell
  • 4,677
  • 2
  • 18
  • 49
0

I ran into this as well, on Maya 2018. I'm thinking it may be a Maya thing? I eventually ended up just rewriting the mouse click event, as the mouse click + release event - so that it never really enters the depressed state:

    def mousePressEvent(self, event):
        super(DragButton, self).mouseReleaseEvent(event)

Things I had also tried:

QPushButton().setDown(False)
QPushButton().setChecked(False)
QPushButton().setPressed(False)

QPushButton().setFocusPolicy(QtCore.Qt.NoFocus)
QPushButton().setFocusPolicy(QtCore.Qt.StrongFocus)

QPushButton().viewport().update()

event.accept()

QtCore.QTimer.singleShot(
    100, lambda: self.setFocusPolicy(QtCore.Qt.NoFocus)
)

QtCore.QTimer.singleShot(100, lambda: self.setDown(False))
super(DragButton, self).mousePressEvent(event)

No matter whatever I try, what I get is shown below, where the black buttons have been permanently depressed after a click + drag, although they're fine if I single click them:

QListWidget_drag_depressedBtns

Jesse
  • 143
  • 1
  • 1
  • 10