Od Qt 5.5 tak zwana Qt Quick Enterprise Controls będzie dostępna również w edycji wspólnotowej Qt pod nazwą Qt Quick Extras. Między innymi, Tumbler
wydaje się być wykonalnym rozwiązaniem dla twoich wymagań: możesz łatwo ustawić dwie kolumny, jedną dla godzin i jedną dla minut.
Jeśli nadal jesteś zainteresowany kołowego wyboru (lub chce zaimplementować własną szklankę) można podjąć różne trasy, takie jak stworzyć własny element dziedziczy z QQuickItem
lub QQuickPaintedItem
lub wykorzystywanie niestandardowego widoku z PathView
. Ta ostatnia sytuacja ma miejsce w tej odpowiedzi. Wystarczy zapoznać się z zamieszczonymi linkami w celu uzyskania przykładów tworzenia niestandardowych komponentów.
Powołując dokumentację PathView
:
Widok ma modelu, który definiuje dane mają być wyświetlane i delegata, który określa w jaki sposób dane powinny być wyświetlane. Delegat tworzy instancję dla każdego elementu na ścieżce. Elementy można przesuwać, przesuwając wzdłuż ścieżki.
W związku z tym ścieżka określa sposób układania przedmiotów na ekranie, nawet w cykliczny sposób. Ścieżka może być zbudowana za pomocą typu Path
, tj. Sekwencji segmentów ścieżki różnego rodzaju. PathArc
to ten, który nas interesuje, ponieważ zapewnia pożądany zaokrąglony kształt.
Następujący przykład wykorzystuje te elementy do zdefiniowania kołowego selektora czasu. Każda ścieżka jest konstruowana przez wykorzystanie elementu currentIndex
elementu delegowanego: liczba całkowita jest używana jako model dla widoku godzinowego i 6
dla widoku minut. Tekst delegatów generowany jest przez wykorzystanie załączonej właściwości i manipulowanie nią w celu wygenerowania godzin i 10-minutowych wartości interwałów (patrz elementy delegatów: Text
). Na koniec tekst bieżącego elementu (tj. currentItem
) jest powiązany z etykietą czasu w środku okna: wraz ze zmianą currentIndex
i currentItem
również etykieta jest aktualizowana.
Ogólnym komponent wygląda następująco:

highlight
składniki (niebieskie i zielone kółka) są wykorzystywane do graficznie reprezentujących edycji po raz: gdy widoczny czas może być edytowany, czyli kolejna Item
od ścieżka może być wybrana. Przełączanie między trybem normalnym a trybem edycji następuje po kliknięciu etykiety czasu w środku.
W trybie edycji użytkownik może po prostu najechać kursorem na różne wartości godzin/minut, aby je wybrać. Jeśli kliknięta zostanie nowo wybrana godzina/minuta, edycja dla tego konkretnego PathView
jest wyłączona i odpowiedni krąg podświetlenia znika.
Ten kod jest oczywiście tylko zabawnym przykładem, który daje pojęcie o tym, do czego można użyć PathView
. Można wprowadzić kilka ulepszeń, np. animacje, lepsze pozycjonowanie liczb, szczegółowa reprezentacja minut, ładne tło i tak dalej. Są one jednak poza zakresem w.r.t. pytanie i nie zostały uwzględnione.
import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls.Styles 1.3
import QtQuick.Layouts 1.1
Window {
visible: true
width: 280; height: 280
RowLayout { // centre time label
anchors.centerIn: parent
Text {
id: h
font.pixelSize: 30
font.bold: true
text: outer.currentItem.text
}
Text {
id: div
font.pixelSize: 30
font.bold: true
text: qsTr(":")
}
Text {
id: m
font.pixelSize: 30
font.bold: true
text: inner.currentItem.text
}
MouseArea {
anchors.fill: parent
onClicked: outer.choiceActive = inner.choiceActive = !outer.choiceActive
}
}
PathView { // hours path
id: outer
property bool pressed: false
model: 12
interactive: false
highlightRangeMode: PathView.NoHighlightRange
property bool choiceActive: false
highlight: Rectangle {
id: rect
width: 30 * 1.5
height: width
radius: width/2
border.color: "darkgray"
color: "steelblue"
visible: outer.choiceActive
}
delegate: Item {
id: del
width: 30
height: 30
property bool currentItem: PathView.view.currentIndex == index
property alias text : textHou.text
Text {
id: textHou
anchors.centerIn: parent
font.pixelSize: 24
font.bold: currentItem
text: index + 1
color: currentItem ? "black" : "gray"
}
MouseArea {
anchors.fill: parent
enabled: outer.choiceActive
onClicked: outer.choiceActive = false
hoverEnabled: true
onEntered: outer.currentIndex = index
}
}
path: Path {
startX: 200; startY: 40
PathArc {
x: 80; y: 240
radiusX: 110; radiusY: 110
useLargeArc: false
}
PathArc {
x: 200; y: 40
radiusX: 110; radiusY: 110
useLargeArc: false
}
}
}
PathView { // minutes path
id: inner
property bool pressed: false
model: 6
interactive: false
highlightRangeMode: PathView.NoHighlightRange
property bool choiceActive: false
highlight: Rectangle {
width: 30 * 1.5
height: width
radius: width/2
border.color: "darkgray"
color: "lightgreen"
visible: inner.choiceActive
}
delegate: Item {
width: 30
height: 30
property bool currentItem: PathView.view.currentIndex == index
property alias text : textMin.text
Text {
id: textMin
anchors.centerIn: parent
font.pixelSize: 24
font.bold: currentItem
text: index * 10
color: currentItem ? "black" : "gray"
}
MouseArea {
anchors.fill: parent
enabled: inner.choiceActive
onClicked: inner.choiceActive = false
hoverEnabled: true
onEntered: inner.currentIndex = index
}
}
path: Path {
startX: 140; startY: 60
PathArc {
x: 140; y: 220
radiusX: 40; radiusY: 40
useLargeArc: false
}
PathArc {
x: 140; y: 60
radiusX: 40; radiusY: 40
useLargeArc: false
}
}
}
// to set current time!
onVisibleChanged: {
var d = new Date();
outer.currentIndex = d.getUTCHours() % 12
inner.currentIndex = d.getMinutes()/10
}
}
Dobra odpowiedź :-) –
Dziękuję bardzo za kompleksową odpowiedź. Jak tylko będę mógł to zweryfikować, zaakceptuję to. –
Nie martw się. :) Starałem się być w zasięgu z odpowiedzią i przedstawiłem kilka zaleceń bardziej niż gotowe do użycia rozwiązanie. Jeśli masz ochotę na integrację z treścią, poproś o nią. – BaCaRoZzo