2017-09-25 3 views
0

Im essayant de faire mon auto menu généré à l'aide de cette boucle:En utilisant DataBase et Dict à Ajouter PyQt5 Menus et Triggers [Python 3]

q3 = connect_menu.addMenu('Q3') 
q3menus = {} 
x = 0 
for element in q3s: 
    key = 'Q'+str(x) 
    q3menus[key] = QAction(element[7], self) 
    q3.addAction(q3menus[key]) 
    q3menus[key].triggered.connect(lambda: self.main_form.consavesv(q3menus[key].text())) 
    x += 1 

q3s équivaut à une fonction FetchAll qui obtient les données de la dernière SQL requête

q3s = [(1, 'Q3', '127.0.0.1', 28960, "Server Test Name", '5154', '127.0.0.1:28960', "127.0.0.1:28960 | Server Test Name"), (2, 'Q3', '192.168.1.66', 28960, 'Server Test 2', '5154', '192.168.1.66:28960', '192.168.1.66:28960 | Server Test 2')]

J'ai essayé d'utiliser un dictianory, Cette dictianory ajoute des étiquettes de menu et comme il se doit, mais quand je clique sur eux, je ils ont tous la même triggered.connect() que le dernier fait ..

Qu'est-ce que je fais mal? Je ne veux pas créer des Signaux moi-même ici, Parce que les résultats de la base de données ne sont pas statiques ..

Désolé pour un mauvais anglais.

+0

Je suppose que je devrais ajouter 'triggered.connect()' en dehors de la boucle, mais je ne sais pas alors comment dois-je mettre 'triggered.connect()' pour tous les articles que vous dictianory – DarkSuniuM

+0

pourrait montrer ce que vous obtenez lorsque vous exécutez 'impression (q3s)' – eyllanesc

+0

@ @ yllanesc la question mise à jour et le contenu q3s ajouté – DarkSuniuM

Répondre

1

il problème est la façon dont vous passez les paramètres à une fonction lambda, la syntaxe correcte est:

f = lambda p_1, p_2, ..., p_n: some operation with p_1, p_2, ..., p_n 

Dans votre cas, vous devez également tenir compte du fait que le signal déclenché de QAction retourne une valeur appelée vérifiée , vous devez donc précéder ce paramètre comme indiqué ci-dessous:

q3menus[key].triggered.connect(lambda checked, key=key: self.main_form.consavesv(q3menus[key].text())) 

en plus de cette approche, vous pouvez également utiliser la méthode sender() qui retourne l'objet qui émet le signal et obtenir le texte directement comme indiqué dans e e exemple suivant:

class Example(QMainWindow): 
    def __init__(self, parent = None): 
     QMainWindow.__init__(self, parent) 

     q3s = [(1, 'Q3', '127.0.0.1', 28960, "Server Test Name", '5154', '127.0.0.1:28960', "127.0.0.1:28960 | Server Test Name"), 
     (2, 'Q3', '192.168.1.66', 28960, 'Server Test 2', '5154', '192.168.1.66:28960', '192.168.1.66:28960 | Server Test 2')] 
     menubar = self.menuBar() 

     q3 = menubar.addMenu("Q") 
     q3menus = {} 
     for x, element in enumerate(q3s): 
      key = 'Q'+str(x) 
      q3menus[key] = QAction(element[7], self) 
      q3.addAction(q3menus[key]) 
      q3menus[key].triggered.connect(lambda checked, key=key : self.someFunction(q3menus[key].text())) 
      q3menus[key].triggered.connect(self.anotherFuntions) 

    def someFunction(self, text): 
     print("someFunction {}".format(text)) 

    def anotherFuntions(self): 
     print("anotherFuntions {}".format(self.sender().text())) 

if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    w = Example() 
    w.show()  
    sys.exit(app.exec_()) 
+0

Cela a fonctionné !! Peut-on expliquer 'q3menus [clé] .triggered.connect (lambda vérifié, clé = clé: self.someFunction (q3menus [clé] .text()))' pour moi? – DarkSuniuM

+1

le signal déclenché renvoie un paramètre qui indique si elle a été vérifiée depuis un QAction peut être vérifiable, mais par défaut il ne l'est pas, mais nous devons en tenir compte, puis nous devons passer les autres paramètres en les affectant, pour clarifier le ci-dessus équivaut à: 'q3menus [clé] .triggered.connect (lambda vérifié, param = clé: self.someFunction (q3menus [param] .text()))' – eyllanesc