PDA

View Full Version : [PyQt] QTableView not showing vertical scroll bar



Gad82
22nd November 2012, 11:07
Hi everyone,

in my script I have a table view showing one column and few rows (one or two) in which each cell contains lots of data. When the data in the cells is too big it cannot be displayed in the table area, so I expect that a vertical scrollbar comes in, but this does not happen. Here is a piece of code showing the problem:



from PyQt4.QtCore import *
from PyQt4.QtGui import *

class TableModel(QAbstractItemModel) :
def rowCount(self, index):
return 1

def columnCount(self, index):
return 1

def data(self, index, role) :
i, j = index.row(), index.column()
if role == Qt.DisplayRole :
return '\n'.join(["data %d"%i for i in range(1000)])

def index(self, row, col, parent=QModelIndex()) :
return self.createIndex(row, col, 0)


class Table(QTableView) :
def __init__(self, model) :
QTableView.__init__(self)

self.setModel(model)
self.setSelectionBehavior(QAbstractItemView.Select Rows)
#self.setVerticalScrollBarPolicy(Qt.ScrollBarAlway sOn)

class Frame(QWidget) :
def __init__(self, parent, model=None) :
super(QWidget, self).__init__(parent)

self.table = Table(TableModel())

vbox = QVBoxLayout()
vbox.setContentsMargins(0, 0, 0, 0)
vbox.addWidget(self.table)
self.setLayout(vbox)
self.table.resizeRowsToContents()

if __name__ == "__main__" :
import sys
a = QApplication(sys.argv)

dia = Frame(None)
dia.resize(400, 400)
dia.show()
a.exec_()


If you run this code you'll see that even if the content of the cell exceeds the table area, the scrollbar is not displayed...am I missing something?
Thanks in advance for your help!

prof.ebral
23rd November 2012, 13:48
Set your row count to greater than 1.

You also need to reimplement the parent method. There is what I did and it works.



from PyQt4.QtCore import *
from PyQt4.QtGui import *

class TableModel(QAbstractItemModel):
def __init__(self):
QAbstractItemModel.__init__(self)

def parent(self, *args):
return self.p

def rowCount(self, index):
return 2

def columnCount(self, index):
return 1

def data(self, index, role) :
i, j = index.row(), index.column()
if role == Qt.DisplayRole :
return '\n'.join(["data %d"%i for i in range(1000)])

def index(self, row, col, parent=QModelIndex()):
self.p = parent
return self.createIndex(row, col, 0)


class Table(QTableView) :
def __init__(self, model) :
QTableView.__init__(self)

self.setModel(model)
self.setSelectionBehavior(QAbstractItemView.Select Rows)
#self.setVerticalScrollBarPolicy(Qt.ScrollBarAlway sOn)

class Frame(QWidget) :
def __init__(self, parent, model=None) :
super(QWidget, self).__init__(parent)

self.table = Table(TableModel())

vbox = QVBoxLayout()
vbox.setContentsMargins(0, 0, 0, 0)
vbox.addWidget(self.table)
self.setLayout(vbox)
self.table.resizeRowsToContents()

if __name__ == "__main__" :
import sys
a = QApplication(sys.argv)

dia = Frame(None)
dia.resize(400, 400)
dia.show()
a.exec_()

I'm also not a big fan of

from PyQt4.QtCore import *
from PyQt4.QtGui import *
I think that is a bad practice.

Gad82
23rd November 2012, 14:33
Set your row count to greater than 1.

You also need to reimplement the parent method. There is what I did and it works.



Thank you for your reply. Unfortunately something is still wrong, first the scroll bar does not allow to view "intermediate" values, that is I can only see the top and the bottom of the table. Second , adding a "fake" row in order to get things working is not really suitable in my case, since the number of rows of the table is heavily used outside the table code, so it is not so easy for me to modify it.



I'm also not a big fan of

from PyQt4.QtCore import *
from PyQt4.QtGui import *
I think that is a bad practice.

You're right, I'm not either but it was just a quick'n'dirty work to show the problem.

prof.ebral
23rd November 2012, 14:55
heh ... I guess you are correct about my scroll fix. I did not notice this in my Grids. I use a QTableView without setting a new model and my grid does not scrol the contents of one cell. You may need ti reimplement the scrollContentsBy method.