سؤال

أحتاج إلى أن أكون قادرا على معرفة العنصر الذي قمت بالنقر عليه في نظام قائمة تم إنشاؤه ديناميكيا. أريد فقط أن أعرف ما قمت بالنقر فوقه، حتى لو كان مجرد تمثيل سلسلة.

def populateShotInfoMenus(self):
    self.menuFilms = QMenu()
    films = self.getList()

    for film in films:
        menuItem_Film = self.menuFilms.addAction(film)
        self.connect(menuItem_Film, SIGNAL('triggered()'), self.onFilmSet)
        self.menuFilms.addAction(menuItem_Film)

def onFilmRightClick(self, value):
    self.menuFilms.exec_(self.group1_inputFilm.mapToGlobal(value))

def onFilmSet(self, value):
    print 'Menu Clicked ', value
هل كانت مفيدة؟

المحلول

بدلا من استخدام onFilmSet مباشرة كمستقبل اتصالك، استخدم وظيفة Lambda حتى تتمكن من اجتياز معلمات إضافية:

receiver = lambda film=film: self.onFilmSet(self, film)
self.connect(menuItem_Film, SIGNAL('triggered()'), receiver)

نصائح أخرى

ألق نظرة على نظام خاصية QT. يمكنك إضافة خاصية ديناميكيا تحتوي على سلسلة أو أي شيء تريده، مما يحدد الإجراء. ثم يمكنك استخدام طريقة المرسل () في الفتحة للحصول على QOOBJECT استدعاء الفتحة. بعد ذلك، استئناف الخاصية التي قمت بتعيينها وتقوم بكل ما تريد وفقا لذلك.

ولكن هذه ليست هي أفضل طريقة للقيام بذلك. لا ينصح باستخدام المرسل () لأنه ينتهك مبدأ الوحوضة الموجهة للكائنات.

أفضل طريقة ستستخدم فئة QSignalMapper. تشير هذه الخرائط الفئة من كائنات مختلفة إلى نفس الفتحة مع حجج مختلفة.

لم أستخدم pyqt لذلك لا أستطيع أن أقدم لك بناء جملة دقيق أو مثالا، لكن لا ينبغي أن يكون من الصعب العثور عليه مع القليل من البحث.

كنت أحاول معرفة مشكلة مماثلة وبعد النظر إلى التعليمات البرمجية أعلاه وهذا هو ما عمل لي. يعتقد أنه سيكون من الجيد أن تظهر كل شيء معا. =)

self.taskMenu = QtGui.QMenu("Task")
self.tasks = self.getTasks() #FETCHES A LIST OF LIST
self.menuTasks = QtGui.QMenu()
for item in self.tasks:
     menuItem_Task = self.taskMenu.addAction(item[1]) 
     receiver = lambda taskType=item[0]: self.setTask(taskType)
     self.connect(menuItem_Task, QtCore.SIGNAL('triggered()'), receiver)
     self.taskMenu.addAction(menuItem_Task)

def setTask(self,taskType):
     print taskType

فقط بعض المعلومات الإضافية، لا أعرف لماذا، ولكن وظيفة Lambda لا تعمل مع بناء جملة PYQT الجديد للاتصالات:

مثال على التعليمات البرمجية لا يعمل:

    self.contextTreeMenuAssignTo = QtGui.QMenu(self)
    actionAssign = contextMenu.addMenu( self.contextTreeMenuAssignTo )
    actionAssign.setText("Assign to : ")
    for user in self.whoCanBeAssignated() :
        actionAssignTo = QtGui.QAction( user[0]  ,self)
        self.contextTreeMenuAssignTo.addAction( actionAssignTo )
        actionAssignTo.triggered.connect(  lambda userID = user[1] :  self.assignAllTo( userID )  )

ولكن إذا قمت بتشغيل السطر الأخير مع بناء جملة اتصال النمط القديم:

self.connect(actionAssignTo, QtCore.SIGNAL('triggered()'),  lambda userID = user[1] :  self.assignAllTo( userID )  )    

كل شيء على ما يرام. مع بناء جملة الاتصال الجديد، يمكنك فقط الحصول على العنصر الأخير من الحلقة :(

وجدت هذه الإجابة هنا للتعامل مع هذه المشكلة في PYQT5، Python3. أنا لا أحب ذلك، أن يكون متغير BVAL دقيقا، لأنني لا أفهم ذلك تماما، لكنه استغرق الأمر وقتا طويلا للعثور عليه، فأعتقد أنني كنت أشاركه هنا. تلتقط BVAL القيمة المنطقية من الناتجة وتسمح بمرور المهام.

self.taskMenu = QtGui.QMenu("Task")
self.tasks = self.getTasks() #FETCHES A LIST OF LIST
self.menuTasks = QtGui.QMenu()

for item in self.tasks:
   menuItem_Task = self.taskMenu.addAction(item[1]) 
   receiver = lambda: bVal, taskType=item: self.setTask(bVal, taskType)
   menuItem_Task.triggered.connect(receiver)
   self.taskMenu.addAction(menuItem_Task)

def setTask(self, ignore_bVal, taskType):
   print taskType
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top