0

我正在尝试构建我从这里遇到的这个例子: Right click contextMenu on QPushButton

当我动态创建按钮时,如何让它工作?我想不出一种动态创建方法的方法on_context_menu

这是我到目前为止的代码。

import sys
from PyQt4 import QtGui,QtCore
import sip

class LayoutTest(QtGui.QWidget):
    def __init__(self):
        super(LayoutTest, self).__init__()
        self.setGeometry(300, 300, 400, 200)
        VmasterLayout = QtGui.QVBoxLayout(self)
        self.Hbox = QtGui.QHBoxLayout()

        for i in range(1,4):
            self.butVal = 'buttonMenu_%s' % i
            self.button = QtGui.QPushButton(self.butVal)
            self.button.clicked.connect(self.allCheckButton)
            self.button.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
            self.connect(self.button, QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'), self.on_context_menu)

            # create context menu
            self.popMenu = QtGui.QMenu(self)
            action = QtGui.QActionGroup(self, exclusive=True)
            listVer = ['image_v001','image_v003','image_v012','image_v120','image_v140', 'image_v013']
            for i, vDir in enumerate(sorted(listVer)):
                x = action.addAction(QtGui.QAction( vDir, self, checkable = True))
                x.triggered.connect(self.foo(x.text())) 
                self.popMenu.addAction(x)
                self.popMenu.addSeparator()

            self.Hbox.addWidget(self.button)

        VmasterLayout.addLayout(self.Hbox)

    def on_context_menu(self, point):
        # show context menu
        self.popMenu.exec_(self.button.mapToGlobal(point)) 

    def foo(self, name):
        def poo():
            print 'Image version is: %s' % name
        return poo

    def allCheckButton(self):
        point = QtGui.QCursor.pos()
        print point

def run():
    app = QtGui.QApplication(sys.argv)
    ex = LayoutTest()
    ex.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    run()
4

1 回答 1

1

我重写了这段代码:python pyqt4 contextMenu on pushButton

首先,如果你想动态创建它们,你需要能够识别不同的按钮,所以我创建了自己的QPushButton类 - MyPushButton.

之后我就搬进on_context_menu了那个班。

第三个重要的事情是我已经将MainFormclass 和MyPushButtonclass 与buttonXclickedSignalsignal 连接起来,它提供了MainForm点击哪个按钮的类信息,这样你就可以处理按钮点击的信号,MainForm并为不同的按钮做任何你想做的事情。

这是代码(运行它并尝试单击按钮并右键单击按钮):

import sys
from PyQt4 import QtGui, QtCore

class MyPushButton(QtGui.QPushButton):
    def __init__(self, popMenu,elementID, mainForm):
        super(MyPushButton, self).__init__()
        self.__elementID = elementID
        self.__mainForm = mainForm
        self.__popMenu = popMenu

        self.connect(self, QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'), self.on_context_menu)   
        self.connect(self, QtCore.SIGNAL('clicked()'),  self,        QtCore.SLOT("triggerOutput()"))    

    def on_context_menu(self, point):
        # show context menu
        self.__popMenu.exec_(self.mapToGlobal(point)) 

    @QtCore.pyqtSlot()
    def triggerOutput(self):
        self.__mainForm.emit(QtCore.SIGNAL("buttonXclickedSignal(PyQt_PyObject)"), self.__elementID) # send signal to MainForm class


class MainForm(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MainForm, self).__init__(parent)
        self.setGeometry(300, 300, 400, 200)
        VmasterLayout = QtGui.QVBoxLayout(self)
        self.Hbox = QtGui.QHBoxLayout()

        # Custom signal
        self.connect(self, QtCore.SIGNAL("buttonXclickedSignal(PyQt_PyObject)"),         self.buttonXclicked)

        for i in range(1,4):
            # create context menu as you like
            popMenu = QtGui.QMenu(self)
            popMenu.addAction(QtGui.QAction('button %s - test0'%(i), self))
            popMenu.addAction(QtGui.QAction('button %s - test1'%(i), self))
            popMenu.addSeparator()
            popMenu.addAction(QtGui.QAction('button %s - test2'%(i), self))

            # create button
            self.button = MyPushButton(popMenu, i, self)   
            self.button.setText("test button %s" %(i))    
            self.button.resize(100, 30)

            # set button context menu policy
            self.button.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)        

            self.Hbox.addWidget(self.button)

        VmasterLayout.addLayout(self.Hbox)

    def buttonXclicked(self, buttonID):
        if buttonID == 1: 
            #do something , call some method ..
            print "button with ID ", buttonID, " is clicked"
        if buttonID == 2: 
            #do something , call some method ..
            print "button with ID ", buttonID, " is clicked"
        if buttonID == 3: 
            #do something , call some method ..
            print "button with ID ", buttonID, " is clicked"

def main():
    app = QtGui.QApplication(sys.argv)
    form = MainForm()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()
于 2013-08-26T15:19:53.467 回答