#python #pyqt5 #qml
Вопрос:
У меня есть приложение, которое использует PyQt5, у него есть табличное представление в QML, которое берет данные из фрейма данных pandas.
Мне нужна ширина столбцов, чтобы автоматически соответствовать ширине содержимого при каждом обновлении данных с новой загрузкой фреймов данных. Я не нашел ничего нового по этой теме на форумах, и старые ответы очень запутанны, я не могу поверить, что в 2021 году не будет простого решения для чего-то столь распространенного в табличных процедурах.
Код QML, который у меня есть, выглядит следующим образом:
TableView {
id: tableView
antialiasing: true
width: parent.width
height: parent.height
columnWidthProvider: function (column) { return 200; }
rowHeightProvider: function (column) { return 60; }
leftMargin: rowsHeader.implicitWidth
topMargin: columnsHeader.implicitHeight
rightMargin: columnsHeader.implicitHeight
Layout.fillHeight: true
model: table_model
delegate: Rectangle {
color: "transparent"
Text {
text: display
anchors.fill: parent
anchors.margins: 10
horizontalAlignment: Text.AlignHCenter
color: {
if (temaescolhido.currentText == 'Claro') return 'Black'
return 'White'
}
font.pixelSize: 15
verticalAlignment: Text.AlignVCenter
}
}
Rectangle { // mask the headers
z: 3
color: "transparent"
y: tableView.contentY
x: tableView.contentX
width: tableView.leftMargin
height: tableView.topMargin
}
Row {
id: columnsHeader
y: tableView.contentY
z: 2
Repeater {
model: tableView.columns > 0 ? tableView.columns : 1
Label {
width: tableView.columnWidthProvider(modelData)
height: 35
text: table_model.headData(modelData, Qt.Horizontal)
color: 'green'
font.bold: true
font.pixelSize: 15
padding: 10
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
background: Rectangle { color: "#adadad" }
}
}
}
Column {
id: rowsHeader
x: tableView.contentX
z: 2
Repeater {
model: tableView.rows > 0 ? tableView.rows : 1
Label {
width: 35
height: tableView.rowHeightProvider(modelData)
text: table_model.headData(modelData, Qt.Vertical)
color: 'green'
font.bold: true
font.pixelSize: 15
padding: 10
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
background: Rectangle { color: "#adadad" }
}
}
}
ScrollIndicator.horizontal: ScrollIndicator { }
ScrollIndicator.vertical: ScrollIndicator { }
}
Комментарии:
1. старые ответы, вероятно, сбивают с толку, потому что табличное представление было официально добавлено только в версии 2.12, до этого мы создавали большинство таблиц с помощью ListView. Я попробую ответить, если у меня будет время. Эта функция изменилась между версиями с 5.12 по 5.15, поэтому, чтобы предоставить что-то полезное, на какую версию Qt (или PyQt5) вы нацелены?
2. Привет, спасибо за ответ. Я использую qt 5.15.4 с Qtquick. Но я рассматриваю возможность использования qtwidgets, чтобы иметь возможность выполнять весь код на python (без qml), так как у меня больше знаний на этом языке. Как вы думаете, я бы слишком много потерял в возможностях создания, переключившись с qtquick на qtwidgets?
3. Я не думаю, что есть простой ответ на виджеты vs Quick. В Quick есть анимации, которые используют OpenGL для использования 3D-графического процессора, но я читал, что виджеты лучше интегрированы с matplotlib, так что все зависит от того, что вы пытаетесь сделать
Ответ №1:
Идея нового TableView состоит в том, чтобы установить неявную ширину и неявную высоту делегатов, а затем TableView должен автоматически определять размер строк и столбцов.
Вот тривиальный пример:
import QtQuick 2.15
import QtQuick.Controls 2.15
import Qt.labs.qmlmodels 1.0
ApplicationWindow {
id: window
visible: true
width: 500
height: 500
Row {
id: buttons
Button {
text: "Press To Add Data"
onClicked: {
var index = myTableModel.rowCount 1
myTableModel.insertRow(0, {
"col 0": (1000000 index).toString(),
"col 1": index.toString().repeat(index)
})
}
}
Item {
// button spacer
width: 5
height: 5
}
Button {
text: "Press To Clear Data"
onClicked: {
myTableModel.removeRow(0)
}
}
}
TableView {
id: tableView
y: buttons.height
height: parent.height - buttons.height
width: parent.width
columnSpacing: 0
rowSpacing: 0
clip: true
model: TableModel {
id: myTableModel
TableModelColumn { display: "col 0" }
TableModelColumn { display: "col 1" }
rows: [
{
"col 0": "0",
"col 1": "1"
},
{
"col 0": "2",
"col 1": "3"
},
{
"col 0": "4",
"col 1": "5"
}
]
}
delegate: Rectangle {
implicitWidth: childrenRect.width
implicitHeight: childrenRect.height
border.width: 1
Text {
padding: 5
text: display
}
}
}
}