【问题标题】:How to add rows of widgets after deletion in a QGridLayout如何在 QGridLayout 中删除后添加小部件行
【发布时间】:2018-05-03 00:02:44
【问题描述】:

我正在向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

当我添加多行小部件(例如五行小部件)时,第一次一切正常。如果我删除行(例如两行小部件),一切也都很好。但是一旦我决定再次添加一行(删除后),它就无法正常工作:我最终得到了 6 行,而我应该有 3 行。

它必须是我的代码,用于删除不能正常工作的行(但这些行在视觉上被删除了)。我做错了什么?

【问题讨论】:

  • 如果你想让我们帮助你,你必须提供一个Minimal, Complete, and Verifiable example,也就是说它可以被复制但是你需要更多的代码来执行它,我个人懒于完成你的代码
  • 您好 eyllanesc,对不起,我正在尝试尽快发送更完整的答案。这是我在这里的第一条消息(我想发布完整的 689 行代码,但在代码标签中,......不太好......)。
  • 您必须提供一个最小、完整和可验证的示例。如果您的代码很长,请创建另一个项目,其中仅包含生成错误的功能。

标签: python layout pyqt pyqt4 qgridlayout


【解决方案1】:

QGridLayout 在删除其小部件时不会删除任何行 - 但空行不会占用任何空间,因此您通常不会注意到它们。如果您添加超出当前行数的小部件,则布局将简单地增长到所需的大小。因此,如果当前行数为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)+'. ')

(请注意,我在这里也修复了最后一行,之前没有任何意义)。

编辑

根据 cmets,以下是所需的更改,以便为每次单击第一个按钮添加一行,并在单击第二个按钮时清除所有行。

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]

【讨论】:

  • 感谢您的回答 ekhumoro 但如果我用此代码替换,则只会创建一行...每次按下按钮时,只会创建第 1 行。
  • ekhumoro 你可以在这里查看整个代码:pastebin.com/EqsTVgrs
  • @ekdmekdm。为什么您希望该代码创建不止一行?其他行应该来自哪里?
  • 对不起,我确实做得很糟糕(也许我对我的解释感到困惑)......实际上我每次按下按钮时都想要......额外的一行是已添加。
  • @ekdmekdm。所以实际上你不想在ajouter_un_mot_vocab 中循环,也不想每次都将dico_vocab_mot 等重置为空的dict
猜你喜欢
  • 2011-07-20
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多