headerData of qabstracttablemodel unable to return QtCore.QVariant(list of strings)
-
Hello guys,
i am creating a qabstracttablemodel and setting that into my view, but the view is unable to load the listthis works fine
QtCore.QVariant(str("Col 2"))but when i pass
QtCore.QVariant(self.stringsList)it does not show me in the ui, i have no clue why, i even checked the typeName and it is QVariantList, still no
i tried forloop the list with str(x) still no,
i went through alot of the c++ docs and most of them said stringlist works with qvariantlist so i did not understand why it isn't working,
need some wisdom hereMy ui file converted to py file
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'D:\All_Projs\Qt_Designer_Proj\table_view_with_delegates_for_different_column\tableview_delegate\ui\table_view_delgate.ui' # # Created by: PyQt5 UI code generator 5.15.4 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(552, 489) self.verticalLayout = QtWidgets.QVBoxLayout(Form) self.verticalLayout.setObjectName("verticalLayout") self.label = QtWidgets.QLabel(Form) self.label.setObjectName("label") self.verticalLayout.addWidget(self.label) self.tableView = QtWidgets.QTableView(Form) self.tableView.setObjectName("tableView") self.verticalLayout.addWidget(self.tableView) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.label.setText(_translate("Form", "table_view"))
BaseClass - you need to run this to get the ui
from ui.table_view_delgate import Ui_Form from tablemodel import TableModel from PyQt5 import QtWidgets import sys strings = ["test_01", "test_02", "test_03", "test_04"] class TableView(QtWidgets.QWidget): """ Tableview to test the delegates for multiple rows and columns """ def __init__(self): super(TableView, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) self.model = TableModel(strings) self.ui.tableView.setModel(self.model) self.horizontalHeader = self.ui.tableView.horizontalHeader() self.horizontalHeader.setVisible(True) app = QtWidgets.QApplication(sys.argv) window = TableView() window.show() sys.exit(app.exec_())
model class - my QAbstractTableModel class for showing row and column
from PyQt5 import QtCore class TableModel(QtCore.QAbstractTableModel): def __init__(self, strings, parent=None): super(TableModel, self).__init__(parent) self.stringsList = strings def rowCount(self, index=QtCore.QModelIndex()): return len(self.stringsList) def columnCount(self, index=QtCore.QModelIndex()): return len(self.stringsList) def data(self, index=QtCore.QModelIndex(), role=QtCore.Qt.DisplayRole): if not index.isValid(): return None elif role != QtCore.Qt.DisplayRole: return None def headerData(self, section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole): if role == QtCore.Qt.DisplayRole: if orientation == QtCore.Qt.Horizontal: if section == 0: return QtCore.QVariant(str("Col 2")) if orientation == QtCore.Qt.Vertical: if section == 0: return QtCore.QVariant(str("Row 1"))
-
Hello guys,
i am creating a qabstracttablemodel and setting that into my view, but the view is unable to load the listthis works fine
QtCore.QVariant(str("Col 2"))but when i pass
QtCore.QVariant(self.stringsList)it does not show me in the ui, i have no clue why, i even checked the typeName and it is QVariantList, still no
i tried forloop the list with str(x) still no,
i went through alot of the c++ docs and most of them said stringlist works with qvariantlist so i did not understand why it isn't working,
need some wisdom hereMy ui file converted to py file
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'D:\All_Projs\Qt_Designer_Proj\table_view_with_delegates_for_different_column\tableview_delegate\ui\table_view_delgate.ui' # # Created by: PyQt5 UI code generator 5.15.4 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(552, 489) self.verticalLayout = QtWidgets.QVBoxLayout(Form) self.verticalLayout.setObjectName("verticalLayout") self.label = QtWidgets.QLabel(Form) self.label.setObjectName("label") self.verticalLayout.addWidget(self.label) self.tableView = QtWidgets.QTableView(Form) self.tableView.setObjectName("tableView") self.verticalLayout.addWidget(self.tableView) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.label.setText(_translate("Form", "table_view"))
BaseClass - you need to run this to get the ui
from ui.table_view_delgate import Ui_Form from tablemodel import TableModel from PyQt5 import QtWidgets import sys strings = ["test_01", "test_02", "test_03", "test_04"] class TableView(QtWidgets.QWidget): """ Tableview to test the delegates for multiple rows and columns """ def __init__(self): super(TableView, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) self.model = TableModel(strings) self.ui.tableView.setModel(self.model) self.horizontalHeader = self.ui.tableView.horizontalHeader() self.horizontalHeader.setVisible(True) app = QtWidgets.QApplication(sys.argv) window = TableView() window.show() sys.exit(app.exec_())
model class - my QAbstractTableModel class for showing row and column
from PyQt5 import QtCore class TableModel(QtCore.QAbstractTableModel): def __init__(self, strings, parent=None): super(TableModel, self).__init__(parent) self.stringsList = strings def rowCount(self, index=QtCore.QModelIndex()): return len(self.stringsList) def columnCount(self, index=QtCore.QModelIndex()): return len(self.stringsList) def data(self, index=QtCore.QModelIndex(), role=QtCore.Qt.DisplayRole): if not index.isValid(): return None elif role != QtCore.Qt.DisplayRole: return None def headerData(self, section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole): if role == QtCore.Qt.DisplayRole: if orientation == QtCore.Qt.Horizontal: if section == 0: return QtCore.QVariant(str("Col 2")) if orientation == QtCore.Qt.Vertical: if section == 0: return QtCore.QVariant(str("Row 1"))
@blossomsg
YourTableModel.data()
method does not accessself.stringsList
in any way, and never returns anything, so I don't know what you expect?You will want at minimum something like:
def data(self, index=QtCore.QModelIndex(), role=QtCore.Qt.DisplayRole): if not index.isValid(): return None if role == QtCore.Qt.DisplayRole: return self.stringsList[index.row()]
You also have both
rowCount()
&columnCount()
returninglen(self.stringsList)
, which can't be right. The strings are (presumably) your rows, socolumnCount()
should justreturn 1
, or maybe vice versa if you want them to show as columns rather than rows. Either way, your string list is one-dimensional, so it can only be the data for either rows or columns. -
Apologies if i did not explain well,
in my TableModel.headerData i want to pass a list
currently if you see i am passing str("Col 2") for section 0
for section 1 i'll have to pass str("Col 3") and so onis there any way to pass list?
and how did you highlight all the specifics in pink in your comment?
-
Hi,
You may store the data as a list but there's no reason for a list to be returned unless you have your own QHeaderView that handles that use case.
-
Apologies if i did not explain well,
in my TableModel.headerData i want to pass a list
currently if you see i am passing str("Col 2") for section 0
for section 1 i'll have to pass str("Col 3") and so onis there any way to pass list?
and how did you highlight all the specifics in pink in your comment?
@blossomsg
As @SGaist has said. You can makeheaderData()
work from a an internal list of header strings in the same way as yourdata()
intends to useself.stringsList
for its data. Like:self.headerStrings = ["Col0", "Col1", ...] ... def headerData(self, section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole): if role == QtCore.Qt.DisplayRole: if orientation == QtCore.Qt.Horizontal: return self.headerStrings[section]
The "pinks", as you call them, are for code/literals --- note they are in monospace font. For an inline code you enclose it in single backticks; type:
This is `code inside backticks` within a line
shows as
This is
code inside backticks
within a lineFor multiline blocks, like a whole block of code, put triple-backticks immediately before & after; type:
``` This is code across multiple lines ```
shows as
This is code across multiple lines
-
@JonB and @SGaist ,
Thank you guys
everything works superb the output that i was looking for is above2 new things that i learnt,
we could parent the argument
self.headerStrings[section]
like you did ---- how did you know we could use arguments in such manner @JonB ?plus i did something really foolish
if section == 0: return QtCore.QVariant(str("Col 2"))
in theTableModel.headerData
0 limits the value for section output to position 0 only and QtCore.QVariant did not work for lists the above isthe best answer
but i'll will definitely try @SGaist what you suggested Qheaderview, if there is any page that you could suggest or any book?
Thank you.
-
@blossomsg said in headerData of qabstracttablemodel unable to return QtCore.QVariant(list of strings):
we could parent the argument
self.headerStrings[section] like you did ---- how did you know we could use arguments in such manner @JonB ?There's no parenting done. Are you talking about the usage of self ?
As for the arguments question: section will go from 0 to number of sections minus one. The headerStrings list has the same size and its content is properly ordered hence the fine result you have.
-
Hello guys,
i am creating a qabstracttablemodel and setting that into my view, but the view is unable to load the listthis works fine
QtCore.QVariant(str("Col 2"))but when i pass
QtCore.QVariant(self.stringsList)it does not show me in the ui, i have no clue why, i even checked the typeName and it is QVariantList, still no
i tried forloop the list with str(x) still no,
i went through alot of the c++ docs and most of them said stringlist works with qvariantlist so i did not understand why it isn't working,
need some wisdom hereMy ui file converted to py file
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'D:\All_Projs\Qt_Designer_Proj\table_view_with_delegates_for_different_column\tableview_delegate\ui\table_view_delgate.ui' # # Created by: PyQt5 UI code generator 5.15.4 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(552, 489) self.verticalLayout = QtWidgets.QVBoxLayout(Form) self.verticalLayout.setObjectName("verticalLayout") self.label = QtWidgets.QLabel(Form) self.label.setObjectName("label") self.verticalLayout.addWidget(self.label) self.tableView = QtWidgets.QTableView(Form) self.tableView.setObjectName("tableView") self.verticalLayout.addWidget(self.tableView) self.retranslateUi(Form) QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): _translate = QtCore.QCoreApplication.translate Form.setWindowTitle(_translate("Form", "Form")) self.label.setText(_translate("Form", "table_view"))
BaseClass - you need to run this to get the ui
from ui.table_view_delgate import Ui_Form from tablemodel import TableModel from PyQt5 import QtWidgets import sys strings = ["test_01", "test_02", "test_03", "test_04"] class TableView(QtWidgets.QWidget): """ Tableview to test the delegates for multiple rows and columns """ def __init__(self): super(TableView, self).__init__() self.ui = Ui_Form() self.ui.setupUi(self) self.model = TableModel(strings) self.ui.tableView.setModel(self.model) self.horizontalHeader = self.ui.tableView.horizontalHeader() self.horizontalHeader.setVisible(True) app = QtWidgets.QApplication(sys.argv) window = TableView() window.show() sys.exit(app.exec_())
model class - my QAbstractTableModel class for showing row and column
from PyQt5 import QtCore class TableModel(QtCore.QAbstractTableModel): def __init__(self, strings, parent=None): super(TableModel, self).__init__(parent) self.stringsList = strings def rowCount(self, index=QtCore.QModelIndex()): return len(self.stringsList) def columnCount(self, index=QtCore.QModelIndex()): return len(self.stringsList) def data(self, index=QtCore.QModelIndex(), role=QtCore.Qt.DisplayRole): if not index.isValid(): return None elif role != QtCore.Qt.DisplayRole: return None def headerData(self, section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole): if role == QtCore.Qt.DisplayRole: if orientation == QtCore.Qt.Horizontal: if section == 0: return QtCore.QVariant(str("Col 2")) if orientation == QtCore.Qt.Vertical: if section == 0: return QtCore.QVariant(str("Row 1"))
@blossomsg In python it is not necessary to use QVariant since, unlike c++, the typing is dynamic and the conversion to QVariant is done by the binding
-
@blossomsg said in headerData of qabstracttablemodel unable to return QtCore.QVariant(list of strings):
we could parent the argument
self.headerStrings[section] like you did ---- how did you know we could use arguments in such manner @JonB ?There's no parenting done. Are you talking about the usage of self ?
As for the arguments question: section will go from 0 to number of sections minus one. The headerStrings list has the same size and its content is properly ordered hence the fine result you have.
headerStrings[section]
only this, what is this logic, apologies i don't understand this specificfor example
if one is using listWigdet.items(list_of_strings)but in the
headerData(section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole)
how is this the otherway headerStrings[section]
the list is outside and section is in boxbracketsjust trying to understand what is the concept here
same thing after i applied [section] i searched on google
https://wiki.qt.io/Qt_for_Python_Tutorial:_Data_Visualization_Tool
https://stackoverflow.com/questions/41510927/pyqt-horizontal-and-vertical-headersare we replacing??
-
headerStrings[section]
only this, what is this logic, apologies i don't understand this specificfor example
if one is using listWigdet.items(list_of_strings)but in the
headerData(section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole)
how is this the otherway headerStrings[section]
the list is outside and section is in boxbracketsjust trying to understand what is the concept here
same thing after i applied [section] i searched on google
https://wiki.qt.io/Qt_for_Python_Tutorial:_Data_Visualization_Tool
https://stackoverflow.com/questions/41510927/pyqt-horizontal-and-vertical-headersare we replacing??
@blossomsg
I was the person who wrote theheaderData()
definition earlier. I don't understand what you are asking here.self.headerStrings = ["Col0", "Col1", ...]
In
TableModel
I am declaring a member variable,self.headerStrings
. It is a Python array/list because I set it to["Col0", "Col1", ...]
. That is an array/list of strings. Clearly"Col0"
is intended to be the header for column #0,"Col1"
the header for column #1, and so on.def headerData(self, section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole): ... return self.headerStrings[section]
Qt passes
section
to this method and wants the header string for the column atsection
to be returned. So I can just usesection
as the index intoself.headerStrings[]
to retrieve the header for that column/section.That's all there is to it.
-
@blossomsg
I was the person who wrote theheaderData()
definition earlier. I don't understand what you are asking here.self.headerStrings = ["Col0", "Col1", ...]
In
TableModel
I am declaring a member variable,self.headerStrings
. It is a Python array/list because I set it to["Col0", "Col1", ...]
. That is an array/list of strings. Clearly"Col0"
is intended to be the header for column #0,"Col1"
the header for column #1, and so on.def headerData(self, section, orientation=QtCore.Qt.Orientation, role=QtCore.Qt.DisplayRole): ... return self.headerStrings[section]
Qt passes
section
to this method and wants the header string for the column atsection
to be returned. So I can just usesection
as the index intoself.headerStrings[]
to retrieve the header for that column/section.That's all there is to it.
@JonB
Hey sorry for the trouble, the last line explains a lot of logic, i had never seen such an approach in python and nor in pyqt, so i got confused
we usually use class.method(some datatypes) to execute/return values directly to the view/ui.
This was new, Thank you for taking out time.
Can you suggest any pages where i can refer such examples?
But for now i'll close ticket.