如何在 QGridLayout 中删除后添加多行小部件
How to add rows of widgets after deletion in a QGridLayout
我正在将小部件行添加到 QGridLayout
,就像这样(带有按钮):
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
并像这样删除小部件行:
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
当我添加多行小部件(例如五行小部件)时,第一次一切正常。如果我删除行(例如两行小部件),一切也都很好。但是一旦我决定再次添加一行(删除后),它就无法正常工作:我最终得到了六行,而我应该有三行。
一定是我的代码删除了不能正常工作的行(但这些行在视觉上被删除了)。我做错了什么?
A QGridLayout
在删除其小部件时不会删除任何行 - 但空行不会占用任何 space,因此您通常不会注意到它们。如果您添加超出当前行数的小部件,布局将简单地增长到所需的大小。因此,如果当前行数为 5
,并且您在行 10
处添加了一个小部件,行数将立即更改为 10
,并且将创建五个空的中间行。
网格布局始终以行数 1 开头。但是在您的代码中,您在添加小部件时使用 r + 1
:
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)
这将跳过第一行,并开始向行索引 1
添加小部件。因此,添加五行小部件后,行数将为 六,而不是五行。每次您删除并重新添加小部件时,行数都会增加一个。
您的代码应该如下所示:
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)+'. ')
(注意,我在这里也修复了最后一行,之前没有意义)。
编辑:
根据评论,这里是需要进行的更改,以便每次单击第一个按钮时添加一行,并在单击第二个按钮时清除所有行。
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]
我正在将小部件行添加到 QGridLayout
,就像这样(带有按钮):
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
并像这样删除小部件行:
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
当我添加多行小部件(例如五行小部件)时,第一次一切正常。如果我删除行(例如两行小部件),一切也都很好。但是一旦我决定再次添加一行(删除后),它就无法正常工作:我最终得到了六行,而我应该有三行。
一定是我的代码删除了不能正常工作的行(但这些行在视觉上被删除了)。我做错了什么?
A QGridLayout
在删除其小部件时不会删除任何行 - 但空行不会占用任何 space,因此您通常不会注意到它们。如果您添加超出当前行数的小部件,布局将简单地增长到所需的大小。因此,如果当前行数为 5
,并且您在行 10
处添加了一个小部件,行数将立即更改为 10
,并且将创建五个空的中间行。
网格布局始终以行数 1 开头。但是在您的代码中,您在添加小部件时使用 r + 1
:
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)
这将跳过第一行,并开始向行索引 1
添加小部件。因此,添加五行小部件后,行数将为 六,而不是五行。每次您删除并重新添加小部件时,行数都会增加一个。
您的代码应该如下所示:
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)+'. ')
(注意,我在这里也修复了最后一行,之前没有意义)。
编辑:
根据评论,这里是需要进行的更改,以便每次单击第一个按钮时添加一行,并在单击第二个按钮时清除所有行。
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]