Bonjour,

J'ai une fenêtre qui affiche le contenu d'une table d'une base de données SQL avec un QTableView. Et ça marche bien!

Sauf que, au lancement de la fenêtre, lorsque la table SQL à afficher est grande (plusieurs milliers de lignes), l'ascenseur vertical est réglé pour 255 lignes. Quand on descend le curseur de l'ascenseur, les 255 premières lignes s'affichent bien, et une fois arrivé tout en bas, le curseur remonte pour montrer les ...255 lignes suivantes. Etc... et on finit par voir toutes les lignes, 3000 lignes par exemple.

Une fois cette "ajustement" fait, le curseur de l'ascenseur vertical adopte une bonne position relativement aux lignes affichées et au nombre total de lignes. En fait, tout se passe comme si le "branchement" du QTableView sur son "model" (avec setModel) ne mettait pas à jour le scrollbar vertical du nombre total de lignes.

Ce n'est pas un problème grave, mais par rapport à la qualité des IHM qu'on fait avec PyQt4, je trouve ça moche...

Ce problème ne se pose pas avec un QTableWidget.

Quelqu'un aurait-il une idée pour que l'ascenseur vertical du QTableView sache dès le départ qu'il y a 3000 lignes à afficher issues du model, et pas seulement 255?

Pour montrer le problème, voici un code autoporteur qui affiche une table SQL que ce code fabrique aussi lui-même (un simple copier-coller devrait suffire):

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import division
# Python 2.7
 
import sys
import sqlite3
import random
random.seed()
from PyQt4 import QtCore, QtGui, QtSql
 
#############################################################################
def creabasesql(basesql):
    """créer une base sql composée de 3000 nombres entiers tirés au hasard"""
    cnx = sqlite3.connect(basesql)
    cur = cnx.cursor()
    cur.execute("""drop table if exists 'matable' """)
    cur.execute("""create table 'matable' (num integer)""")
    try:
        for i in xrange(1, 3001):
            cur.execute("""insert into 'matable' values(?)""", 
                                                (random.randint(0, 100000),))
        cnx.commit()
    except sqlite3.Error, err:
        cnx.rollback()
        print "erreur: %s" % (unicode(err.args[0]),)
    cur.close()
    cnx.close()
 
#############################################################################
class Vuetable(QtGui.QWidget):
 
    def __init__(self, basesql, table, parent=None):
        super(Vuetable, self).__init__(parent)
 
        # stocker les arguments
        self.basesql = basesql
        self.table = table
 
        # instructions pour la fenêtre
        self.setWindowTitle(u"table: %s de la base: %s" % (self.table, 
                                                                self.basesql))
        self.resize(800, 600)
 
        # ouvrir une connexion avec la base de données 
        self.cnx = QtSql.QSqlDatabase.addDatabase(u"QSQLITE")
        self.cnx.setDatabaseName(self.basesql)
        if not self.cnx.open():
            QtGui.QMessageBox.critical(self, 
                        u"Ouverture de la base de données",
                        "Erreur d'ouverture: %s" % self.cnx.lastError().text())
            self.cnx = None
            self.close() # fermeture de vuetable
 
        # créer et configurer le modèle
        self.model = QtSql.QSqlRelationalTableModel(self, self.cnx)
        self.model.setTable(self.table)
        self.model.setEditStrategy(QtSql.QSqlRelationalTableModel.\
                                                               OnManualSubmit)
        self.model.select()
 
        # créer le QTableView d'affichage
        self.vue = QtGui.QTableView(self)
 
        # créer le lien entre la base sql et le QTableView grâce au modèle 
        self.vue.setModel(self.model)
        self.vue.setItemDelegate(QtSql.QSqlRelationalDelegate(self.vue))
 
        # tri ascendant du tableau affiché selon la 1ère colonne
        self.vue.setSortingEnabled(True)
        self.vue.sortByColumn(0, QtCore.Qt.AscendingOrder)
 
        # régler la largeur des colonnes en fonction de leur contenu
        self.vue.resizeColumnsToContents()
 
        # faire que le QTableView prenne toute la fenêtre et suive la redim.
        posit = QtGui.QGridLayout()
        posit.addWidget(self.vue, 0, 0)
        self.setLayout(posit)
 
 
#############################################################################
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    basesql = u"basesql.db3"
    creabasesql(basesql)
    fen = Vuetable(basesql, u"matable")
    fen.show()
    sys.exit(app.exec_())