IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PyQt Python Discussion :

Geler des lignes ou colonnes dans un QTableView


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2013
    Messages : 19
    Par défaut Geler des lignes ou colonnes dans un QTableView
    J'ai un tableau avec beaucoup d'information a faire afficher dans un QTableView ou QTableWidget, peut importe. Ce que je veux c'est de pouvoir geler quelque colonnes et lignes, les premières du tableau pour que lorsque je me déplace vers le bas ou la droite dans le tableau, je puisse toujours voir ces lignes et colonnes.

    Il existe un exemple de ça, mais programmer en C++ et je n'arrive pas à le convertir ou comprendre suffisamment le code C++ pour le mettre dans mon Python. Ce que je veux c'est un code python. j'ai mis le lien vers le code c++ que j'ai trouvé qui fait ce que je veux

    Si quelqu'un peut m'aider à me batir un code python qui fera la même chose ça serait grandement apprécié.

    Merci et voici le lien discuté plus haut.

    http://harmattan-dev.nokia.com/docs/...zencolumn.html

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    C'est super intéressant ça, j'y ai un peu planché hier soir et ce matin.

    Je propose une version Python du code que tu as donné en lien.

    Je sous-classe ici un QTableView mais ce pourrait aussi être un QAbstractItemModel, à tester.

    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
     
    # -*- coding: utf-8 -*-
     
    from PyQt4 import QtCore, QtGui
     
    class FreezeTableView(QtGui.QtableView):
        def __init__(self, model=None, parent=None):
            super(FreezeTableView, self).__init__(parent)
            self.model = model
            self.frozenTable = FrozenTableView(self)
            self.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
            self.setVerticalScrollMode((QtGui.QAbstractItemView.ScrollPerPixel)
            self.viewport().stackUnder(self.frozenTable)
     
            self.horizontalHeader().sectionResized.connect(self.updateSectionWidth)
            self.verticalHeader().sectionResized.connect(self.updateSectionHeight)
            self.frozenTable.verticalScrollBar().valueChanged.connect(self.verticalScrollBar().setValue)
            self.verticalScrollBar().valueChanged.connect(self.frozenTableView.verticalScrollBar().setValue)
     
            if model is not None:
                self.set_model(model)
     
        def set_model(self, mdl):
            self.setModel(mdl)
            self.frozenTable.setModel(mdl)
            for i in range(1, self.model.columnCount() - 1):
                self.frozenTable.setColumnHidden(i, true)
                self.frozenTable.setColumnWidth(0, self.columnWidth(0))
                self.updateFrozenTableGeometry()
     
        def scrollTo(self, index, hint=QtGui.QAbstractItemView.EnsureVisible):
            if index.column() > 0:
                QtGui.QtableView.scrollTo(index, hint)
     
        def updateSectionWidth(self, idx, old, new):
            if idx == 0:
                self.frozenTable.setColumnWidth(0, new)
                self.updateFrozenTableGeometry()
     
        def updateSectionHeight(self, idx, old, new):
            self.frozenTableView.setRowHeight(idx, new)
     
        def updateFrozenTableGeometry(self):
            self.frozenTable.setGeometry(self.verticalHeader().width() +
                                         self.frameWidth(), self.frameWidth(), 
                                         self.columnWidth(0),
                                         self.viewport().height() + 
                                         self.horizontalHeader().height())
     
        def resizeEvent(self, event):
            self.updateFrozenTableGeometry()
            QtGui.QTableView.resizeEvent(event)
     
    class FrozenTableView(QtGui.QtableView):
        def __init__(self, parent=None):
            super(FrozenTableView, self).__init__(parent)
            self.setFocusPolicy(QtCore.Qt.NoFocus)
            self.verticalHeader().hide()
            self.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
            self.setSelectionModel(QtGui.QItemSelectionModel())
            self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.setVerticalScrollMode((QtGui.QAbstractItemView.ScrollPerPixel)
    Le principe de ce code, que tu auras sans doute compris, consiste à afficher par dessus le tableur principal un second tableur d'une seule colonne et auquel on applique le même modèle de données que le premier.

    Pour obtenir la même chose avec la première ligne, il faudra donc créer un troisième tableur de la même manière.

    Ceci fonctionne tant que les colonnes "figées" se trouvent à gauche du tableur et les lignes "figées" en haut.

    Remarques:
    Je n'ai rien testé, faudra commencer par les erreurs de syntaxe donc.

    Je n'ai pas réimplémenté le mouveCursor(), parce que si j'en comprend l'utilité, la syntaxe m'est apparue quelque peu ésotérique. Je regarderai cela plus tard.


    Quoiqu'il en soit, fait des test et tiens nous au courant, il y aura sûrement des choses à corriger mais ça vaut la peine.

  3. #3
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Un exemple utilisable: (en tous cas testable)
    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
     
    # -*- coding: utf-8 -*-
     
    from PyQt4 import QtCore, QtGui
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setWindowTitle("FreezeTableView")
            MainWindow.resize(401, 291)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.gridLayout = QtGui.QGridLayout(self.centralwidget)
            self.tableView = FreezeTableView(None, self.centralwidget)
            self.gridLayout.addWidget(self.tableView, 0, 0, 1, 1)
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtGui.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 401, 25))
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtGui.QStatusBar(MainWindow)
            MainWindow.setStatusBar(self.statusbar)
     
            self.create_model()
            self.tableView.set_model(self.model)
     
        def create_model(self):
            self.model = QtGui.QStandardItemModel(12, 20, None)
            for i in range(20):
                self.model.setHeaderData(1, QtCore.Qt.Horizontal, "Col. %s" % i)
     
            for i in range(12):
                infos = ["Row%sCol%s" %(i, j) for j in range(20)]
                self.add_data(infos)
     
        def add_data(self, data):
            self.model.insertRow(0)
            for idx, val in enumerate(data):
                self.model.setData(self.model.index(0, idx), val)
     
     
    class FreezeTableView(QtGui.QTableView):
        def __init__(self, model=None, parent=None):
            super(FreezeTableView, self).__init__(parent)
            self.frozenTable = FrozenTableView(self)
            self.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
            self.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
            self.viewport().stackUnder(self.frozenTable)
     
            self.horizontalHeader().sectionResized.connect(self.updateSectionWidth)
            self.verticalHeader().sectionResized.connect(self.updateSectionHeight)
            self.frozenTable.verticalScrollBar().valueChanged.connect(
                                                self.verticalScrollBar().setValue)
            self.verticalScrollBar().valueChanged.connect(
                                self.frozenTable.verticalScrollBar().setValue)
     
            if model is not None:
                self.set_model(model)
     
        def set_model(self, mdl):
            self.model = mdl
            self.setModel(mdl)
            self.frozenTable.setModel(mdl)
            self.frozenTable.setSelectionModel(QtGui.QItemSelectionModel(mdl))
            for i in range(1, self.model.columnCount() - 1):
                self.frozenTable.setColumnHidden(i, True)
                self.frozenTable.setColumnWidth(0, self.columnWidth(0))
                self.updateFrozenTableGeometry()
     
        def scrollTo(self, index, hint):
            if index.column() > 0:
                QtGui.QTableView.scrollTo(self, QtGui.QAbstractItemView.EnsureVisible)
     
        def updateSectionWidth(self, idx, old, new):
            if idx == 0:
                self.frozenTable.setColumnWidth(0, new)
                self.updateFrozenTableGeometry()
     
        def updateSectionHeight(self, idx, old, new):
            self.frozenTableView.setRowHeight(idx, new)
     
        def updateFrozenTableGeometry(self):
            self.frozenTable.setGeometry(self.verticalHeader().width() +
                                         self.frameWidth(), self.frameWidth(), 
                                         self.columnWidth(0),
                                         self.viewport().height() + 
                                         self.horizontalHeader().height())
     
        def resizeEvent(self, event):
            self.updateFrozenTableGeometry()
            QtGui.QTableView.resizeEvent(self, event)
     
    class FrozenTableView(QtGui.QTableView):
        def __init__(self, parent=None):
            super(FrozenTableView, self).__init__(parent)
            self.setFocusPolicy(QtCore.Qt.NoFocus)
            self.verticalHeader().hide()
            self.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
            self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.setVerticalScrollMode((QtGui.QAbstractItemView.ScrollPerPixel))
     
     
     
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2013
    Messages : 19
    Par défaut
    Merci, je vais regarder ça cet après midi et demain. Je vous en donne des nouvelle.

    Merci, c'est très apprécié et je suis certain que ça va pouvoir servir à d'autre par la suite, donc une fois qu'on aura tout débuger, on pourra mettre le code sur ce post.

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2013
    Messages : 19
    Par défaut
    J'ai travaillé sur le code et j'ai ajouter le header pour deux ligne en haut du tableau.

    Deux problème subsiste par la suite, le premier header que vous avez créer reste là mais les données disparaisse. De plus, au point de jointe des deux header (en ligne et colonne) quand je déplace le scrollBar ça ne fait pas ce qu'on voudrait, on ne vois pas les données correctement au point de jonction.

    J'ai tenté plusieurs chose, mais je n'y ai pas arrivé.

    De plus, je ne comprends pas la ligne "self.viewport().stackUnder(self.frozenTable)"

    Je ne la comprends pas bien. Je croyais que ça permettait de mettre un tableau en dessous, mais je tente de faire apparaitre celui du côté mais je n'y arrive pas.

    Merci de votre aide.

    Richard

    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
     
    # -*- coding: utf-8 -*-
     
    from PyQt4 import QtCore, QtGui
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setWindowTitle("FreezeTableView")
            MainWindow.resize(401, 291)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.gridLayout = QtGui.QGridLayout(self.centralwidget)
            self.tableView = FreezeTableView(None, self.centralwidget)
            self.gridLayout.addWidget(self.tableView, 0, 0, 1, 1)
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtGui.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 401, 25))
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtGui.QStatusBar(MainWindow)
            MainWindow.setStatusBar(self.statusbar)
     
            self.create_model()
            self.tableView.set_model(self.model)
     
        def create_model(self):
            self.model = QtGui.QStandardItemModel(12, 20, None)
            for i in range(20):
                self.model.setHeaderData(1, QtCore.Qt.Horizontal, "Col. %s" % i)
     
            for i in range(12):
                infos = ["Row%sCol%s" %(i, j) for j in range(20)]
                self.add_data(infos)
     
        def add_data(self, data):
            self.model.insertRow(0)
            for idx, val in enumerate(data):
                self.model.setData(self.model.index(0, idx), val)
     
     
    class FreezeTableView(QtGui.QTableView):
        def __init__(self, model=None, parent=None):
            super(FreezeTableView, self).__init__(parent)
            self.frozenTable = FrozenTableView(self)
            self.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
            self.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
    #        self.viewport().stackUnder(self.frozenTable)
     
            self.ligneFrozenTable = FrozenTableView(self)
    #        self.viewport().stackUnder(self.ligneFrozenTable)
     
            self.verticalHeader().hide()
            self.horizontalHeader().sectionResized.connect(self.updateSectionWidth)
            self.verticalHeader().sectionResized.connect(self.updateSectionHeight)
            self.frozenTable.verticalScrollBar().valueChanged.connect(
                                                self.verticalScrollBar().setValue)
            self.verticalScrollBar().valueChanged.connect(
                                self.frozenTable.verticalScrollBar().setValue)
     
            self.ligneFrozenTable.horizontalScrollBar().valueChanged.connect(
                                                self.horizontalScrollBar().setValue)
            self.horizontalScrollBar().valueChanged.connect(
                                self.ligneFrozenTable.horizontalScrollBar().setValue)
     
     
            if model is not None:
                self.set_model(model)
     
        def set_model(self, mdl):
            self.model = mdl
            self.setModel(mdl)
            self.frozenTable.setModel(mdl)
            self.ligneFrozenTable.setModel(mdl)
            self.frozenTable.setSelectionModel(QtGui.QItemSelectionModel(mdl))
            self.ligneFrozenTable.setSelectionModel(QtGui.QItemSelectionModel(mdl))
            for i in range(1, self.model.columnCount() - 1):
                self.frozenTable.setColumnHidden(i, True)
                self.frozenTable.setColumnWidth(0, self.columnWidth(0))
                self.updateFrozenTableGeometry()
            for i in range(1, self.model.rowCount() - 1):
                self.frozenTable.setRowHidden(i, True)
                self.frozenTable.setRowHeight(0, self.rowHeight(0))
                self.updateFrozenTableGeometry()
     
        def scrollTo(self, index, hint):
            if index.column() > 0:
                QtGui.QTableView.scrollTo(self, QtGui.QAbstractItemView.EnsureVisible)
     
        def updateSectionWidth(self, idx, old, new):
            if idx == 0:
                self.frozenTable.setColumnWidth(0, new)
                self.ligneFrozenTable.setRowHeight(0, new)
                self.updateFrozenTableGeometry()
     
        def updateSectionHeight(self, idx, old, new):
            self.frozenTable.setRowHeight(idx, new)
            self.ligneFrozenTable.setColumnWidth(idx, new)
     
        def updateFrozenTableGeometry(self):
            self.frozenTable.setGeometry(self.verticalHeader().width() +
                                         self.frameWidth(), self.frameWidth(), 
                                         self.columnWidth(0),
                                         self.viewport().height() + 
                                         self.horizontalHeader().height())
            self.ligneFrozenTable.setGeometry(self.verticalHeader().width() +
                                         self.frameWidth(), self.frameWidth(), 
                                         self.viewport().width() + self.verticalHeader().width(),
                                         self.horizontalHeader().height() + self.rowHeight(0) + self.rowHeight(1))
     
        def resizeEvent(self, event):
            self.updateFrozenTableGeometry()
            QtGui.QTableView.resizeEvent(self, event)
     
    class FrozenTableView(QtGui.QTableView):
        def __init__(self, parent=None):
            super(FrozenTableView, self).__init__(parent)
            self.setFocusPolicy(QtCore.Qt.NoFocus)
            self.verticalHeader().hide()
            self.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
            self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.setVerticalScrollMode((QtGui.QAbstractItemView.ScrollPerPixel))
            self.setHorizontalScrollMode((QtGui.QAbstractItemView.ScrollPerPixel))
     
     
     
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())

  6. #6
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    Les données qui disparaissent, c'est normal, telle que je l'ai écrite la classe FrozenTableView ne convient que pour une colonne, la geométrie doit être adaptée pour une rangée.

    J'ai modifié le code pour que la même classe puisse servir pour une colonne et pour une rangée il suffit d'indiquer l'orientation 0 == horizontal et 1 == vertical.

    Le stackUnder() sert bien à garder la table principale en dessous de la table figée mais il ne faut le faire que pour une seule des deux tables figées.

    Par contre la cellule commune aux deux tables figées contiendra toujours la donnée de la table qui recouvre les autres. Dans ce cas ci la rangée figée. Et là, je pense qu'on ne pourra rien y faire. En tout cas la question reste posée.

    Donc j'ai modifié le code en ajoutant une rangée figée et en déplaçant dans la classe FrozenTableView les méthodes qui lui appartiennent.

    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
     
    # -*- coding: utf-8 -*-
     
    from PyQt4 import QtCore, QtGui
     
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setWindowTitle("FreezeTableView")
            MainWindow.resize(401, 291)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.gridLayout = QtGui.QGridLayout(self.centralwidget)
            self.tableView = FreezeTableView(None, self.centralwidget)
            self.gridLayout.addWidget(self.tableView, 0, 0, 1, 1)
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtGui.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 401, 25))
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtGui.QStatusBar(MainWindow)
            MainWindow.setStatusBar(self.statusbar)
     
            self.create_model()
            self.tableView.set_model(self.model)
     
        def create_model(self):
            self.model = QtGui.QStandardItemModel(12, 20, None)
            for i in range(19, -1, -1):
                self.model.setHeaderData(i, QtCore.Qt.Horizontal, "Col. %s" % i)
     
            for i in range(11, -1, -1):
                infos = ["Row%sCol%s" %(i, j) for j in range(20)]
                self.add_data(infos)
     
        def add_data(self, data):
            self.model.insertRow(0)
            for idx, val in enumerate(data):
                self.model.setData(self.model.index(0, idx), val)
     
     
    class FreezeTableView(QtGui.QTableView):
        def __init__(self, model=None, parent=None):
            super(FreezeTableView, self).__init__(parent)
            self.frozenColumn = FrozenTableView(self)
            self.frozenColumn.set_orientation(1)
            self.frozenRow = FrozenTableView(self)
            self.frozenRow.set_orientation(0)
            self.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
            self.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
            self.viewport().stackUnder(self.frozenColumn)
     
            self.horizontalHeader().sectionResized.connect(self.updateSectionWidth)
            self.verticalHeader().sectionResized.connect(self.updateSectionHeight)
            self.frozenColumn.verticalScrollBar().valueChanged.connect(
                                                self.verticalScrollBar().setValue)
            self.frozenRow.horizontalScrollBar().valueChanged.connect(
                                                self.horizontalScrollBar().setValue)
            self.verticalScrollBar().valueChanged.connect(
                                self.frozenColumn.verticalScrollBar().setValue)
            self.horizontalScrollBar().valueChanged.connect(
                                self.frozenRow.horizontalScrollBar().setValue)
     
            if model is not None:
                self.set_model(model)
     
        def show_value(self, val):
            print val
     
        def set_model(self, mdl):
            self.model = mdl
            self.setModel(mdl)
            self.frozenColumn.setModel(mdl)
            self.frozenColumn.setSelectionModel(QtGui.QItemSelectionModel(mdl))
            self.frozenColumn.show_columns()
            self.frozenRow.setModel(mdl)
            self.frozenRow.setSelectionModel(QtGui.QItemSelectionModel(mdl))
            self.frozenRow.show_rows()
     
        def scrollTo(self, index, hint):
            if index.column() > 0:
                QtGui.QTableView.scrollTo(self, QtGui.QAbstractItemView.EnsureVisible)
     
        def updateSectionWidth(self, idx, old, new):
            if idx == 0:
                self.frozenColumn.setColumnWidth(0, new)
                self.frozenColumn.update_geometry()
     
        def updateSectionHeight(self, idx, old, new):
            self.frozenRow.setRowHeight(idx, new)
     
        def resizeEvent(self, event):
            self.frozenColumn.update_geometry()
            self.frozenRow.update_geometry()
            QtGui.QTableView.resizeEvent(self, event)
     
    class FrozenTableView(QtGui.QTableView):
        def __init__(self, parent=None):
            super(FrozenTableView, self).__init__(parent)
            self.parent = parent
            self.setFocusPolicy(QtCore.Qt.NoFocus)
            self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
            self.setVerticalScrollMode((QtGui.QAbstractItemView.ScrollPerPixel))
            self.setHorizontalScrollMode((QtGui.QAbstractItemView.ScrollPerPixel))
            self.is_vertical = True
     
        def set_orientation(self, orient):
            if orient:
                self.is_vertical = True
                self.verticalHeader().hide()
                self.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
     
            else:
                self.is_vertical = False
                self.horizontalHeader().hide()
                self.verticalHeader().hide()
                self.verticalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
     
        def show_columns(self):
            for i in range(1, self.model().columnCount()):
                self.setColumnHidden(i, True)
     
            self.setColumnWidth(0, self.parent.columnWidth(0))
            self.update_geometry()
     
        def show_rows(self):
            for i in range(1, self.model().rowCount()):
                self.setRowHidden(i, True)
     
            self.setRowHeight(0, self.parent.rowHeight(0))
            self.update_geometry()
     
        def update_geometry(self):
            geo = self.parent.viewport().geometry()
            if self.is_vertical:
                self.setGeometry(geo.x(), 0, self.parent.columnWidth(0),
                                geo.height() + 
                                self.parent.horizontalHeader().height())
     
            else:
                self.setGeometry(geo.x(), geo.y(),
                                self.parent.viewport().width() +
                                self.parent.verticalHeader().width(),
                                self.parent.rowHeight(0))
     
     
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        sys.exit(app.exec_())
    Il faudra aussi synchroniser les cellules sélectionnées. Quand on sélectionne par exemple une cellule dans la colonne 1 et que l'on se déplace avec la flèche gauche la cellule de la colonne figée ne se sélectionne pas. La sélection existe mais elle est cachée par la table supérieure.
    Pareil si on sélectionne une cellule dans la colonne figée et qu'on se déplace avec la flèche droite, la sélection ne se poursuit pas dans la grande table.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. inverser les champs des lignes en colonnes dans un XML
    Par almanar dans le forum XML/XSL et SOAP
    Réponses: 0
    Dernier message: 19/02/2010, 21h09
  2. ajouter des lignes et colonnes dans un tableau
    Par sky88 dans le forum Débuter
    Réponses: 1
    Dernier message: 03/12/2008, 18h04
  3. copier des lignes sous conditions (dans 2 colonnes différentes)
    Par olive08 dans le forum Macros et VBA Excel
    Réponses: 18
    Dernier message: 12/10/2007, 14h44
  4. Concaténer des lignes d'enregistrements dans une colonne
    Par dany13 dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 08/07/2005, 21h56
  5. [Fichier] Ajout des lignes de doc dans arraylist
    Par 3adoula dans le forum Entrée/Sortie
    Réponses: 9
    Dernier message: 29/04/2004, 22h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo