2014-09-12 32 views
12

Deliriyorum. ScrollView içinde bir ListView var, QAbstractListModel devralan bir modele bağladım. Nesne modele eklendiğinde, ListView bir temsilci kullanarak bunları gösterir. Çok uzak çok iyi.QML ListView yöntem positionViewAtEnd() tam olarak tersi yapar

Ama gerçekten görünümü (sohbet penceresinin gibi) altına kaydırılacağı halde kalmasını istiyorsanız, ve bunun olmasına yapma çok zor zamanlar geçiriyorum. ,

Rectangle { 
    ScrollView { 
     [anchor stuff] 

     ListView { 
      id: messageList 
      model: textMessageFiltered 
      delegate: messageDelegate 
     } 
    } 

    TextField { 
     id: messageEditor 
     [anchor stuff] 

     onAccepted: { 
      controller.sendTextMessage(text) 
      text = "" 

      /* This works. */ 
      //messageList.positionViewAtEnd(); 
     } 
    } 

    Component { 
     id: messageDelegate 
     Rectangle { 
      anchors.left: parent.left 
      anchors.right: parent.right 

      color: "white" 
      height: nameText.height + 4 

      Text { 
       id: nameText 
       wrapMode: Text.Wrap 
       text: "<b>" + authorName + " (" + authorId + ")</b> " + message 
       [anchor stuff] 
      } 
      ListView.onAdd: { 
       console.log("This prints just fine!") 
       messageList.positionViewAtEnd() 
      } 
     } 
    } 
} 

gerçekten garip bir şey messageList.positionViewAtEnd() (dosyanın sonunda) aslında başından onu atlar şudur: Burada, ilgili QML kodudur. Arama olmadan, listede yeni girişler görünse bile görünüm nerede kalır. Eğer Qt documentation for the ListView.positionViewAtEnd() bakarsak Gerçekten de, diyor: de

Pozisyonlar görünümü başlayan veya sona dikkate alarak ...

Bu bir aptal hata içinde belgeler, ya da ne? Bu çalışmayı yapmak için düşünebildiğim her şeyi, özellikle de positionViewAtIndex() yöntemini denedim ve kaydırma işleminin gerçekleşmesini zorlamak için vurgulayıcıları kullanıyorum. Ama hiçbir şey işe yaramıyor. Yukarıdaki kaynak kodunda bulunan /* This works. */ yorumuna dikkat edin. Bu etkin olduğunda, tamamen iyi çalışıyor!

kimse burada yanlış olabilir bir fikrin var mı - (yerine listenin sonu, 2 indeksi elbette hariç, bu ListView.count() atlar)? Herhangi bir örnekte, QML'de korkunç, korkunç bir hata olduğunu kanıtlamaya çalışabilir miyim?

Ben QtQuick 2.0 ile Qt 5.3.1 kullanıyorum (veya 2.1 veya 2.2 de başarısız). Birçok diğer yapılandırmayı ve kodu da denedim, bu yüzden daha fazla bilgiye ihtiyacınız olup olmadığını sorun. Google-fu'mı tamamen tükettim.

Teşekkürler! Kabul yanıt yukarıda sorunu çözmek yok iken


düzenleme 1

, bu temsilciye Component.onCompleted eklenmektedir. Bu, listeyi kaydırdığınızda sorunlara neden oluyor, çünkü (ben inanıyorum) delege, yukarı kaydırdığınızda görünümüne eklenir, model öğesi yeni olmasa bile onCompleted tetikleyicinin çağrılmasına neden olur. Bu çok istenmeyen bir durumdur. Aslında, yukarı kaydırmaya çalıştığımda ve listeye yeni öğeler eklediğinde uygulama donuyor. Ben kaydırma tetiklemek için bir temsilci örneği varlığını kullanmak yerine bir model.onAdd() sinyali gerekiyor gibi

görünüyor. Herhangi bir fikir?


Düzenleme 2

Ve nasıl olacak bu iş DEĞİLDİR?

ListView { 
     id: messageList 
     model: textMessageFiltered 
     delegate: messageDelegate 

     onCountChanged: { 
      console.log("This prints properly.") 
      messageList.positionViewAtEnd() 
     } 
    } 

"Bu doğru yazdırılıyor" metni yazdırılıyor, bu yüzden neden konumu yok? Aslında, konumu en üste sıfırlar. Bu yüzden positionViewAtBeginning()'u denedim, ama aynı şeyi yaptı.

Tamamen stumped. Bir böcek gibi hissettiriyor.

+0

? Bu benim için Ubuntu üzerinde Qt 5.4 kullanarak çalışır (görebildiğim kadarıyla değil, doğru sayılır - 2). Kaydırma ve onCountChanged çalışmadığında ortaya çıkan asmak için lütfen bir hata raporu oluşturun. – Mitch

+1

sorun üzerinde (öğe anında (gerçek öğe bir sunucu isteğinden eklenir) listesine eklenir değildir ve bu nedenle bu ya biri olarak kapalıdır (gönderici üzerine) veya hiç güncelleme olmamasıdır diğer müşteri). PositionViewAtBeginning() '_must_, güncellenmekte olan listenin üzerinde hareket eder. Kötü bir hata isteği gönderdim (QTBUG-41571), bu yüzden bu gönderi sorunu açıklığa kavuşturmak için yeterlidir. – jmbeck

+0

Sorunu çözmeyi başardınız mı? Tam problemim var ve herhangi bir çözüm bulamıyorum. Teşekkürler! –

cevap

5

documentation bir not var:

Not: Bileşen tamamlandıktan sonra yöntemleri yalnızca çağrılmalıdır. Görünümü başlangıçta konumlandırmak için, bu yöntem Component.onCompleted tarafından çağrılmalıdır.

değiştirme

senin ListView.onAdd:

Component.onCompleted: { 
    console.log("This prints just fine!") 
    messageList.positionViewAtEnd() 
} 

için Ve iyi çalışıyor. Yeni temsilci oluşturulan ve tamamlanmadan önce durumda

, ListView add sinyal yayar. ListView hala sahne arkasında bir şey üzerinde çalışıyor, bu yüzden positionViewAtEnd beklendiği gibi çalışamaz. Ve /* This works. */ çünkü yeni delege tamamlandıktan sonra çağrılır. Ancak, bunun her zaman işe yarayacağını varsayalım. Notu takip ederek, Component.onCompleted numaralı telefondan positionViewAtEnd belgesini arayın.

+0

Siz haktasınız. Teşekkür ederim. Gelecekteki Google'cuların için, bu ikinci önemli parçası Component.onCompleted' * temsilci yer alması gerekir 'olmasıdır *, ** değil ** listesinde kendisi. Onu özledim. – jmbeck

+0

Uh oh. Kaydırma konusunda sorun yaşıyorum. İlk düzenlememe bak. – jmbeck

+0

Hmm ... haklısınız. Listeyi kaydırdığınızda ListView yeni delegeler oluşturur ve cevabım başarısız olur. Belki 'positionViewAtEnd' çağırmadan önce modeldeki elemanların sayısını kontrol edebilirsiniz, ancak bunun iyi bir çözüm olduğunu düşünmüyorum. Qt geliştiricileri gerçekten takmak gerekiyordu eğer/'delegesinecevap onCompleted' neden – mcchu

3

Siz de currentIndex ayarlamanız gerekir.

testme.qml

import QtQuick 2.2 
import QtQuick.Controls 1.1 
import QtQuick.Window 2.0 

ApplicationWindow { 
    title: qsTr("Hello World") 
    width: 300 
    height: 240 

    ScrollView { 
     anchors.fill: parent 

     ListView { 
      anchors.fill: parent 

      id: messageList 
      model: messageModel 
      delegate: Text { text: mytextrole } 
      highlight: Rectangle { color: "red" } 
      highlightMoveDuration: 0 

      onCountChanged: { 
       var newIndex = count - 1 // last index 
       positionViewAtEnd() 
       currentIndex = newIndex 
      } 
     } 
    } 

    ListModel { 
     id: messageModel 
     ListElement { mytextrole: "Dog"; } 
     ListElement { mytextrole: "Cat"; } 
    } 

    Timer { 
     property int counter: 0 
     running: true 
     interval: 500 
     repeat: true 

     onTriggered: { 
      messageModel.append({"mytextrole": "Line" + (counter++)}) 
     } 
    } 
} 

Orada ilk elemana bazı atlama hala ve saniyenin bir kısmıyla aşağı geri atlama.

senin çözüm yorumladı nesi var
+0

İlginç. Belki de bu Qt'deki hatanın kaynağıdır. – jmbeck