gpt4 book ai didi

python - 如何在 ListView 中选择行

转载 作者:太空宇宙 更新时间:2023-11-03 20:30:49 26 4
gpt4 key购买 nike

我在网上搜索,但没有找到如何使用 python 在 qml 文件中创建的 ListView 中选择一行。我测试过,但每次都会出错。我刚开始qml,也许基础不好。所以我的问题是,使用我的代码,可以访问我的 ListView 吗?如果是,我如何在启动应用程序中选择第二项(例如)?

当我这样做时:

print(win.findChild(QObject, "listview22").setCurrentIndex(2)))

我有这条消息

AttributeError: 'QQuickItem' object has no attribute 'setCurrentIndex'

但是listview22是一个 ListView 而不是一个项目。

感谢您的帮助。

PS:我刚刚启动 qml,所以如果我的脚本不好请告诉我,然后我可以学习好的编程

main.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1

ApplicationWindow {
title: qsTr("WoodMan Training")

width: 1000
height: 700

visible: true

GridLayout {
id: grid
anchors.fill: parent
columns: 3
anchors.margins: 0
columnSpacing: 0

ColumnLayout {
Layout.columnSpan: 1
Layout.row: 2
Layout.column: 0
Layout.fillWidth: true
Layout.fillHeight: true

Layout.margins: 10

Layout.maximumWidth: 250

// ---
RowLayout{
Main_ListView{objectName: "lstGroupe"; id:lstGroupe; pyModel: ModelGroupe; pyClass: ModelGroupe}
}

Item {Layout.fillWidth: true; Layout.fillHeight: true}

}
}
}

Main_ListView.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2

Rectangle {
property var pyClass: 0
property var pyModel: 0


border.color: "red"
Layout.fillWidth: true
height:150


ListView {
anchors.topMargin: 10
anchors.bottomMargin: 10
anchors.leftMargin: 10
anchors.fill: parent

id: listview22
objectName: "listview22"

model: pyModel
clip: true // --- Empeche la surbrillance de sortir du cadre

delegate: Component {
Item {
width: 200
height: 20

property int item_id: iid

Row {
Text {
anchors.verticalCenter: parent.verticalCenter

width: 60
text: " " + libelle
}
}

MouseArea {
anchors.fill: parent
onClicked: {
listview22.currentIndex = index
pyClass.onClickItem(item_id)
}
}

}
}
highlight: Rectangle {color: '#CDCDCD'}
focus: true
}

Button {
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: 5
anchors.bottomMargin: 5

width: 28
height: 25

iconSource: "ico/math-add-icon.png"

onClicked: {
//console.log("qml adding")
pyClass.onClickInsert(22, "aluis")
}
}

}



主程序.py

from PyQt5.QtCore import QAbstractListModel, Qt, pyqtSignal, pyqtSlot, QModelIndex    

import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQuick import QQuickView

from PyQt5.QtGui import *#QGuiApplication, QColor, QStandardItemModel, QStandardItem
from PyQt5.QtQml import *#QQmlApplicationEngine, QQmlComponent
from PyQt5.QtCore import *#QUrl, Qt, QCoreApplication, QAbstractListModel, QModelIndex, QTimer, qsrand, qrand, QTime, QObject
from PyQt5.QtQuick import *#QQuickItem



class gGroupe(QAbstractListModel):


iid = Qt.UserRole + 1
libelle = Qt.UserRole + 2

data_change = pyqtSignal()

def __init__(self, parent=None):

super().__init__(parent)

self.liste = []
self.insert_list()

self.liste2 = {}

self.createIndex(0,0,125)
self.sort(1, order = Qt.DescendingOrder)


# ------------------------------------------------------------------

def roleNames(self):
return {
gGroupe.iid: b'iid',
gGroupe.libelle: b'libelle',
}

def data(self, index, role=Qt.DisplayRole):
row = index.row()
if role == gGroupe.iid:
return self.liste[row]["iid"]
if role == gGroupe.libelle:
return self.liste[row]["libelle"]

def rowCount(self, parent=QModelIndex()):
return len(self.liste)

# ------------------------------------------------------------------

def insert_list(self):

self.liste = [
{'iid': 10, 'libelle': 'groupe10'},
{'iid': 11, 'libelle': 'groupe11'},
{'iid': 12, 'libelle': 'groupe12'},
]


def delete(self, row):
self.beginRemoveRows(QModelIndex(), row, row)
del self.liste[row]
self.endRemoveRows()

def delete_all(self):
self.beginRemoveRows(QModelIndex(), 0, len(self.liste))
del self.liste[row]
self.endRemoveRows()

def select(self):
pass

@pyqtSlot(int, str)
def onClickInsert(self, iid=10, libelle='toto'):

self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
self.liste.append({'iid': iid, 'libelle': libelle})
self.endInsertRows()

return self.index(len(self.liste)-1)

@pyqtSlot(int)
def onClickItem(self, iid):
print(iid)

"""
@pyqtSlot(int, str, int)
def editPerson(self, row, name, age):
ix = self.index(row, 0)
self.persons[row] = {'iid': 22, 'name': name, 'age': age}
self.dataChanged.emit(ix, ix, self.roleNames())
"""


class MainWindow(QObject):
def __init__(self, parent=None):
super().__init__(parent)

self.g_groupe = gGroupe()
engine.rootContext().setContextProperty('ModelGroupe', self.g_groupe)

engine.load('main.qml')
win = engine.rootObjects()[0]

#win.findChild(QObject, "txtLibelle").setProperty("text", 'toto')

print(win.findChild(QObject, "listview22").setCurrentIndex(2))

a = win.findChild(QObject, "PersonModel")#.removeRows( 0, model.rowCount() )


if __name__ == "__main__":
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
# Création d'un objet QQmlContext pour communiquer avec le code QML
#ctx = engine.rootContext()
py_mainapp = MainWindow()
sys.exit(app.exec())

最佳答案

您有以下错误:

  • 您不应该将 QML 对象导出到 python,因为它会给您带来许多像您遇到的错误,甚至更严重的错误,这是 C++ 中推荐的。

  • 当尝试在 C++ 中使用 findChild (QObject, "listview22") 获取 ListView 时,只会获取一个 QObject,但 python 会尝试推断类型,为此它具有 Qt 的公共(public) API 作为限制,在您的 ListView 中,它不是 QListView,并且它的类型在 Python 或 C++ 中不存在,因为它是私有(private) API 的一部分,因此附近的类是 QQuickItem,因为 ListView 继承自该类。

建议创建一个 QObject 并添加映射逻辑并导出到 QML 的 qproperties,因此,如果您在 python 中修改 QObject,它也会在 QML 中修改它。

ma​​in.py

from PyQt5.QtCore import (
pyqtProperty,
pyqtSignal,
pyqtSlot,
QAbstractListModel,
QModelIndex,
QObject,
Qt,
QTimer,
)
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine


class gGroupe(QAbstractListModel):

iid = Qt.UserRole + 1
libelle = Qt.UserRole + 2

data_change = pyqtSignal()

def __init__(self, parent=None):
super().__init__(parent)

self.liste = []
self.insert_list()

self.sort(0, order=Qt.DescendingOrder)

def roleNames(self):
return {gGroupe.iid: b"iid", gGroupe.libelle: b"libelle"}

def data(self, index, role=Qt.DisplayRole):
row = index.row()
if role == gGroupe.iid:
return self.liste[row]["iid"]
if role == gGroupe.libelle:
return self.liste[row]["libelle"]

def rowCount(self, parent=QModelIndex()):
return len(self.liste)

# ------------------------------------------------------------------

def insert_list(self):
self.beginResetModel()
self.liste = [
{"iid": 10, "libelle": "groupe10"},
{"iid": 11, "libelle": "groupe11"},
{"iid": 12, "libelle": "groupe12"},
]
self.endResetModel()

def delete(self, row):
self.beginRemoveRows(QModelIndex(), row, row)
del self.liste[row]
self.endRemoveRows()

def delete_all(self):
self.beginRemoveRows(QModelIndex(), 0, len(self.liste))
del self.liste[row]
self.endRemoveRows()

def select(self):
pass

@pyqtSlot(int, str)
def insert(self, iid=10, libelle="toto"):
self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
self.liste.append({"iid": iid, "libelle": libelle})
self.endInsertRows()

@pyqtSlot(int)
def onClickItem(self, iid):
print(iid)


class MainWindow(QObject):
currentIndexChanged = pyqtSignal(int)

def __init__(self, parent=None):
super().__init__(parent)
self._g_groupe = gGroupe(self)
self._current_index = 0

@pyqtProperty(QObject, constant=True)
def g_groups(self):
return self._g_groupe

@pyqtProperty(int, notify=currentIndexChanged)
def currentIndex(self):
return self._current_index

@currentIndex.setter
def currentIndex(self, index):
if self._current_index == index:
return
self._current_index = index
self.currentIndexChanged.emit(index)

if __name__ == "__main__":
import sys

app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
main_window = MainWindow()
engine.rootContext().setContextProperty("main_window", main_window)
engine.load("main.qml")
if not engine.rootObjects():
sys.exit(app.exec_())

main_window.currentIndex = 2

sys.exit(app.exec())

ma​​in.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1

ApplicationWindow {
title: qsTr("WoodMan Training")

width: 1000
height: 700

visible: true

Connections{
target: main_window
onCurrentIndexChanged: lstGroupe.currentIndex = main_window.currentIndex
}

GridLayout {
id: grid
anchors.fill: parent
columns: 3
anchors.margins: 0
columnSpacing: 0

ColumnLayout {
Layout.columnSpan: 1
Layout.row: 2
Layout.column: 0
Layout.fillWidth: true
Layout.fillHeight: true

Layout.margins: 10

Layout.maximumWidth: 250

// ---
RowLayout{
Main_ListView{
id:lstGroupe;
model: main_window.g_groups
}
}

Item {
Layout.fillWidth: true
Layout.fillHeight: true
}
}
}
}

Main_ListView.qml

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2

Rectangle {
id: root
property alias model: listview22.model
property alias currentIndex: listview22.currentIndex

border.color: "red"
Layout.fillWidth: true
height:150

ListView {
id: listview22
model: root.model
anchors.topMargin: 10
anchors.bottomMargin: 10
anchors.leftMargin: 10
anchors.fill: parent
clip: true

delegate: Component {
Item {
width: 200
height: 20
property int item_id: iid
Row {
Text {
anchors.verticalCenter: parent.verticalCenter
width: 60
text: " " + libelle
}
}
MouseArea {
anchors.fill: parent
onClicked: {
listview22.currentIndex = index
listview22.model.onClickItem(item_id)
}
}
}
}
highlight: Rectangle {color: '#CDCDCD'}
focus: true
}
Button {
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: 5
anchors.bottomMargin: 5
width: 28
height: 25
iconSource: "ico/math-add-icon.png"
onClicked: {
listview22.model.insert(22, "aluis")
}
}
}

关于python - 如何在 ListView 中选择行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57523238/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com