Qt — Есть ли способ запустить таймер раньше и передать аргумент в таймер

#qt #qml #qtquick2

#qt #qml #qtquick2

Вопрос:

Часть моего приложения (Weather.qml) в настоящее время выполняет HTTP-запрос GET для погоды каждые 5 минут, используя таймер и координаты GPS. У меня также есть пользовательские настройки (Settings.qml), которые позволяют пользователю выбирать местоположение.

Мне было интересно, можно ли запускать таймер всякий раз, когда изменяется настройка местоположения, и чтобы таймер принимал новые координаты для передачи в HTTP Get запрос.

На данный момент я просто передаю координату GPS в качестве аргумента ( weatherLocation ) исполняемому файлу при запуске.

Weather.qml

 WeatherForm {

    // A timer to refresh the forecast every 5 minutes
    Timer {
        interval: 300000
        repeat: true
        triggeredOnStart: true
        running: true
        onTriggered: {
            if (weatherAppKey != "" amp;amp; weatherLocation != "") {
                // Make HTTP GET request and parse the result
                var xhr = new XMLHttpRequest;
                xhr.open("GET",
                         "https://api.darksky.net/forecast/"
                           weatherAppKey   "/"
                           weatherLocation
                           "?exclude=[minutely,hourly,daily,alerts,flags]"
                           "amp;units=auto");
                xhr.onreadystatechange = function() {
                    if (xhr.readyState == XMLHttpRequest.DONE) {
                        var a = JSON.parse(xhr.responseText);
                        parseWeatherData(a);
                    }
                }
                xhr.send();
            } else {

                ...

            }
        }
    }

    ...

}
  

Settings.qml

 SettingsForm {

    Rectangle {

        ...

        ComboBox {
            id: cityComboBox
            anchors.right: parent.right
            anchors.verticalCenter: parent.Center
            model: ListModel {
                id: cbItems
                ListElement { city: "Vancouver"; coordinates: "49.2666,-123.1976" }
                ListElement { city: "New York"; coordinates: "40.7306,-73.9866" }
                ListElement { city: "Hong Kong"; coordinates: "22.2793,114.1628" }
            }
            textRole: 'city'

            // Trigger the Timer here possibly
            onCurrentIndexChanged: console.debug(cbItems.get(currentIndex).city)  
        }
    }
}
  

Ответ №1:

Это невозможно и не нужно. Просто укажите координаты в свойстве, где таймер может ссылаться на него. У вас есть прямой доступ ко всему, что находится в области действия файла (кроме делегатов).

Мне было интересно, можно ли запускать таймер всякий раз, когда изменяется настройка местоположения

Вы могли бы, но это противоречит цели наличия таймера — таймер запускается по истечении определенного интервала времени. Однако вы можете перезапустить и запустить таймер, после чего координаты изменятся:

 property string location : weatherLocation
...
onLocationChanged: timer.restart()
  

Просто измените код для использования location вместо weatherLocation . Вы можете изменить местоположение с помощью:

 onCurrentIndexChanged: location = cbItems.get(currentIndex).coordinates
  

Если вы создадите location свойство основного компонента qml, оно будет доступно напрямую из каждого объекта, вложенного (прямо или косвенно) в основной компонент (если он не затенен локальным свойством источника с идентичным именем).

Комментарии:

1. Спасибо. Я понял, что тоже решаю проблему в неправильном направлении. В итоге я разделил код HTTP GET на его собственную функцию в Weather. qml и использование подключений для вызова функции из Settings.qml. Помещение location переменной в мой основной компонент QML может быть более чистым, поэтому я также рассмотрю это.