上传代码

This commit is contained in:
lxbpxylps@126.com 2021-10-23 23:12:12 +08:00
parent 5ab0dcd29a
commit 7ade530466
26 changed files with 1364 additions and 0 deletions

7
.gitignore vendored
View File

@ -50,3 +50,10 @@ compile_commands.json
# QtCreator local machine specific files for imported projects
*creator.user*
# Gradle and Java
.gradle
.settings
# VSCode
.vscode

39
NodeRoid.pro Normal file
View File

@ -0,0 +1,39 @@
QT += core gui
QT += network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp \
notificationclient.cpp \
syncdata.cpp
HEADERS += \
mainwindow.h \
notificationclient.h \
syncdata.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
android/AndroidManifest.xml \
android/src/cc/akashic/noderoid/NotificationClient.java
contains(ANDROID_TARGET_ARCH,arm64-v8a) {
ANDROID_PACKAGE_SOURCE_DIR = \
$$PWD/android
}

28
android/.project Normal file
View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>android</name>
<comment>Project android created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1634916704863</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cc.akashic.noderoid" android:installLocation="auto" android:versionCode="-- %%INSERT_VERSION_CODE%% --" android:versionName="-- %%INSERT_VERSION_NAME%% --">
<!-- The comment below will be replaced with dependencies permissions upon deployment.
Remove the comment if you do not require these default permissions. -->
<!-- %%INSERT_PERMISSIONS -->
<!-- The comment below will be replaced with dependencies permissions upon deployment.
Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES -->
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" />
<application android:name="org.qtproject.qt.android.bindings.QtApplication" android:extractNativeLibs="true" android:hardwareAccelerated="true" android:label="NodeRoid" android:requestLegacyExternalStorage="true" android:icon="@drawable/icon">
<activity android:name="org.qtproject.qt.android.bindings.QtActivity" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:label="NodeRoid" android:launchMode="singleTop" android:screenOrientation="unspecified">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --" />
<meta-data android:name="android.app.background_running" android:value="false" />
<meta-data android:name="android.app.extract_android_style" android:value="none" />
</activity>
</application>
</manifest>

77
android/build.gradle Normal file
View File

@ -0,0 +1,77 @@
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.3'
}
}
repositories {
google()
jcenter()
}
apply plugin: 'com.android.application'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
android {
/*******************************************************
* The following variables:
* - androidBuildToolsVersion,
* - androidCompileSdkVersion
* - qt5AndroidDir - holds the path to qt android files
* needed to build any Qt application
* on Android.
*
* are defined in gradle.properties file. This file is
* updated by QtCreator and androiddeployqt tools.
* Changing them manually might break the compilation!
*******************************************************/
compileSdkVersion androidCompileSdkVersion.toInteger()
buildToolsVersion androidBuildToolsVersion
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
res.srcDirs = [qt5AndroidDir + '/res', 'res']
resources.srcDirs = ['resources']
renderscript.srcDirs = ['src']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
tasks.withType(JavaCompile) {
options.incremental = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
abortOnError false
}
// Do not compress Qt binary resources file
aaptOptions {
noCompress 'rcc'
}
defaultConfig {
resConfig "en"
minSdkVersion qtMinSdkVersion
targetSdkVersion qtTargetSdkVersion
}
}

11
android/gradle.properties Normal file
View File

@ -0,0 +1,11 @@
# Project-wide Gradle settings.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m
# Gradle caching allows reusing the build artifacts from a previous
# build with the same inputs. However, over time, the cache size will
# grow. Uncomment the following line to enable it.
#org.gradle.caching=true

Binary file not shown.

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
android/gradlew vendored Normal file
View File

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
android/gradlew.bat vendored Normal file
View File

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,20 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<!-- DO NOT EDIT THIS: This file is populated automatically by the deployment tool. -->
<array name="bundled_libs">
<!-- %%INSERT_EXTRA_LIBS%% -->
</array>
<array name="qt_libs">
<!-- %%INSERT_QT_LIBS%% -->
</array>
<array name="load_local_libs">
<!-- %%INSERT_LOCAL_LIBS%% -->
</array>
<string name="static_init_classes"><!-- %%INSERT_INIT_CLASSES%% --></string>
<string name="use_local_qt_libs"><!-- %%USE_LOCAL_QT_LIBS%% --></string>
<string name="bundle_local_qt_libs"><!-- %%BUNDLE_LOCAL_QT_LIBS%% --></string>
</resources>

View File

@ -0,0 +1,93 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
package cc.akashic.noderoid;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.BitmapFactory;
import android.app.NotificationChannel;
public class NotificationClient
{
public static void notify(Context context, String message) {
try {
NotificationManager m_notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder m_builder;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel notificationChannel;
notificationChannel = new NotificationChannel("NodeRoid", "NodeRoid Notifier", importance);
m_notificationManager.createNotificationChannel(notificationChannel);
m_builder = new Notification.Builder(context, notificationChannel.getId());
} else {
m_builder = new Notification.Builder(context);
}
Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
m_builder.setSmallIcon(R.drawable.icon)
.setLargeIcon(icon)
.setContentTitle("NodeRoid")
.setContentText(message)
.setDefaults(Notification.DEFAULT_SOUND)
.setColor(Color.GREEN)
.setAutoCancel(true);
m_notificationManager.notify(0, m_builder.build());
} catch (Exception e) {
e.printStackTrace();
}
}
}

18
main.cpp Normal file
View File

@ -0,0 +1,18 @@
/**
* @file main.cpp
* @author Myth
* @version 1.0
* @date 2021.10.23
*/
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

119
mainwindow.cpp Normal file
View File

@ -0,0 +1,119 @@
/**
* @file mainwindows.cpp
* @author Myth
* @version 1.0
* @date 2021.10.23
*/
#include "ui_mainwindow.h"
#include "notificationclient.h"
#include "syncdata.h"
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
syncdata = new SyncData(this);
connect(syncdata, SIGNAL(timeUpdated(QString)),
this, SLOT(dispUpdateTime(QString)));
connect(syncdata, SIGNAL(nodeDataUpdated(int, float, float, float)),
this, SLOT(dispNodeData(int, float, float, float)));
connect(syncdata, SIGNAL(nodeDataUpdated(int, float, float, float)),
this, SLOT(sendNodeWarn(int, float, float, float)));
temp_max = 27.0;
connect(this->ui->doubleSpinBox, SIGNAL(valueChanged(double)),
this, SLOT(updateTempMax(double)));
}
/**
* @brief
*/
void MainWindow::updateTempMax(double temp_value)
{
temp_max = temp_value;
}
/**
* @brief
*/
void MainWindow::dispNodeData(int seq, float humi, float temp, float light)
{
QString line_str;
line_str = "节点" +
QString::number(seq) +
" 湿度:" +
QString::number((double)humi) +
"% 温度:" +
QString::number((double)temp) +
"°C\n 光照度:" +
QString::number((double)light) +
"lx";
switch (seq)
{
case 2:
ui->label_node2->setText(line_str);
break;
case 3:
ui->label_node3->setText(line_str);
break;
case 4:
ui->label_node4->setText(line_str);
break;
case 5:
ui->label_node5->setText(line_str);
}
}
/**
* @brief
*/
void MainWindow::dispUpdateTime(QString time)
{
QString line_str;
line_str = "更新时间:" + time;
ui->label_time->setText(line_str);
}
/**
* @brief
*/
void MainWindow::sendNodeWarn(int seq, float humi, float temp, float light)
{
static bool is_first_run = true;
static QString last_warn_str;
if (is_first_run)
{
NotificationClient().setNotification("成功获取数据!");
is_first_run = false;
}
if (temp > temp_max)
{
QString warn_str = "节点" +
QString::number(seq) +
"温度过高:" +
QString::number((double)temp) +
"°C";
if (QString::compare(warn_str, last_warn_str) != 0)
{
NotificationClient().setNotification(warn_str);
last_warn_str.clear();
last_warn_str.append(warn_str);
}
}
}
MainWindow::~MainWindow()
{
delete ui;
delete syncdata;
}

41
mainwindow.h Normal file
View File

@ -0,0 +1,41 @@
/**
* @file mainwindows.h
* @author Myth
* @version 1.0
* @date 2021.10.23
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "syncdata.h"
QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
SyncData *syncdata;
double temp_max;
private slots:
void updateTempMax(double temp_value);
void dispNodeData(int seq, float humi, float temp, float light);
void dispUpdateTime(QString time);
void sendNodeWarn(int seq, float humi, float temp, float light);
};
#endif // MAINWINDOW_H

275
mainwindow.ui Normal file
View File

@ -0,0 +1,275 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1080</width>
<height>1920</height>
</rect>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label_title">
<property name="geometry">
<rect>
<x>10</x>
<y>0</y>
<width>351</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>30</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>NodeRoid v1.0</string>
</property>
</widget>
<widget class="Line" name="line_title">
<property name="geometry">
<rect>
<x>0</x>
<y>40</y>
<width>1081</width>
<height>16</height>
</rect>
</property>
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_node2">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>1071</width>
<height>101</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>25</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>等待中</string>
</property>
</widget>
<widget class="QLabel" name="label_node3">
<property name="geometry">
<rect>
<x>10</x>
<y>160</y>
<width>1071</width>
<height>101</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>25</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>等待中</string>
</property>
</widget>
<widget class="QLabel" name="label_node4">
<property name="geometry">
<rect>
<x>10</x>
<y>260</y>
<width>1071</width>
<height>101</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>25</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>等待中</string>
</property>
</widget>
<widget class="QLabel" name="label_node5">
<property name="geometry">
<rect>
<x>10</x>
<y>360</y>
<width>1071</width>
<height>101</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>25</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>等待中</string>
</property>
</widget>
<widget class="QLabel" name="label_time">
<property name="geometry">
<rect>
<x>10</x>
<y>460</y>
<width>1071</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>25</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>等待中</string>
</property>
</widget>
<widget class="QDoubleSpinBox" name="doubleSpinBox">
<property name="geometry">
<rect>
<x>90</x>
<y>550</y>
<width>231</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>25</pointsize>
</font>
</property>
<property name="minimum">
<double>-100.000000000000000</double>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="value">
<double>27.000000000000000</double>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1080</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

90
notificationclient.cpp Normal file
View File

@ -0,0 +1,90 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "notificationclient.h"
#include <QtCore/qjniobject.h>
#include <QtCore/qcoreapplication.h>
NotificationClient::NotificationClient(QObject *parent)
: QObject(parent)
{
connect(this, &NotificationClient::notificationChanged,
this, &NotificationClient::updateAndroidNotification);
}
void NotificationClient::setNotification(const QString &notification)
{
if (m_notification == notification)
return;
//! [notification changed signal]
m_notification = notification;
emit notificationChanged();
//! [notification changed signal]
}
QString NotificationClient::notification() const
{
return m_notification;
}
//! [Send notification message to Java]
void NotificationClient::updateAndroidNotification()
{
QJniObject javaNotification = QJniObject::fromString(m_notification);
QJniObject::callStaticMethod<void>(
"cc/akashic/noderoid/NotificationClient",
"notify",
"(Landroid/content/Context;Ljava/lang/String;)V",
QNativeInterface::QAndroidApplication::context(),
javaNotification.object<jstring>());
}
//! [Send notification message to Java]

76
notificationclient.h Normal file
View File

@ -0,0 +1,76 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef NOTIFICATIONCLIENT_H
#define NOTIFICATIONCLIENT_H
#include <QObject>
//! [Qt Notification Class]
class NotificationClient : public QObject
{
Q_OBJECT
public:
explicit NotificationClient(QObject *parent = 0);
void setNotification(const QString &notification);
QString notification() const;
signals:
void notificationChanged();
private slots:
void updateAndroidNotification();
private:
QString m_notification;
};
//! [Qt Notification Class]
#endif // NOTIFICATIONCLIENT_H

132
syncdata.cpp Normal file
View File

@ -0,0 +1,132 @@
/**
* @file syncdata.cpp
* @author Myth
* @version 1.0
* @date 2021.10.23
*/
#include <QByteArray>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonValue>
#include "syncdata.h"
//数据源链接,数据由其他程序生成
#define DATA_URL "http://node.akashic.cc/data.json"
//每 100ms 更新一次数据
#define UPDATE_INTERVAL 100
SyncData::SyncData(QObject *parent) : QObject(parent)
{
data_manager = new QNetworkAccessManager(this);
//每次请求返回结果后调用槽函数 dataReplyFinished
connect(data_manager, SIGNAL(finished(QNetworkReply *)),
this, SLOT(dataReplyFinished(QNetworkReply *)));
timer = new QTimer(this);
//定时器触发后调用槽函数 updateNodeData
connect(timer, SIGNAL(timeout()),
this, SLOT(updateNodeData()));
timer->start(UPDATE_INTERVAL);
}
/**
* @brief
*/
void SyncData::updateNodeData(void)
{
data_manager->get(QNetworkRequest(QUrl(DATA_URL)));
}
/**
* @brief
*/
void SyncData::dataReplyFinished(QNetworkReply *reply)
{
QNetworkReply::NetworkError networkerror = reply->error();
if (networkerror == QNetworkReply::NoError)
{
// JSON 解析
QByteArray databuff = reply->readAll();
QString result = QString::fromStdString(databuff.toStdString()).toUtf8();
QJsonDocument document;
QJsonParseError parseerror;
document = QJsonDocument::fromJson(result.toUtf8(), &parseerror);
QString time;
double humi;
double temp;
double light;
if (!document.isNull() && parseerror.error == QJsonParseError::NoError)
{
if (document.isObject())
{
QJsonObject Object = document.object();
if (!Object.isEmpty())
{
if (Object.contains("time"))
{
QJsonValue time_val = Object.value("time");
if (time_val.isString())
{
time = time_val.toString();
emit timeUpdated(time); //信号:时间更新
}
}
//遍历 2 ~ 5 节点数据
for (int seq = 2; seq <= 5; seq++)
{
if (Object.contains("node" + QString::number(seq)))
{
QJsonValue dataObj = Object.value("node" + QString::number(seq));
if (dataObj.isObject())
{
QJsonObject ObjectData = dataObj.toObject();
if (ObjectData.contains("humi"))
{
QJsonValue humi_val = ObjectData.value("humi");
if (humi_val.isDouble())
{
humi = humi_val.toDouble();
}
}
if (ObjectData.contains("temp"))
{
QJsonValue temp_val = ObjectData.value("temp");
if (temp_val.isDouble())
{
temp = temp_val.toDouble();
}
}
if (ObjectData.contains("light"))
{
QJsonValue light_val = ObjectData.value("light");
if (light_val.isDouble())
{
light = light_val.toDouble();
}
}
emit nodeDataUpdated(seq, humi, temp, light); //信号:数据更新
}
}
}
}
}
}
}
}
SyncData::~SyncData()
{
delete data_manager;
delete timer;
}

36
syncdata.h Normal file
View File

@ -0,0 +1,36 @@
/**
* @file syncdata.h
* @author Myth
* @version 1.0
* @date 2021.10.23
*/
#ifndef SYNCDATA_H
#define SYNCDATA_H
#include <QObject>
#include <QtNetwork>
#include <QTimer>
class SyncData : public QObject
{
Q_OBJECT
public:
SyncData(QObject *parent = nullptr);
~SyncData();
private:
QNetworkAccessManager *data_manager;
QTimer *timer;
signals:
void timeUpdated(QString time);
void nodeDataUpdated(int seq, float humi, float temp, float light);
private slots:
void updateNodeData(void);
void dataReplyFinished(QNetworkReply *reply);
};
#endif // SYNCDATA_H