QML Listview выделенный элемент выделяется при нажатии
Привет, я хочу поставить этот код:
highlight: Rectangle {
color: "black"
radius: 5
opacity: 0.7
focus: true
}
в mouseArea в обработчике onclick:
MouseArea {
id: mouse_area1
z: 1
hoverEnabled: false
anchors.fill: parent
onClicked: {
}
Это все listView:
ListView {
id: listview1
x: 0
y: 82
// width: 574
// height: 967
width: window.width
height: window.height
visible: true
keyNavigationWraps: false
boundsBehavior: Flickable.DragAndOvershootBounds
opacity: 1
maximumFlickVelocity: 2500
anchors.leftMargin: 0
highlightMoveSpeed: 489
contentWidth: 0
preferredHighlightEnd: 2
spacing: 5
highlightRangeMode: ListView.NoHighlightRange
snapMode: ListView.SnapToItem
anchors.bottomMargin: 0
anchors.rightMargin: 0
anchors.topMargin: 82
anchors.fill: parent
model: myModel
delegate:Component {
//id: contactDelegate
Item {
property variant myData: model
width: 574; height: 90
Column {
x: 12
y: 0
width: 562
height: 90
anchors.rightMargin: 0
anchors.bottomMargin: 0
anchors.leftMargin: 12
anchors.topMargin: 0
anchors.fill: parent
spacing: 2
Text { text: '<b>ID: </b> ' + id_user ; verticalAlignment: Text.AlignTop; wrapMode: Text.NoWrap; horizontalAlignment: Text.AlignHCenter; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 10 }
Text { text: '<b>Name: </b> ' + user_name; horizontalAlignment: Text.AlignHCenter; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 10 }
Text { text: '<b>Lastname: </b> ' + user_lastname; horizontalAlignment: Text.AlignHCenter; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 10 }
Text { height: 16; text: '<b>Tel number: </b> ' + user_number; verticalAlignment: Text.AlignVCenter; horizontalAlignment: Text.AlignHCenter; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 10 }
Text { text: '<b>Address: </b> ' + user address; horizontalAlignment: Text.AlignHCenter; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 10 }
MouseArea {
id: mouse_area1
z: 1
hoverEnabled: false
anchors.fill: parent
onClicked:
Item
{
}
}
}
}
}
//delegate: contactDelegate
highlight: Rectangle
{
color:"black"
radius: 5
opacity: 0.7
focus: true
}
}
Пока выделение работает только при использовании стрелок, но это будет приложение для Android, поэтому мне нужно прикоснуться к тому же эффекту, и ВТОРОЙ вопрос - как прочитать определенные данные из выбранного элемента в списке? Внутри у меня есть идентификатор, имя, фамилия, номер и адрес. Я хочу поместить эти значения в поля text_input.
Спасибо
7 ответов
Ответ предоставлен user123_456: Вам необходимо добавить эту строку:
listview1.currentIndex = index
Похоже, вам нужно два решения вашего вопроса:
- Вы хотите иметь возможность установить текущий элемент
ListView
когда он нажал - Вы хотите знать, когда изменяется текущий выбор
Документация Qt5 говорит об этом ListView
управление мышью и сенсорным экраном:
Представления обрабатывают перетаскивание и перетаскивание своего содержимого, однако они не обрабатывают сенсорное взаимодействие с отдельными делегатами. Чтобы делегаты реагировали на сенсорный ввод, например, чтобы установить currentIndex, делегат должен предоставить MouseArea с соответствующей логикой обработки касания.
Клавишный ввод будет работать "из коробки", но вам нужно будет явно перехватить событие мыши / касания на делегате и изменить ListView.currentIndex
значение на основе index
значение выбранного элемента делегата.
Вот полный пример:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
width: 640
height: 480
visible: true
ListModel {
id: model
ListElement {
name:'abc'
number:'123'
}
ListElement {
name:'efg'
number:'456'
}
ListElement {
name:'xyz'
number:'789'
}
}
ListView {
id: list
anchors.fill: parent
model: model
delegate: Component {
Item {
width: parent.width
height: 40
Column {
Text { text: 'Name:' + name }
Text { text: 'Number:' + number }
}
MouseArea {
anchors.fill: parent
onClicked: list.currentIndex = index
}
}
}
highlight: Rectangle {
color: 'grey'
Text {
anchors.centerIn: parent
text: 'Hello ' + model.get(list.currentIndex).name
color: 'white'
}
}
focus: true
onCurrentItemChanged: console.log(model.get(list.currentIndex).name + ' selected')
}
}
Это делает следующие вещи:
- создает простой список и модель
- использует
MouseArea
элемент в делегате элемента для обновления установитеlist.currentIndex = index
который является локальной переменной и уникален для выбранного элемента - слушает
onCurrentItemChanged
событиеListView
чтобы показать, как получить доступ к значениям элемента текущей модели - привязывает текстовое значение выбранного в данный момент элемента к выделенному элементу, чтобы показать его, используя текущие выбранные значения в другом месте
ListView
обеспечивает так называемые " прикрепленные свойства", то есть свойства, доступные в delegate
для списка. Среди них Listview.view
это ссылка на сам список. Может использоваться для доступа currentIndex
свойство и обновить его. Следовательно, чтобы решить вашу проблему просто:
- Раскоментируйте
//id: contactDelegate
, - Задавать
contactDelegate.ListView.view.currentIndex = index
вOnClick
даже обработчик.
Самый простой, чем когда-либо, вы можете использовать: onCurrentItemChanged
ListView{
id: listViewMainMenu
signal Myselect(int playmode)
onCurrentItemChanged: Myselect(listViewMainMenu.currentIndex)
// ...
}
Для тех, кто использует подсветку в ListView с определенной высотой (не заполненной на 100%):
Обязательно включите свойство clip в ListView, так как в противном случае выделение будет по-прежнему видно за пределами границ ListView при прокрутке.
ListView
{
clip: true
}
Как обсуждено здесь: скрыть выделение ListView при прокрутке
Ответ действительноlistView.currentIndex = index
.
Играя с этим ответом, я обнаружил, что у него может не быть фокуса клавиатуры, поэтому я обнаружил, что может потребоваться позвонитьlistView.forceActiveFocus()
так что нажатия клавиш со стрелками вверх и вниз обрабатываются.
Я нашел делегата, особенно использованиеText
вListView
делегировать, чтобы быть подробным и громоздким. Чтобы убрать это, я провел рефакторингAppInfo
компонент для рендеринга контакта в приятной манере.
Чтобы отшлифовать ответ, я предоставил несколько примеров данных для контактов.ListModel
и почистил механизм подсветки:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
ListView {
id: listView
anchors.fill: parent
model: contacts
clip: true
focus: true
delegate: Item {
width: frame.width
height: frame.height
Frame {
id: frame
background: Item { }
ColumnLayout {
id: columnLayout
AppInfo { label: "ID"; value: id_user }
AppInfo { label: "Name"; value: user_name }
AppInfo { label: "Last Name"; value: user_lastname }
AppInfo { label: "Tel number"; value: user_number }
AppInfo { label: "Address"; value: user_address }
}
}
MouseArea {
anchors.fill: parent
onClicked: {
listView.currentIndex = index;
listView.forceActiveFocus();
}
}
}
highlight: Rectangle {
border.color: "black"
radius: 5
opacity: 0.7
focus: true
}
}
ListModel {
id: contacts
ListElement {
id_user: "bgates"
user_name: "Bill"
user_lastname: "Gates"
user_number: "555-Microsoft"
user_address: "1 Microsoft Way"
}
ListElement {
id_user: "sjobs"
user_name: "Steve"
user_lastname: "Jobs"
user_number: "555-Apple"
user_address: "1 Apple St"
}
ListElement {
id_user: "jbezos"
user_name: "Jeff"
user_lastname: "Bezos"
user_number: "555-Amazon"
user_address: "1 Amazon Ave"
}
}
}
//AppInfo.qml
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
RowLayout {
property string label: "ID"
property string value: "id"
Text {
Layout.preferredWidth: 100
text: label
verticalAlignment: Text.AlignTop
wrapMode: Text.NoWrap
horizontalAlignment: Text.AlignRight
color: "steelblue"
font.family: "Helvetica"
font.pointSize: 10
font.bold: true
}
Text {
Layout.preferredWidth: 100
text: value
verticalAlignment: Text.AlignTop
wrapMode: Text.NoWrap
horizontalAlignment: Text.AlignLeft
font.family: "Helvetica"
font.pointSize: 10
}
}
Вы можете попробовать это онлайн!
Начиная с Qt 5.7 существует ItemDelegate . По умолчанию реагирует на щелчки мыши.
import QtQuick
import QtQuick.Controls
ListView {
model: ListModel {
ListElement {
name: "Item 1"
}
ListElement {
name: "Item 2"
}
ListElement {
name: "Item 3"
}
}
delegate: ItemDelegate {
text: name
}
}