I am adding rows of widgets to a QGridLayout
like this (with a button):
def ajouter_un_mot_vocab(self) :
'''
'''
# Dictionnaire des mots de vocabulaire
self.dico_vocab_mot = {}
# Dictionnaire des définitions des mots de vocabulaire
self.dico_vocab_def = {}
# Liste pour chargement des données
# (écriture des textes par l'utilisateur)
self.liste_mots_vocabulaire = []
print
print 'self.grille_3_stack_3.rowCount() creation', self.grille_3_stack_3.rowCount()
print
#
for r in range(self.grille_3_stack_3.rowCount()) :
# Création des widgets et taille générique
self.dico_vocab_mot[r] = QTextEdit()
self.dico_vocab_def[r] = QTextEdit()
self.dico_vocab_mot[r].setMaximumWidth(180)
self.dico_vocab_mot[r].setMinimumWidth(180)
self.dico_vocab_mot[r].setMaximumHeight(54)
self.dico_vocab_mot[r].setMinimumHeight(54)
self.dico_vocab_def[r].setMaximumHeight(54)
self.dico_vocab_def[r].setMinimumHeight(54)
print 'r', r
# Conditions de redimensionnement
if r > 5 :
self.dico_vocab_mot[r].setMaximumHeight(34)
self.dico_vocab_mot[r].setMinimumHeight(34)
self.dico_vocab_def[r].setMaximumHeight(34)
self.dico_vocab_def[r].setMinimumHeight(34)
# Répartition dans la grille
self.grille_3_stack_3.addWidget(self.dico_vocab_mot[r], r+1, 0)
self.grille_3_stack_3.addWidget(self.dico_vocab_def[r], r+1, 1)
# Ecriture des n°s de lignes dans la partie mots de vocabulaire
self.grille_3_stack_3.addWidget(self.dico_vocab_mot[r].setText(str(r+1)+'. '), r+1, 0)
# Les données sont introduites dans une liste
self.liste_mots_vocabulaire.append([self.dico_vocab_mot[r], self.dico_vocab_def[r]])
# =====================================================
# Signaux
self.dico_vocab_mot[r].textChanged.connect(self.changements_phase_3)
self.dico_vocab_def[r].textChanged.connect(self.changements_phase_3)
# =====================================================
print 'self.dico_vocab_mot', self.dico_vocab_mot
print 'self.dico_vocab_def', self.dico_vocab_def
print self.liste_mots_vocabulaire
And removing the rows of widgets like this:
def supprimer_un_mot_vocab(self) :
'''
'''
index = len(self.liste_mots_vocabulaire)-1
for r in reversed(range(self.grille_3_stack_3.rowCount())) :
for c in reversed(range(self.grille_3_stack_3.columnCount()))
layout = self.grille_3_stack_3.itemAtPosition(r, c)
if layout is not None :
layout.widget().deleteLater()
#layout_1.widget().hide()
self.grille_3_stack_3.removeItem(layout)
self.liste_mots_vocabulaire.pop()
del self.dico_vocab_mot[index]
del self.dico_vocab_def[index]
print
print "rowCount apres suppr", self.grille_3_stack_3.rowCount()
print
print self.dico_vocab_mot
print self.dico_vocab_def
print self.liste_mots_vocabulaire
print
Everything works well the first time, when I add rows of widgets (for example five rows of widgets). Everything works well too if I delete the rows (for example two rows of widgets). But as soon as I decide to add a row again (after deletion), it does not work properly: I end up with six lines, while I should have three.
It must be my code for deleting lines that does not work properly (yet the rows are removed visually). What am I doing wrong?
A QGridLayout
does not delete any rows when its widgets are removed - but the empty rows do not take up any space, so you won't usually notice them. If you add widgets beyond the current row-count, the layout will simply grow to the required size. So if the current row-count is 5
, and you add a widget at row 10
, the row-count will immediately change to 10
, and five empty intervening rows will be created.
A grid-layout always starts with a row-count of one. But in your code, you use r + 1
when adding widgets:
for r in range(self.grille_3_stack_3.rowCount()):
...
self.grille_3_stack_3.addWidget(self.dico_vocab_mot[r], r+1, 0)
self.grille_3_stack_3.addWidget(self.dico_vocab_def[r], r+1, 1)
# Ecriture des n°s de lignes dans la partie mots de vocabulaire
self.grille_3_stack_3.addWidget(self.dico_vocab_mot[r].setText(str(r+1)+'. '), r+1, 0)
This will skip the first row, and start adding widgets a row index 1
. So after adding five rows of widgets, the row-count will be six, rather than five. And every time you delete and re-add the widgets, the row-count will grow by one.
Your code should instead look like this:
for r in range(self.grille_3_stack_3.rowCount()):
...
self.grille_3_stack_3.addWidget(self.dico_vocab_mot[r], r, 0)
self.grille_3_stack_3.addWidget(self.dico_vocab_def[r], r, 1)
self.dico_vocab_mot[r].setText(str(r+1)+'. ')
(Note that I have also fixed the last line here, which previously made no sense).
EDIT:
As per the comments, here are the changes needed so that one row is added for each click of the first button, and all rows are cleared when clicking the second button.
class EssaiQStackedWidget_Seq_Prof(QWidget) :
def __init__(self, parent=None):
...
self.dico_vocab_mot = {}
self.dico_vocab_def = {}
self.liste_mots_vocabulaire = []
self.liste_menu.currentIndexChanged.connect(self.affiche_phases)
def ajouter_un_mot_vocab(self) :
r = len(self.liste_mots_vocabulaire)
self.dico_vocab_mot[r] = QTextEdit()
self.dico_vocab_def[r] = QTextEdit()
self.dico_vocab_mot[r].setMaximumWidth(180)
self.dico_vocab_mot[r].setMinimumWidth(180)
self.dico_vocab_mot[r].setMaximumHeight(54)
self.dico_vocab_mot[r].setMinimumHeight(54)
self.dico_vocab_def[r].setMaximumHeight(54)
self.dico_vocab_def[r].setMinimumHeight(54)
if r > 5 :
self.dico_vocab_mot[r].setMaximumHeight(34)
self.dico_vocab_mot[r].setMinimumHeight(34)
self.dico_vocab_def[r].setMaximumHeight(34)
self.dico_vocab_def[r].setMinimumHeight(34)
self.grille_3_stack_3.addWidget(self.dico_vocab_mot[r], r, 0)
self.grille_3_stack_3.addWidget(self.dico_vocab_def[r], r, 1)
self.dico_vocab_mot[r].setText(str(r+1)+'. ')
self.liste_mots_vocabulaire.append([self.dico_vocab_mot[r], self.dico_vocab_def[r]])
self.dico_vocab_mot[r].textChanged.connect(self.changements_phase_3)
self.dico_vocab_def[r].textChanged.connect(self.changements_phase_3)
def supprimer_un_mot_vocab(self) :
row = len(self.liste_mots_vocabulaire) - 1
if row >= 0:
for column in range(self.grille_3_stack_3.columnCount()):
item = self.grille_3_stack_3.itemAtPosition(row, column)
if item is not None:
item.widget().deleteLater()
del self.liste_mots_vocabulaire[row]
del self.dico_vocab_mot[row]
del self.dico_vocab_def[row]