QT qml로 현재 시간 정보를 가져와 아날로그 시계로 보여주기
이번에는 qml로 현재시간 정보를 실시간으로 가져와 아날로그 시계로 표시하도록 구현해보겠습니다.
아날로그 시계를 만들기 위한 구성요소는 아래와 같은데, 하나 하나씩 만들어 보겠습니다.
1. 큰 원
2. 시간을 표시하는 12개의 작은 원
3. 시간을 표시하는 1~12까지의 숫자
4. 시계의 중앙에 위치한 원
5. 시침, 분침, 초침
6. 타이머를 이용한 현재 시간 정보를 가져오기
1. 큰 원(Rectangle)
원을 그리기 위해서는 Rectangle 을 사용합니다.
radius 속성에 원의 반지름 값을 넣어주면 원이 만들어 집니다.
Rectangle{
id: circle
anchors.centerIn: parent
height: Math.min(parent.width, parent.height)
width: height
radius: width/2
border.color: "black"
}
2. 시간을 표시하는 12개의 작은 원, 3. 시간을 표시하는 1~12까지의 숫자
12개를 반복적으로 수행하기 위해 Repeater를 사용합니다.
x: 정중앙, y:0으로 부터 시작하는데, height는 원의 지름으로 하여 30도씩 회전하면서 작은 원과 숫자를 표시합니다.
숫자는 0부터 시작하는데, 0이면 12를 표시하도록 하였습니다.
그런데, Item이 30도씩 회전하면서 숫자도 그에 맞게 회전하기 때문에, 기울이지 않고 똑바로 보이게 하려면 Text에서 rotation을 이용하여, 똑바로 보이게 합니다. Item의 rotation과 Text의 rotation의 합이 360이 되면 똑바로 보이겠죠?
Repeater{
model: 12
Item{
id: hourContainer
property int hour: index
height:circle.height
rotation: index*30
x: circle.width/2
y:0
Rectangle{
height: circle.height*0.05
width: height
radius: width/2
color: "black"
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
}
Text{
x: -15
y: circle.height*0.05
rotation: 360 - index*30
text: hourContainer.hour == 0 ?12 : hourContainer.hour
font.pixelSize: circle.height*0.05
}
}
}
4. 시계의 중앙에 위치한 원
이건 간단합니다.
height와 width는 최대한 작게 표시하도록 0.05를 곱하였고, radius에 반지름을 넣습니다.
그리고 anchors.centerIn에 parent를 넣어, 화면의 중앙에 표시하도록 하였습니다.
Rectangle{
id: center_rect
anchors.centerIn: parent
height: circle.height*0.05
width: height
radius: width/2
color: "black"
}
5. 시침, 분침, 초침
시침, 분침, 초침 모두 Rectangle로 긴 막대기처럼 표시하도록 만들었습니다.
여기서 중요한건 현재 시간에 따라 시침, 분침, 초침의 rotation을 설정하여, 회전하여 보여지도록 하는 것입니다.
transform을 이용하여, 큰 원의 중앙점을 기준으로 회전하도록 하였습니다.
초침과 분침은 은 분,초마다 360/60=6도씩 회전하도록 하였고,
시침은 360/12=30도씩 회전하도록 하고, 현재 분의 상태에 조금 움직여야 하기 때문에,
30*(minutes/60)로 움직이도록 하였습니다.
시침은 아래 식대로 현재 시에 30도를 곱한 값에 현재 분에 따른 추가 각도를 더하였습니다.
hourItem.value * hourItem.angle_hour + 30*(minutes/60)
Item{
id:hourItem
property int value: hours
property int angle_hour : 360/12
Rectangle{
width:6
x: window.height/2
y: circle.height * 0.21
height: window.height*0.35
color: "blue"
antialiasing: true
}
transform: Rotation
{
origin.x: window.height/2
origin.y: window.height/2
angle: hourItem.value * hourItem.angle_hour + 30*(minutes/60)
}
antialiasing: true
}
Item{
id:minuteItem
property int value: minutes
property int angle_minute : 360/60
Rectangle{
width:4
x: window.height/2
y:circle.height *0.12
height: window.height*0.45
color: "black"
antialiasing: true
}
transform: Rotation
{
origin.x: window.height/2
origin.y: window.height/2
angle: minuteItem.value * minuteItem.angle_minute
}
antialiasing: true
}
Item{
id:secondItem
property int value: seconds
property int angle_second: 360/60
Rectangle{
width:2
x: window.height/2
y:circle.height *0.08
height: window.height*0.5
color: "red"
antialiasing: true
}
transform: Rotation
{
origin.x: window.height/2
origin.y: window.height/2
angle: secondItem.value * secondItem.angle_second
}
antialiasing: true
}
6. 타이머를 이용한 현재 시간 정보를 가져오기
현재 시간을 가져오기 위해 Date() 객체를 이용하였습니다.
Timer로 1초가 지날때마다 현재 시간을 가져와 갱신하도록 하고, 로그로 남기도록 하였습니다.
이때, 시간, 분, 초에 대한 변수의 값은 시침, 분침, 초침이 보여질 부분에 대해 영향을 주게 됩니다
property date curentTime: new Date()
property int hour: curentTime.getHours()
property int minutes: curentTime.getMinutes()
property int seconds: curentTime.getSeconds()
Timer{
id: timer
repeat: true
interval: 1000
running: true
onTriggered: {
curentTime = new Date()
print(curentTime.getHours(), ":", curentTime.getMinutes(), ":", curentTime.getSeconds());
}
}
전체 코드
각각의 구성 요소들의 위치가 약간 안맞는 세세한 부분은 신경을 쓰지 않았습니다.
그점 양해부탁 드리고 봐주시면 될 듯 합니다.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
id: window
width: 500
height: 500
visible: true
property date curentTime: new Date()
property int hour: curentTime.getHours()
property int minutes: curentTime.getMinutes()
property int seconds: curentTime.getSeconds()
Rectangle{
id: circle
anchors.centerIn: parent
height: Math.min(parent.width, parent.height)
width: height
radius: width/2
border.color: "black"
}
Repeater{
model: 12
Item{
id: hourContainer
property int hour: index
height:circle.height
rotation: index*30
x: circle.width/2
y:0
Rectangle{
height: circle.height*0.05
width: height
radius: width/2
color: "black"
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
}
Text{
x: -15
y: circle.height*0.05
rotation: 360 - index*30
text: hourContainer.hour == 0 ?12 : hourContainer.hour
font.pixelSize: circle.height*0.05
}
}
}
Rectangle{
id: center_rect
anchors.centerIn: parent
height: circle.height*0.05
width: height
radius: width/2
color: "black"
}
Item{
id:hourItem
property int value: hours
property int angle_hour : 360/12
Rectangle{
width:6
x: window.height/2
y: circle.height * 0.21
height: window.height*0.35
color: "blue"
antialiasing: true
}
transform: Rotation
{
origin.x: window.height/2
origin.y: window.height/2
angle: hourItem.value * hourItem.angle_hour + 30*(minutes/60)
}
antialiasing: true
}
Item{
id:minuteItem
property int value: minutes
property int angle_minute : 360/60
Rectangle{
width:4
x: window.height/2
y:circle.height *0.12
height: window.height*0.45
color: "black"
antialiasing: true
}
transform: Rotation
{
origin.x: window.height/2
origin.y: window.height/2
angle: minuteItem.value * minuteItem.angle_minute
}
antialiasing: true
}
Item{
id:secondItem
property int value: seconds
property int angle_second: 360/60
Rectangle{
width:2
x: window.height/2
y:circle.height *0.08
height: window.height*0.5
color: "red"
antialiasing: true
}
transform: Rotation
{
origin.x: window.height/2
origin.y: window.height/2
angle: secondItem.value * secondItem.angle_second
}
antialiasing: true
}
Timer{
id: timer
repeat: true
interval: 1000
running: true
onTriggered: {
curentTime = new Date()
print(curentTime.getHours(), ":", curentTime.getMinutes(), ":", curentTime.getSeconds());
}
}
}
'프로그래밍 > QT_QML' 카테고리의 다른 글
QT qml의 slider를 이용해 Rectangle 색상 변경하기 (0) | 2020.07.30 |
---|---|
QT qml의 popup 표시하고 timer를 이용해 팝업 닫기 (0) | 2020.07.29 |
QT qml의 listview을 이용하여 간단한 리스트 표시하기 - hightlight 포함 (0) | 2020.07.28 |
QT qml의 TextField, Button을 이용한 Label 문구 업데이트 하기 (0) | 2020.07.25 |
QT - Widget, Console, Quick 프로젝트 생성하여 Hello world 출력하기 (0) | 2020.07.25 |