2016-12-11 1 views
1

Ich habe einen Rahmen, zu dem Layout dynamisch Lineedits hinzufügen, klicken Sie auf einen ToolButton. Ich brauche alle diese Lineedits, um mit meinem Autocompleter auf Signal textChanged zu arbeiten. Ich kann nicht ganz verstehen, wie es geht. Ich sah während der Untersuchung, dass lambda kann helfen, aber ich konnte es nicht tun. Ich schätze, es liegt daran, dass ich schlecht verstehe, wie das alles funktioniert. Ich habe QtDesigner und this Tutorial verwendet, um GUI zu machen. Mein Code ist in zwei Dateien - in der ersten gibt es nur Widgets:Binden Sie dynamisch gemachte Widgets zu einem Signal in PyQt5

from PyQt5 import QtCore, QtGui, QtWidgets 

class Ui_Form(object): 
    def setupUi(self, Form): 
     Form.setObjectName("Form") 
     Form.resize(799, 424) 
     ... 
     self.toolbutton_add_score = QtWidgets.QToolButton(self.groupbox_scores) 
     self.toolbutton_add_score.setObjectName("toolbutton_add_score") 
     self.layout_groupbox_scores.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.toolbutton_add_score) 
     self.frame_movies_scores = QtWidgets.QFrame(self.groupbox_scores) 
     self.frame_movies_scores.setObjectName("frame_movies_scores") 
     self.layout_frame_movies_scores = QtWidgets.QGridLayout(self.frame_movies_scores) 
     self.layout_frame_movies_scores.setObjectName("layout_frame_movies_scores") 
     self.lineedit_input_movie = QtWidgets.QLineEdit(self.frame_movies_scores) 
     self.lineedit_input_movie.setObjectName("lineedit_input_movie") 
     self.layout_frame_movies_scores.addWidget(self.lineedit_input_movie, 0, 0) 

     self.retranslateUi(Form) 
     QtCore.QMetaObject.connectSlotsByName(Form) 

    def retranslateUi(self, Form): 
     _translate = QtCore.QCoreApplication.translate 
     Form.setWindowTitle(_translate("Form", "Рекомендательная система")) 
     ... 

Im zweiten gibt es meine Funktionen:

class MyWin(QtWidgets.QMainWindow): 
    def __init__(self, parent = None): 
     QtWidgets.QWidget.__init__(self, parent) 
     self.ui = Ui_Form() 
     self.ui.setupUi(self) 
     self.ui.lineedit_input_movie.textChanged.connect(self.autocomplete) 
     self.ui.toolbutton_add_score.clicked.connect(self.add_score_field) 

    def autocomplete(self): 
     cursor.execute("SELECT title FROM movies WHERE title LIKE '%%' || %s || '%%';", (self.ui.lineedit_input_movie.text(),)) 
     it = cursor.fetchall() 
     strings = [item[0] for item in it] 
     completer = QtWidgets.QCompleter(strings, self) 
     self.ui.lineedit_input_movie.setCompleter(completer) 
     self.ui.lineedit_input_movie.show() 

    def add_score_field(self): 
     self.lineedit_input_movie = QtWidgets.QLineEdit(self.ui.frame_movies_scores) 
     self.lineedit_input_movie.setObjectName("lineedit_input_movie") 
     self.ui.layout_frame_movies_scores.addWidget(self.lineedit_input_movie, r, 0) 

Der Code funktioniert hier nur für die fiers LineEdit in das Layout. Was muss ich tun, damit es für alle Zeilen im Layout funktioniert?

Antwort

1

Sie müssen Ihre zusätzlichen Felder in eine Liste aufnehmen, um ihre Referenzen zu behalten. Im Moment überschreiben Sie Ihr bestehendes Feld, was nicht gut ist. Außerdem müssen Sie Ihr textChanged Signal für jedes neue Feld verbinden.

class MyWin(QtWidgets.QMainWindow): 

    def __init__(self, parent = None): 

     self.score_fields = [] 
     # ... 


    def add_score_field(self): 

     # Create a new Line Edi 
     new_lineedit = QtWidgets.QLineEdit(self.ui.frame_movies_scores) 
     new_lineedit.setObjectName("lineedit_input_movie") 

     # append it to your score_fields list 
     self.score_fields.append(new_lineedit) 

     # add it to your layout 
     self.ui.layout_frame_movies_scores.addWidget(new_lineedit, r, 0) 

     # connect your signal 
     new_lineedit.textChanged.connect(self.autocomplete) 
+0

Eigentlich habe ich schon so etwas probiert und es hat nicht funktioniert. Wie auch immer, ich habe deine Lösung versucht und es funktioniert auch nicht. Ich habe das Gefühl, dass das Programm keine Verbindungen herstellt, wenn man versucht, es aus Funktionen heraus zu tun. Außerdem warnt PyCharm mich "Ungelöste Attributverweis 'verbinden' für die Klasse 'pyqtBoundSignal" in dieser Zeile: 'new_lineedit.textChanged.connect (self.autocomplete)' – Yulia

+0

Ich denke, ich war nicht richtig in meinem Kommentar. Tatsächlich funktionieren Verbindungen von innerhalb von Funktionen. Aber was in meinem Programm nicht stimmt, ist, wie Autocomplete funktioniert: Ich muss dieser Funktion irgendwie das Lineedit geben, das gerade benutzt wird. Ich habe versucht, Google zu verbinden, um connectons mit Argumenten zu machen, aber nicht ganz verstanden. Kannst du mir dabei helfen? – Yulia

+0

Ihre Autocomplete-Funktion verwendet derzeit 'self.ui.lineedit_input_movie', um Ihre Änderungen zu übernehmen. Sie müssen das Absenderobjekt an Ihre Funktion übergeben. Verwenden Sie stattdessen 'self.sender()'. – MrLeeh

Verwandte Themen