【问题标题】:PySide: QPushButton stays highlighted after pressing itPySide:QPushButton 在按下后保持突出显示
【发布时间】:2023-03-15 15:35:01
【问题描述】:

在我的工具中,当用户按下按钮时,会创建一个弹出窗口。我的问题是用户按下以调出窗口的按钮在弹出窗口创建时保持突出显示(好像我将鼠标悬停在它上面),即使在弹出窗口被删除后仍然保持这种状态。实际上,当弹出窗口处于活动状态时,我喜欢这个突出显示(它在视觉上将窗口连接到弹出窗口,这很好),但我希望它在窗口被删除时消失。

下面是一个说明发生了什么的例子:

如果我点击创建资产,然后点击次要保存,创建资产按钮保持突出显示

代码:

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()

【问题讨论】:

  • 您的要求并不像看起来那么简单。您可以通过执行button.setFocusPolicy(QtCore.Qt.NoFocus) 完全停用按钮的突出显示。但是,为了能够以编程方式控制按钮的突出显示,我认为您必须继承 QPushButton 并自己绘制按钮。我不知道更简单的方法。我将尝试整理一个示例来向您展示如何做到这一点。
  • 在我的完整代码中,我有 QPushButtons 的子类,但我不知道如何使用上下文焦点策略,所以感谢您的帮助!同时,我尝试将 QPushButton 子类的焦点策略设置为无焦点,但似乎没有效果。我已向我的代码添加了更新以显示此内容
  • 你不能关注self.button1.released上的另一个元素吗?
  • 将clicked 改为released 效果和之前一样。可能值得注意的是,在我关闭弹出窗口并将鼠标移到按钮上后,按钮的持续高亮消失并且其行为恢复正常。
  • 您的 QPushButton 最终保持突出显示的问题解决了吗?

标签: focus pyside highlight qpushbutton


【解决方案1】:

在 Windows 7 和 Ubuntu (QtCore.Qt.FocusPolicy.StrongFocus) 上将焦点策略设置为默认值时,我无法重现您的问题。但是,在我将按钮的焦点策略设置为QtCore.Qt.FocusPolicy.NoFocus 之后,它在两个系统上都存在。

为了解决这个问题,我建议,目前,在注册关闭事件时,从Popup_WindoweventFilter方法强制重绘Tool_Window实例,如下所示:

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)

当按钮的焦点策略设置为QtCore.Qt.FocusPolicy.NoFocus 时,它已经为我解决了 Windows7 和 Ubuntu 上的问题。我可能会进一步调查以更好地了解发生了什么,我会及时通知您。

旁注:我没有使用OpenMayaUI 测试您的代码,所以也许这就是我默认没有遇到问题的原因,但只有在我明确设置按钮的焦点策略之后到NoFocus。也许OpenMayaUI 强制您的按钮默认使用NoFocus 策略。这也可能是因为我们的操作系统和主题之间的差异。

【讨论】:

  • 您好 Jean-Sebastien,感谢您的回复,抱歉耽搁了。我循环工作,刚刚开始重新开始我的代码开发。我只是想让您知道我尝试了您的解决方案,但它并没有改变按钮问题。
【解决方案2】:

由于某种原因,当您的 Popup_Window 类使用 self.setWindowFlags(QtCore.Qt.Popup) 时,亮点似乎仍然存在。

相反,您可以删除该行并使Popup_Window 类继承自QDialog。现在,当新窗口出现时,突出显示不会保留。尽管您最初的行为是您只能在弹出窗口显示时与它进行交互,但要实现相同的效果,只需调用 self.popup.exec_() 而不是 self.popup.show() 使其成为模态。

现在我们让它像没有“粘”在突出显示状态的按钮一样工作。

【讨论】:

    【解决方案3】:

    我在 Maya 2018 上也遇到了这个问题。我想这可能是 Maya 的事情?我最终只是重写了鼠标点击事件,作为鼠标点击+释放事件——这样它就永远不会真正进入抑郁状态:

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

    我也尝试过的事情:

    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)
    

    无论我尝试什么,我得到的结果如下所示,黑色按钮在单击 + 拖动后被永久按下,但如果我单击它们就可以了:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-31
      • 2017-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 2016-01-09
      • 2021-04-01
      相关资源
      最近更新 更多