【问题标题】:Change the parent of QActions with... signals and slots?用...信号和插槽更改 QActions 的父级?
【发布时间】:2015-05-20 22:55:41
【问题描述】:

我有一堆 QAction,其中一些(目前)在两个子菜单和主菜单中。

正如您在下面的代码中所见,操作是在没有父级的情况下创建的,因为这些操作与具有相同菜单的按钮共享。 那个插槽on_connect 应该创建一个类 Wire 的实例。

唯一阻止我创建wire类实例的是jack_connector,它应该是按下并显示菜单的按钮。其他参数都还可以,暂时只关心这个。 我发现我可以通过self.sender().parent().objectName() 获得我需要的值 但此时 QActions 有父集 None ,所以我需要在运行时将显示菜单的按钮设置为父级。

我已经知道可以使用 .setParent() 方法完成,但我不知道如何在按钮按下事件期间对所有操作执行此操作。

这是最相关的代码:

scene = MyScene()
menu = QMenu()
widget_container = QWidget()

#dictonaries for dragbuttons (used later for connecting them)
jacks_dic = {}
inputs_dic = collections.OrderedDict()
wire_dic = {}

...
@pyqtSlot(str)
def on_connect(self,  input):
    print 'connected'
    jack_connector = self.sender().parent().objectName() #sender's parent of QAction should be the button
    wire_dic['wire_1'] = Wire(  jack_connector , widget_container.findChild( DragButton,  'btn_' + input ) , None, scene)

#Load Menu options for Jacks dragbuttons

#create sub-menus
submenus_dic = collections.OrderedDict()
submenus_dic['AIF1TX1_submenu'] = QMenu("AIF1TX1 (L) Record to Device")
submenus_dic['AIF1TX2_submenu'] = QMenu("AIF1TX2 (R) Record to Device")


actions_dic = collections.OrderedDict()
for input   in inputs_dic:
    #Create an Action
    actions_dic[ input  ] = QtGui.QAction( input, None)
    #TODO: Find a way to set parent a QAction after click
    #TODO: Research how to connect every action to a slot()
    actions_dic[ input ].triggered[()].connect( lambda input=input:  on_connect(actions_dic[ input  ], input)  )


    #Condition to add to a submenu
    if input[:-2] == 'AIF1TX1' :
        submenus_dic['AIF1TX1_submenu'].addAction( actions_dic[ input ] )

    if input[:-2] == 'AIF1TX2' :
        submenus_dic['AIF1TX2_submenu'].addAction( actions_dic[ input ] )

#Add SubMenus to Main Menu
for submenu in submenus_dic:
    menu.addMenu(submenus_dic[ submenu ] )

【问题讨论】:

    标签: python qt pyqt pyqt4 pyside


    【解决方案1】:

    问题在于触发了一个操作,而您正试图找出打开了哪个菜单并激活了该操作。您可以采取多种方法。

    您可能希望使用 QMenu 的 activeAction() 方法来探索 QAction 的 menu()、parentWidget() 和 associatedWidgets() 方法。您还可以检查可见的菜单。

    当您向菜单添加操作时,QMenus 创建一个代表该操作的小部件。因此,您可以手动创建这些小部件并创建一组单独的触发器,以将另一个参数传递给您的函数。

    听起来你确实需要单独的课程。

    class MyMenu(QMenu):
    
        newWire = QtCore.Signal(str)
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
            self.wire_dic = collections.OrderedDictionary()
    
            self.action1 = QAction("text")
            self.action1.triggered.connect(self.action1method)
            self.addAction(self.action1)
        # end Constructor
    
        def action1method(self):
            # Maybe use self.windowTitle()
            self.wire_dic['wire_1'] = Wire(self.title(), widget_container.findChild( DragButton,  'btn_' + input ) , None, scene)
            self.newWire.emit("wire_1")
        # end action1method
    # end class MyMenu
    
    m1 = MyMenu("Menu1")
    m2 = MyMenu("Menu2")
    
    menubar.addMenu(m1)
    menubar.addMenu(m2)
    

    这样每个对象都与它自己的操作相关联,而无需您手动创建和管理一堆重复的操作。这应该更容易管理,并且所有操作都将以相同的方式运行。

    【讨论】:

    • 插槽需要在一个类中?就算是主窗口类?
    • 我不确定这种方法是否对我有帮助。我需要一个插槽不仅可以接收 Qmenu 的操作,还需要接收拖放事件
    • 您仍然可以使用 m1.action1method() 调用常规插槽方法。在 PySide 中,您甚至不必担心某个东西是否是一个插槽。任何方法都可以是带有描述符的槽。
    猜你喜欢
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2021-07-11
    • 2019-10-29
    • 1970-01-01
    • 2013-11-13
    • 1970-01-01
    相关资源
    最近更新 更多