headerData of qabstracttablemodel unable to return QtCore.QVariant(list of strings)
-
wrote on 17 Sept 2021, 10:16 last edited by
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"))
wrote on 17 Sept 2021, 11:42 last edited by@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. -
wrote on 17 Sept 2021, 19:58 last edited by blossomsg
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?
wrote on 18 Sept 2021, 06:31 last edited by JonB@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
-
wrote on 18 Sept 2021, 17:07 last edited by
@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"))
wrote on 18 Sept 2021, 20:48 last edited by@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.
wrote on 19 Sept 2021, 03:56 last edited by blossomsgheaderStrings[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??
wrote on 19 Sept 2021, 06:39 last edited by@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.
wrote on 19 Sept 2021, 11:15 last edited by@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.
8/11