v3 first commit
This commit is contained in:
parent
10e6c3be04
commit
f7941a4a5b
@ -1,2 +0,0 @@
|
|||||||
[build]
|
|
||||||
target = "x86_64-pc-windows-gnu"
|
|
27
CMakeLists.txt
Executable file
27
CMakeLists.txt
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.21)
|
||||||
|
project(untitled)
|
||||||
|
set(CMAKE_PREFIX_PATH "C:\\Programs\\Qt\\6.2.4\\msvc2019_64")
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
|
#OPTION(USE ntddmodm ON)
|
||||||
|
find_package(Qt6 COMPONENTS
|
||||||
|
Core
|
||||||
|
Gui
|
||||||
|
Widgets
|
||||||
|
SerialPort
|
||||||
|
Charts
|
||||||
|
REQUIRED)
|
||||||
|
|
||||||
|
add_executable(untitled main.cpp main_window.cpp main_window.h)
|
||||||
|
#add_executable(untitled WIN32 main.cpp main_window.cpp main_window.h)
|
||||||
|
target_link_libraries(untitled
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Widgets
|
||||||
|
Qt::Charts
|
||||||
|
Qt6::SerialPort
|
||||||
|
)
|
||||||
|
|
817
Cargo.lock
generated
817
Cargo.lock
generated
@ -1,817 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "CoreFoundation-sys"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"mach 0.1.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "IOKit-sys"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a"
|
|
||||||
dependencies = [
|
|
||||||
"CoreFoundation-sys",
|
|
||||||
"libc",
|
|
||||||
"mach 0.1.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "0.7.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anyhow"
|
|
||||||
version = "1.0.44"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "atk"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a83b21d2aa75e464db56225e1bda2dd5993311ba1095acaa8fa03d1ae67026ba"
|
|
||||||
dependencies = [
|
|
||||||
"atk-sys",
|
|
||||||
"bitflags",
|
|
||||||
"glib",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "atk-sys"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "badcf670157c84bb8b1cf6b5f70b650fed78da2033c9eed84c4e49b11cbe83ea"
|
|
||||||
dependencies = [
|
|
||||||
"glib-sys",
|
|
||||||
"gobject-sys",
|
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitflags"
|
|
||||||
version = "1.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cairo-rs"
|
|
||||||
version = "0.14.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9164355c892b026d6257e696dde5f3cb39beb3718297f0f161b562fe2ee3ab86"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cairo-sys-rs",
|
|
||||||
"glib",
|
|
||||||
"libc",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cairo-sys-rs"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80"
|
|
||||||
dependencies = [
|
|
||||||
"glib-sys",
|
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.0.70"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-expr"
|
|
||||||
version = "0.8.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e"
|
|
||||||
dependencies = [
|
|
||||||
"smallvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "0.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "closure"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d6173fd61b610d15a7566dd7b7620775627441c4ab9dac8906e17cb93a24b782"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "either"
|
|
||||||
version = "1.6.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "field-offset"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92"
|
|
||||||
dependencies = [
|
|
||||||
"memoffset",
|
|
||||||
"rustc_version",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-channel"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888"
|
|
||||||
dependencies = [
|
|
||||||
"futures-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-core"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-executor"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c"
|
|
||||||
dependencies = [
|
|
||||||
"futures-core",
|
|
||||||
"futures-task",
|
|
||||||
"futures-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-io"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-task"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-util"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"futures-core",
|
|
||||||
"futures-task",
|
|
||||||
"pin-project-lite",
|
|
||||||
"pin-utils",
|
|
||||||
"slab",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gdk"
|
|
||||||
version = "0.14.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a453eae5ec10345b3a96ca1b547328bfc94edd40aa95b08f14bb4c35863db140"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cairo-rs",
|
|
||||||
"gdk-pixbuf",
|
|
||||||
"gdk-sys",
|
|
||||||
"gio",
|
|
||||||
"glib",
|
|
||||||
"libc",
|
|
||||||
"pango",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gdk-pixbuf"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "534192cb8f01daeb8fab2c8d4baa8f9aae5b7a39130525779f5c2608e235b10f"
|
|
||||||
dependencies = [
|
|
||||||
"gdk-pixbuf-sys",
|
|
||||||
"gio",
|
|
||||||
"glib",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gdk-pixbuf-sys"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590"
|
|
||||||
dependencies = [
|
|
||||||
"gio-sys",
|
|
||||||
"glib-sys",
|
|
||||||
"gobject-sys",
|
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gdk-sys"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0e091b3d3d6696949ac3b3fb3c62090e5bfd7bd6850bef5c3c5ea701de1b1f1e"
|
|
||||||
dependencies = [
|
|
||||||
"cairo-sys-rs",
|
|
||||||
"gdk-pixbuf-sys",
|
|
||||||
"gio-sys",
|
|
||||||
"glib-sys",
|
|
||||||
"gobject-sys",
|
|
||||||
"libc",
|
|
||||||
"pango-sys",
|
|
||||||
"pkg-config",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gio"
|
|
||||||
version = "0.14.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f3a29d8062af72045518271a2cd98b4e1617ce43f5b4223ad0fb9a0eff8f718c"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
|
||||||
"futures-io",
|
|
||||||
"gio-sys",
|
|
||||||
"glib",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gio-sys"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa"
|
|
||||||
dependencies = [
|
|
||||||
"glib-sys",
|
|
||||||
"gobject-sys",
|
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "glib"
|
|
||||||
version = "0.14.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d4a930b7208e6e0ab839eea5f65ac2b82109f729621430d47fe905e2e09d33f4"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
|
||||||
"futures-executor",
|
|
||||||
"futures-task",
|
|
||||||
"glib-macros",
|
|
||||||
"glib-sys",
|
|
||||||
"gobject-sys",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"smallvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "glib-macros"
|
|
||||||
version = "0.14.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2aad66361f66796bfc73f530c51ef123970eb895ffba991a234fcf7bea89e518"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"heck",
|
|
||||||
"proc-macro-crate",
|
|
||||||
"proc-macro-error",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "glib-sys"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gobject-sys"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5"
|
|
||||||
dependencies = [
|
|
||||||
"glib-sys",
|
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gtk"
|
|
||||||
version = "0.14.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6603bb79ded6ac6f3bac203794383afa8b1d6a8656d34a93a88f0b22826cd46c"
|
|
||||||
dependencies = [
|
|
||||||
"atk",
|
|
||||||
"bitflags",
|
|
||||||
"cairo-rs",
|
|
||||||
"field-offset",
|
|
||||||
"futures-channel",
|
|
||||||
"gdk",
|
|
||||||
"gdk-pixbuf",
|
|
||||||
"gio",
|
|
||||||
"glib",
|
|
||||||
"gtk-sys",
|
|
||||||
"gtk3-macros",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"pango",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gtk-sys"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8c14c8d3da0545785a7c5a120345b3abb534010fb8ae0f2ef3f47c027fba303e"
|
|
||||||
dependencies = [
|
|
||||||
"atk-sys",
|
|
||||||
"cairo-sys-rs",
|
|
||||||
"gdk-pixbuf-sys",
|
|
||||||
"gdk-sys",
|
|
||||||
"gio-sys",
|
|
||||||
"glib-sys",
|
|
||||||
"gobject-sys",
|
|
||||||
"libc",
|
|
||||||
"pango-sys",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gtk3-macros"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "21de1da96dc117443fb03c2e270b2d34b7de98d0a79a19bbb689476173745b79"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"heck",
|
|
||||||
"proc-macro-crate",
|
|
||||||
"proc-macro-error",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "heck"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-segmentation",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "itertools"
|
|
||||||
version = "0.10.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
|
|
||||||
dependencies = [
|
|
||||||
"either",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.103"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libudev"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"libudev-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libudev-sys"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mach"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mach"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memoffset"
|
|
||||||
version = "0.6.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nix"
|
|
||||||
version = "0.16.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cc",
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"void",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "once_cell"
|
|
||||||
version = "1.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pango"
|
|
||||||
version = "0.14.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e1fc88307d9797976ea62722ff2ec5de3fae279c6e20100ed3f49ca1a4bf3f96"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"glib",
|
|
||||||
"libc",
|
|
||||||
"once_cell",
|
|
||||||
"pango-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pango-sys"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe"
|
|
||||||
dependencies = [
|
|
||||||
"glib-sys",
|
|
||||||
"gobject-sys",
|
|
||||||
"libc",
|
|
||||||
"system-deps",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pest"
|
|
||||||
version = "2.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
|
||||||
dependencies = [
|
|
||||||
"ucd-trie",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-project-lite"
|
|
||||||
version = "0.2.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-utils"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.20"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-crate"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror",
|
|
||||||
"toml",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro-error-attr",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error-attr"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro2"
|
|
||||||
version = "1.0.29"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-xid",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quote"
|
|
||||||
version = "1.0.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "1.5.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.6.25"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc_version"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
|
|
||||||
dependencies = [
|
|
||||||
"semver",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver"
|
|
||||||
version = "0.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
|
||||||
dependencies = [
|
|
||||||
"semver-parser",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "semver-parser"
|
|
||||||
version = "0.10.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
|
|
||||||
dependencies = [
|
|
||||||
"pest",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde"
|
|
||||||
version = "1.0.130"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serial_communication_tool_v2"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"closure",
|
|
||||||
"gio",
|
|
||||||
"glib",
|
|
||||||
"gtk",
|
|
||||||
"serialport",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serialport"
|
|
||||||
version = "4.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5d8cd7c0f22290ee2c01457009fa6fc1cae4153d5608a924e5dc423babc2c655"
|
|
||||||
dependencies = [
|
|
||||||
"CoreFoundation-sys",
|
|
||||||
"IOKit-sys",
|
|
||||||
"bitflags",
|
|
||||||
"cfg-if",
|
|
||||||
"libudev",
|
|
||||||
"mach 0.2.3",
|
|
||||||
"nix",
|
|
||||||
"regex",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "slab"
|
|
||||||
version = "0.4.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smallvec"
|
|
||||||
version = "1.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strum"
|
|
||||||
version = "0.21.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strum_macros"
|
|
||||||
version = "0.21.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec"
|
|
||||||
dependencies = [
|
|
||||||
"heck",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "syn"
|
|
||||||
version = "1.0.77"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"unicode-xid",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "system-deps"
|
|
||||||
version = "3.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"cfg-expr",
|
|
||||||
"heck",
|
|
||||||
"itertools",
|
|
||||||
"pkg-config",
|
|
||||||
"strum",
|
|
||||||
"strum_macros",
|
|
||||||
"thiserror",
|
|
||||||
"toml",
|
|
||||||
"version-compare",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror"
|
|
||||||
version = "1.0.29"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror-impl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror-impl"
|
|
||||||
version = "1.0.29"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "toml"
|
|
||||||
version = "0.5.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
|
||||||
dependencies = [
|
|
||||||
"serde",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ucd-trie"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-segmentation"
|
|
||||||
version = "1.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-xid"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version-compare"
|
|
||||||
version = "0.0.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "void"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-i686-pc-windows-gnu",
|
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
31
Cargo.toml
31
Cargo.toml
@ -1,31 +0,0 @@
|
|||||||
cargo-features=["strip"]
|
|
||||||
[package]
|
|
||||||
name = "serial_communication_tool_v2"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
gtk = "0.14.1"
|
|
||||||
gio = "0.14.6"
|
|
||||||
glib = "0.14.5"
|
|
||||||
#pretty-hex = "0.2.1"
|
|
||||||
#gtk4 = {git = "https://github.com/gtk-rs/gtk4-rs/"}
|
|
||||||
#gtk4 = "0.3.0"
|
|
||||||
#gio4_sys ="0."
|
|
||||||
#gtk4_sys = "0.3.0"
|
|
||||||
#gtk4-sys = "0.3.0"
|
|
||||||
serialport = "4.0.1"
|
|
||||||
closure = "0.3.0"
|
|
||||||
[profile.release]
|
|
||||||
opt-level = 'z'
|
|
||||||
lto = true
|
|
||||||
codegen-units = 1
|
|
||||||
panic = 'abort'
|
|
||||||
strip = "debuginfo"
|
|
||||||
#[[bin]]
|
|
||||||
#name = "win_serial_comm_tool"
|
|
||||||
#target = "x86_64-pc-windows-gnu"
|
|
||||||
#path = "src/main.rs"
|
|
||||||
|
|
62
README.md
62
README.md
@ -1,62 +0,0 @@
|
|||||||
|
|
||||||
# Serial Port tool
|
|
||||||
|
|
||||||
This is a serial tool for Linux and windows.
|
|
||||||
|
|
||||||
I am a embedded sorfware developer. USART is a very common communication protocal for communication and debug. I was using Moserial Terminal and Cutecom. But I found serveral problem in these tool. So I design this tool to help embedded software developer. This tool still work in progross. The function of this tool is limited for now.
|
|
||||||
|
|
||||||
The main thing in this tool is realiable. Tool will not crash, and get correct data from serial port. Display these data correctly and completance.
|
|
||||||
|
|
||||||
|
|
||||||
## Install
|
|
||||||
Windows
|
|
||||||
|
|
||||||
1. Install [gtk3 runtime environment](https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases/download/2021-04-29/gtk3-runtime-3.24.29-2021-04-29-ts-win64.exe)
|
|
||||||
2. Download executable file from release page.
|
|
||||||
3. Run executable file
|
|
||||||
|
|
||||||
Linux
|
|
||||||
|
|
||||||
1. Install gtk3
|
|
||||||
2. Download executable file from release page.
|
|
||||||
3. Run executable file
|
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
This tool support following commands. `list`, `open`, `close`, `send`, `loop`, `loopend`, `clean`, `show`, `hide`, `set`.
|
|
||||||
|
|
||||||
1. `list`: List all avaliable port in log window
|
|
||||||
2. `open <port_name>`: Open port.
|
|
||||||
3. `close`: Close port.
|
|
||||||
4. `send <data>`: Send _data_ to port.
|
|
||||||
5. `loop <data>`: Send _data_ periodic. The period show in the status bar.
|
|
||||||
6. `loopend`: Stop send _data_ periodic.
|
|
||||||
7. `clear`: Clear log and receive data windows.
|
|
||||||
8. `show <window>`: Show log or hex window. The parameter, _window_, should be `log` or `hex`.
|
|
||||||
9. `hide <window>`" Inverse operation of `show`
|
|
||||||
|
|
||||||
10. `set <name> <value>`: Change port parameter.
|
|
||||||
|
|
||||||
### Set command
|
|
||||||
|
|
||||||
Supportted settings: `baudrate`, `databit`, `parity`, `stopbit`, `flowcontrol`, `period`.
|
|
||||||
1. `baudrate`: Change baudrate. Support any value.
|
|
||||||
2. `databit`: Change databit. Support value: 5, 6, 7, 8.
|
|
||||||
3. `parity`: Change parity. Support value: 0: None, 1: Odd, 2: Even.
|
|
||||||
4. `stopbit`" Change stopit. Support value: 1, 2.
|
|
||||||
5. `flowcontrol`: Change flowcontrol. Support value: hard, soft, none.
|
|
||||||
6. `period`: Change loop send periodic. This will work after port is open. Minimum value: 10ms for Linux, 15 ms for Windows. Because operation system can not run programming in real time, this value is not accurate.
|
|
||||||
|
|
||||||
|
|
||||||
## Feature list
|
|
||||||
|
|
||||||
- [x] open port
|
|
||||||
- [x] close port
|
|
||||||
- [x] send ascii to port
|
|
||||||
- [x] view recived data as hex
|
|
||||||
- [x] change port settings
|
|
||||||
- [x] send data periodic
|
|
||||||
- [ ] record output to file
|
|
||||||
- [ ] send hex to port
|
|
||||||
- [ ] send hex periodic
|
|
10
main.cpp
Executable file
10
main.cpp
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#include <QApplication>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include "main_window.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
main_window win;
|
||||||
|
win.show();
|
||||||
|
return QApplication::exec();
|
||||||
|
}
|
175
main.ui
Executable file
175
main.ui
Executable file
@ -0,0 +1,175 @@
|
|||||||
|
<?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>1489</width>
|
||||||
|
<height>875</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QSplitter" name="splitter">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="layoutWidget">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QComboBox" name="stopbitsComboBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>1</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>1.5</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>2</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QComboBox" name="dataBitsComboBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>8</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>7</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>6</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>5</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QPushButton" name="portUpdBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>port</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Temp</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="portsComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLineEdit" name="tmpFilenameEdit">
|
||||||
|
<property name="text">
|
||||||
|
<string>tmpdata</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Baudrate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Databits</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0" colspan="2">
|
||||||
|
<widget class="QPushButton" name="portOpenBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>open</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Stopbis</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="baudLineEdit">
|
||||||
|
<property name="text">
|
||||||
|
<string>115200</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QTextEdit" name="hexTextEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QTextEdit" name="asciiTextEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>1489</width>
|
||||||
|
<height>31</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
<slots>
|
||||||
|
<slot>update_ui_port()</slot>
|
||||||
|
<slot>open_port()</slot>
|
||||||
|
<slot>update_chart()</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
156
main_window.cpp
Executable file
156
main_window.cpp
Executable file
@ -0,0 +1,156 @@
|
|||||||
|
//
|
||||||
|
// Created by zong on 5/18/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "main_window.h"
|
||||||
|
#include <QtSerialPort/QSerialPort>
|
||||||
|
#include <QtSerialPort/QSerialPortInfo>
|
||||||
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
|
#include <QFile>
|
||||||
|
#include<QMessageBox>
|
||||||
|
|
||||||
|
static bool check_exist(QString str) {
|
||||||
|
for (auto &port: QSerialPortInfo::availablePorts()) {
|
||||||
|
if (str == port.portName())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window::setUiComponent() {
|
||||||
|
this->ui = new Ui::MainWindow;
|
||||||
|
ui->setupUi(this);
|
||||||
|
portsComboBox = ui->portsComboBox;
|
||||||
|
hexTextEdit = ui->hexTextEdit;
|
||||||
|
tmpFilenameEdit = ui->tmpFilenameEdit;
|
||||||
|
portOpenBtn = ui->portOpenBtn;
|
||||||
|
portsComboBox = ui->portsComboBox;
|
||||||
|
portUpdBtn = ui->portUpdBtn;
|
||||||
|
statusbar = ui->statusbar;
|
||||||
|
stopbitsComboBox = ui->stopbitsComboBox;
|
||||||
|
QObject::connect(portOpenBtn, SIGNAL(clicked()), this, SLOT(open_port()));
|
||||||
|
QObject::connect(portUpdBtn, SIGNAL(clicked()), this, SLOT(update_ui_port()));
|
||||||
|
}
|
||||||
|
|
||||||
|
main_window::main_window(QWidget *parent) : QMainWindow(parent) {
|
||||||
|
setUiComponent();
|
||||||
|
QObject::connect(&port, SIGNAL(readyRead()), this, SLOT(read_data()));
|
||||||
|
QFont font("Courier");
|
||||||
|
hexTextEdit->setFont(font);
|
||||||
|
QSerialPortInfo info;
|
||||||
|
auto tmp = QSerialPortInfo::availablePorts();
|
||||||
|
portsComboBox->clear();
|
||||||
|
for (auto &port: tmp) {
|
||||||
|
qDebug() << port.portName();
|
||||||
|
portsComboBox->addItem(port.portName());
|
||||||
|
}
|
||||||
|
hexTextEdit->setLineWrapMode(QTextEdit::FixedColumnWidth);
|
||||||
|
hexTextEdit->setLineWrapColumnOrWidth(48);
|
||||||
|
hexTextEdit->setWordWrapMode(QTextOption::WordWrap);
|
||||||
|
hexTextEdit->setFontFamily("Mono");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
main_window::~main_window() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window::update_ui_port() {
|
||||||
|
portsComboBox->clear();
|
||||||
|
for (auto &port: QSerialPortInfo::availablePorts()) {
|
||||||
|
portsComboBox->addItem(port.portName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window::open_port() {
|
||||||
|
if (is_open) {
|
||||||
|
port.close();
|
||||||
|
QFile file;
|
||||||
|
auto filename = tmpFilenameEdit->text();
|
||||||
|
file.setFileName(filename);
|
||||||
|
file.open(QIODevice::Append);
|
||||||
|
auto val = hexTextEdit->toPlainText();
|
||||||
|
hexTextEdit->clear();
|
||||||
|
file.write(val.toUtf8());
|
||||||
|
file.close();
|
||||||
|
is_open = false;
|
||||||
|
portOpenBtn->setText("open");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (portsComboBox->count() == 0) { return; }
|
||||||
|
auto cur_port = portsComboBox->currentText();
|
||||||
|
if (!check_exist(cur_port)) return;
|
||||||
|
port.setPortName(cur_port);
|
||||||
|
auto stopbits = stopbitsComboBox->currentText();
|
||||||
|
if (stopbits == QString("1")) port.setStopBits(QSerialPort::OneStop);
|
||||||
|
else if (stopbits == QString("1.5")) port.setStopBits(QSerialPort::OneAndHalfStop);
|
||||||
|
else if (stopbits == QString("2")) port.setStopBits(QSerialPort::TwoStop);
|
||||||
|
else {
|
||||||
|
QMessageBox box;
|
||||||
|
box.setText("wrong stopbits settings");
|
||||||
|
box.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: read info from config
|
||||||
|
port.setBaudRate(115200);
|
||||||
|
port.setDataBits(QSerialPort::Data8);
|
||||||
|
port.setParity(QSerialPort::NoParity);
|
||||||
|
port.setFlowControl(QSerialPort::NoFlowControl);
|
||||||
|
if (port.open(QIODevice::ReadWrite)) {
|
||||||
|
is_open = true;
|
||||||
|
portOpenBtn->setText("close");
|
||||||
|
statusbar->showMessage("open port success");
|
||||||
|
} else
|
||||||
|
is_open = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <QLineSeries>
|
||||||
|
|
||||||
|
static uint64_t rest = 0;
|
||||||
|
|
||||||
|
static QLineSeries linedata;
|
||||||
|
static int cnt = 0;
|
||||||
|
static long long line_cnt = 0;
|
||||||
|
|
||||||
|
void main_window::read_data() {
|
||||||
|
auto data = port.readAll();
|
||||||
|
// for (int i = 0; i < data.size(); i++) {
|
||||||
|
// linedata.append(line_cnt++, int(data[i]));
|
||||||
|
// }
|
||||||
|
cnt += data.size();
|
||||||
|
QString new_text = QString(data.toHex(' ').toUpper()) + " ";
|
||||||
|
hexTextEdit->moveCursor(QTextCursor::End);
|
||||||
|
hexTextEdit->insertPlainText(new_text);
|
||||||
|
if (cnt > 1e3) {
|
||||||
|
QFile file;
|
||||||
|
auto filename = tmpFilenameEdit->text();
|
||||||
|
file.setFileName(filename);
|
||||||
|
file.open(QIODevice::Append);
|
||||||
|
auto val = hexTextEdit->toPlainText();
|
||||||
|
hexTextEdit->clear();
|
||||||
|
file.write(val.toUtf8());
|
||||||
|
file.close();
|
||||||
|
cnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <QChart>
|
||||||
|
#include <QChartView>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
void main_window::update_chart() {
|
||||||
|
// TODO: memory leakage
|
||||||
|
QChart *chart = new QChart();
|
||||||
|
linedata.append(1, 10);
|
||||||
|
linedata.append(10, 7);
|
||||||
|
chart->addSeries(&linedata);
|
||||||
|
chart->createDefaultAxes();
|
||||||
|
chart->setTitle("WIP");
|
||||||
|
QChartView *chartview = new QChartView(chart);
|
||||||
|
chartview->show();
|
||||||
|
|
||||||
|
}
|
62
main_window.h
Executable file
62
main_window.h
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// Created by zong on 5/18/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef UNTITLED_MAIN_WINDOW_H
|
||||||
|
#define UNTITLED_MAIN_WINDOW_H
|
||||||
|
|
||||||
|
#include "ui_main.h"
|
||||||
|
#include <QSerialPort>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
class main_window : public QMainWindow {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit main_window(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
~main_window() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
bool is_open = false;
|
||||||
|
QSerialPort port;
|
||||||
|
|
||||||
|
QWidget *centralwidget;
|
||||||
|
QHBoxLayout *horizontalLayout;
|
||||||
|
QSplitter *splitter;
|
||||||
|
QWidget *layoutWidget;
|
||||||
|
QGridLayout *gridLayout;
|
||||||
|
QComboBox *stopbitsComboBox;
|
||||||
|
QComboBox *dataBitsComboBox;
|
||||||
|
QPushButton *portUpdBtn;
|
||||||
|
QLabel *label_4;
|
||||||
|
QComboBox *portsComboBox;
|
||||||
|
QLineEdit *tmpFilenameEdit;
|
||||||
|
QLabel *label;
|
||||||
|
QLabel *label_2;
|
||||||
|
QPushButton *portOpenBtn;
|
||||||
|
QLabel *label_3;
|
||||||
|
QLineEdit *baudLineEdit;
|
||||||
|
QSpacerItem *verticalSpacer;
|
||||||
|
QTextEdit *hexTextEdit;
|
||||||
|
QTextEdit *asciiTextEdit;
|
||||||
|
QMenuBar *menubar;
|
||||||
|
QStatusBar *statusbar;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setUiComponent();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void update_ui_port();
|
||||||
|
|
||||||
|
void open_port();
|
||||||
|
|
||||||
|
void read_data();
|
||||||
|
|
||||||
|
void update_chart();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //UNTITLED_MAIN_WINDOW_H
|
75
main_windows.cpp
Executable file
75
main_windows.cpp
Executable file
@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// Created by zong on 5/18/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "main_windows.h"
|
||||||
|
#include <QtSerialPort/QSerialPort>
|
||||||
|
#include <QtSerialPort/QSerialPortInfo>
|
||||||
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
static bool check_exist(QString str) {
|
||||||
|
for (auto &port: QSerialPortInfo::availablePorts()) {
|
||||||
|
if (str == port.portName())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
main_windows::main_windows(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
QObject::connect(&port, SIGNAL(readyRead()), this, SLOT(read_data()));
|
||||||
|
QSerialPortInfo info;
|
||||||
|
auto tmp = QSerialPortInfo::availablePorts();
|
||||||
|
ui->comboBox->clear();
|
||||||
|
for (auto &port: tmp) {
|
||||||
|
qDebug() << port.portName();
|
||||||
|
ui->comboBox->addItem(port.portName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
main_windows::~main_windows() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_windows::update_ui_port() {
|
||||||
|
ui->comboBox->clear();
|
||||||
|
for (auto &port: QSerialPortInfo::availablePorts()) {
|
||||||
|
ui->comboBox->addItem(port.portName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_windows::open_port() {
|
||||||
|
if (is_open) {
|
||||||
|
port.close();
|
||||||
|
is_open = false;
|
||||||
|
ui->pushButton_2->setText("open");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ui->comboBox->count() == 0) { return; }
|
||||||
|
auto cur_port = ui->comboBox->currentText();
|
||||||
|
if (!check_exist(cur_port)) return;
|
||||||
|
port.setPortName(cur_port);
|
||||||
|
port.setStopBits(QSerialPort::OneStop);
|
||||||
|
port.setBaudRate(115200);
|
||||||
|
port.setDataBits(QSerialPort::Data8);
|
||||||
|
port.setParity(QSerialPort::NoParity);
|
||||||
|
port.setFlowControl(QSerialPort::NoFlowControl);
|
||||||
|
if (port.open(QIODevice::ReadWrite)) {
|
||||||
|
is_open = true;
|
||||||
|
ui->pushButton_2->setText("close");
|
||||||
|
qDebug() << "open port success";
|
||||||
|
} else
|
||||||
|
is_open = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_windows::read_data() {
|
||||||
|
auto data = port.readAll();
|
||||||
|
qDebug() << data;
|
||||||
|
auto tmp = data.toHex(' ').toUpper();
|
||||||
|
auto new_text = QString(tmp);
|
||||||
|
ui->textEdit->insertPlainText(new_text);
|
||||||
|
// auto text = ui->textEdit-
|
||||||
|
}
|
36
main_windows.h
Executable file
36
main_windows.h
Executable file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// Created by zong on 5/18/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef UNTITLED_MAIN_WINDOWS_H
|
||||||
|
#define UNTITLED_MAIN_WINDOWS_H
|
||||||
|
|
||||||
|
#include "ui_main.h"
|
||||||
|
#include <QSerialPort>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
class main_windows : public QMainWindow {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit main_windows(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
~main_windows() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
bool is_open = false;
|
||||||
|
|
||||||
|
|
||||||
|
QSerialPort port;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void update_ui_port();
|
||||||
|
|
||||||
|
void open_port();
|
||||||
|
|
||||||
|
void read_data();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //UNTITLED_MAIN_WINDOWS_H
|
@ -1,68 +0,0 @@
|
|||||||
pub fn get_hex(prefix_len: u32, data: Vec<u8>) -> String {
|
|
||||||
let mut header_begin = prefix_len >> 4;
|
|
||||||
let mut counter = prefix_len % 16;
|
|
||||||
// println!("{}", header_begin);
|
|
||||||
// println!("{}", counter);
|
|
||||||
let mut ret = String::new();
|
|
||||||
|
|
||||||
for i in data {
|
|
||||||
if counter % 16 == 0 {
|
|
||||||
counter = 0;
|
|
||||||
// if header_begin != 0 {
|
|
||||||
// ret.push('\n');
|
|
||||||
// }
|
|
||||||
header_begin += 1;
|
|
||||||
ret += &format!("{:04x}\t", header_begin - 1);
|
|
||||||
}
|
|
||||||
counter += 1;
|
|
||||||
ret = ret + &*format!("{:02x} ", i);
|
|
||||||
if counter % 16 ==0 {
|
|
||||||
ret.push('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_ascii(prefix_len: u32, data: Vec<u8>) -> String {
|
|
||||||
let mut header_begin = prefix_len >> 4;
|
|
||||||
let mut counter = prefix_len % 16;
|
|
||||||
// println!("{}", header_begin);
|
|
||||||
// println!("{}", counter);
|
|
||||||
let mut ret = String::new();
|
|
||||||
|
|
||||||
for i in data {
|
|
||||||
if counter % 16 == 0 {
|
|
||||||
counter = 0;
|
|
||||||
// if header_begin != 0 { ret.push('\n'); }
|
|
||||||
header_begin += 1;
|
|
||||||
ret += &format!("{:04x}\t", header_begin - 1);
|
|
||||||
}
|
|
||||||
counter += 1;
|
|
||||||
|
|
||||||
if i.is_ascii_alphanumeric() || i.is_ascii_punctuation() || i.is_ascii_graphic() {
|
|
||||||
// ret += &*(i as char).to_string();
|
|
||||||
ret.push(char::from(i));
|
|
||||||
// basic_show.push(i as char);
|
|
||||||
} else {
|
|
||||||
ret += ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
if counter % 16 ==0 {
|
|
||||||
ret.push('\n');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::hexdump::get_hex;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn exploration() {
|
|
||||||
let data = vec![10, 20, 203];
|
|
||||||
let tmp = get_hex(14, data);
|
|
||||||
println!("{}", tmp);
|
|
||||||
// assert_eq!(2 + 2, 4);
|
|
||||||
}
|
|
||||||
}
|
|
428
src/main.rs
428
src/main.rs
@ -1,428 +0,0 @@
|
|||||||
#![windows_subsystem = "windows"]
|
|
||||||
|
|
||||||
mod port;
|
|
||||||
mod hexdump;
|
|
||||||
|
|
||||||
use closure::closure;
|
|
||||||
|
|
||||||
use gtk::{Inhibit, TextView, Statusbar, Label};
|
|
||||||
use gtk::{gio, glib};
|
|
||||||
use gtk::prelude::{GtkWindowExt, BuilderExtManual, GtkMenuItemExt, WidgetExt, EntryExt, TextBufferExt, ScrolledWindowExt, AdjustmentExt};
|
|
||||||
use gio::prelude::{ApplicationExt, ApplicationExtManual};
|
|
||||||
use std::sync::mpsc::{Sender, Receiver, channel};
|
|
||||||
use serialport::{StopBits, FlowControl, Parity, DataBits};
|
|
||||||
use crate::port::*;
|
|
||||||
use gtk::prelude::TextViewExt;
|
|
||||||
use gtk::prelude::LabelExt;
|
|
||||||
|
|
||||||
use std::{str, env};
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let application = gtk::Application::new(
|
|
||||||
Some("com.github.gtk-rs.examples.menu_bar_system"),
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
// application.connect_startup(|app| {
|
|
||||||
// });
|
|
||||||
application.connect_activate(build_ui);
|
|
||||||
|
|
||||||
application.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_ui(application: >k::Application) {
|
|
||||||
let builder = gtk::Builder::from_string(include_str!("test.ui"));
|
|
||||||
let ui_main_window: gtk::ApplicationWindow = builder.object("main_window").expect("Can not get window!");
|
|
||||||
ui_main_window.set_application(Some(application));
|
|
||||||
let menu_view_command: gtk::MenuItem = builder.object("view_command").expect("Can not get command item");
|
|
||||||
let command_entry: gtk::Entry = builder.object("command_entry").expect("Can not get command entry");
|
|
||||||
let tmp = command_entry.clone();
|
|
||||||
menu_view_command.connect_activate(move |_| {
|
|
||||||
if WidgetExt::is_visible(&tmp) {
|
|
||||||
tmp.hide();
|
|
||||||
} else {
|
|
||||||
tmp.show();
|
|
||||||
tmp.set_has_focus(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let ui_log_window: gtk::Window = builder.object("log_window").expect("Can not get log view");
|
|
||||||
let menu_log_command: gtk::MenuItem = builder.object("log_command").expect("Can not get log command");
|
|
||||||
let menu_hex_command: gtk::MenuItem = builder.object("hex_command").expect("Can not get log command");
|
|
||||||
let ui_receive_view: TextView = builder.object("receive_view").expect("can not get receive view");
|
|
||||||
let ui_baudrate: Label = builder.object("ui_baudrate").unwrap();
|
|
||||||
let ui_databit: Label = builder.object("ui_databit").unwrap();
|
|
||||||
let ui_parity: Label = builder.object("ui_parity").unwrap();
|
|
||||||
let ui_stopbit: Label = builder.object("ui_stopbit").unwrap();
|
|
||||||
let ui_period: Label = builder.object("ui_period").unwrap();
|
|
||||||
let ui_com: Label = builder.object("ui_com").unwrap();
|
|
||||||
let ui_statusbar: Statusbar = builder.object("statusbar").unwrap();
|
|
||||||
let ui_log_view: TextView = builder.object("log_view").unwrap();
|
|
||||||
let ui_hex_view: TextView = builder.object("hex_view").unwrap();
|
|
||||||
let ui_hex_window: gtk::Window = builder.object("hex_window").unwrap();
|
|
||||||
let ui_ascii_view: TextView = builder.object("ascii_view").unwrap();
|
|
||||||
let ui_hex_scroll: gtk::ScrolledWindow = builder.object("ui_hex_scroll").unwrap();
|
|
||||||
|
|
||||||
// ui_viewport.set_vscroll_policy(Sc)
|
|
||||||
|
|
||||||
|
|
||||||
ui_log_window.show();
|
|
||||||
// ui_hex_window.show();
|
|
||||||
ui_log_window.connect_delete_event(|a, _| {
|
|
||||||
a.hide();
|
|
||||||
Inhibit(true)
|
|
||||||
});
|
|
||||||
|
|
||||||
ui_hex_window.connect_delete_event(|a, _| {
|
|
||||||
a.hide();
|
|
||||||
Inhibit(true)
|
|
||||||
});
|
|
||||||
let tmp = ui_log_window.clone();
|
|
||||||
menu_log_command.connect_activate(move |_| {
|
|
||||||
if tmp.is_visible() {
|
|
||||||
tmp.hide();
|
|
||||||
} else {
|
|
||||||
tmp.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let tmp = ui_hex_window.clone();
|
|
||||||
menu_hex_command.connect_activate(move |_| {
|
|
||||||
if tmp.is_visible() {
|
|
||||||
tmp.hide();
|
|
||||||
} else {
|
|
||||||
tmp.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let mut receive_char_counter = 0;
|
|
||||||
let (sender_ui_upd, receiver_ui_upd) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
|
||||||
receiver_ui_upd.attach(None, move |msg| {
|
|
||||||
match msg {
|
|
||||||
Message::UiUpdateLog(text) => {
|
|
||||||
let buf = ui_log_view.buffer().unwrap();
|
|
||||||
buf.insert(&mut buf.end_iter(), text.as_str());
|
|
||||||
}
|
|
||||||
Message::UiUpdateReceiveMsg(data) => {
|
|
||||||
let mut basic_show = String::new();
|
|
||||||
for i in data.clone() {
|
|
||||||
if i.is_ascii_alphanumeric() || i.is_ascii_whitespace() || i.is_ascii_punctuation() || i.is_ascii_graphic() {
|
|
||||||
basic_show.push(i as char);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let buf = ui_hex_view.buffer().unwrap();
|
|
||||||
let hex = hexdump::get_hex(receive_char_counter, data.clone());
|
|
||||||
buf.insert(&mut buf.end_iter(), hex.as_str());
|
|
||||||
|
|
||||||
// println!("{:?}",std::mem::size_of_val(&buf));
|
|
||||||
let buf = ui_receive_view.buffer().unwrap();
|
|
||||||
buf.insert(&mut buf.end_iter(), basic_show.as_str());
|
|
||||||
|
|
||||||
|
|
||||||
let buf = ui_ascii_view.buffer().unwrap();
|
|
||||||
let ascii = hexdump::get_ascii(receive_char_counter, data.clone());
|
|
||||||
buf.insert(&mut buf.end_iter(), ascii.as_str());
|
|
||||||
|
|
||||||
receive_char_counter += data.len() as u32;
|
|
||||||
let tmp = ui_hex_scroll.vadjustment();
|
|
||||||
tmp.set_value(tmp.upper());
|
|
||||||
}
|
|
||||||
Message::UiClearReceiveMsg => ui_receive_view.buffer().unwrap().set_text(""),
|
|
||||||
Message::UiClearLog => ui_log_view.buffer().unwrap().set_text(""),
|
|
||||||
Message::UiShowLog => ui_log_window.show(),
|
|
||||||
Message::UiHideLog => ui_log_window.hide(),
|
|
||||||
Message::UiShowHex => ui_hex_window.show(),
|
|
||||||
Message::UiHideHex => ui_hex_window.hide(),
|
|
||||||
Message::UiUpdateStatusBarBaudrate(value) => ui_baudrate.set_text(value.to_string().as_str()),
|
|
||||||
Message::UiUpdateStatusBarDatabit(value) => ui_databit.set_text(value.to_string().as_str()),
|
|
||||||
Message::UiUpdateStatusBarParity(value) => ui_parity.set_text(value.to_string().as_str()),
|
|
||||||
Message::UiUpdateStatusBarStopbit(value) => ui_stopbit.set_text(value.to_string().as_str()),
|
|
||||||
Message::UiUpdateStatusBarPeriod(value) => ui_period.set_text(&*(value.to_string() + " ms")),
|
|
||||||
Message::UiUpdateStatusBarCom(value) => ui_com.set_text(value.to_string().as_str()),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
glib::Continue(true)
|
|
||||||
});
|
|
||||||
|
|
||||||
let (gui2main_tx, gui2main_rx) = channel::<Message>();
|
|
||||||
std::thread::spawn(closure!(clone gui2main_tx, clone sender_ui_upd, || {main_proc(gui2main_tx, gui2main_rx, sender_ui_upd)}));
|
|
||||||
|
|
||||||
|
|
||||||
let to_ui = sender_ui_upd.clone();
|
|
||||||
command_entry.connect_activate(move |x| {
|
|
||||||
let command_buf = x.buffer();
|
|
||||||
let command = command_buf.text();
|
|
||||||
command_buf.set_text("");
|
|
||||||
process_cmd(command, to_ui.clone(), gui2main_tx.clone());
|
|
||||||
});
|
|
||||||
|
|
||||||
ui_main_window.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn process_cmd(command: String, to_ui: glib::Sender<Message>, gui2main_tx: Sender<Message>) {
|
|
||||||
let command_split: Vec<&str> = command.split_whitespace().collect();
|
|
||||||
if command_split.len() != 0 {
|
|
||||||
let cmd = command_split[0].to_ascii_lowercase();
|
|
||||||
match cmd.as_str() {
|
|
||||||
"set" => {
|
|
||||||
if command_split.len() == 1 {
|
|
||||||
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
let args: Vec<String> = command_split[1..].to_vec().into_iter().map(|item| String::from(item)).collect();
|
|
||||||
gui2main_tx.send(Message::MainCmdSet(args)).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"open" => {
|
|
||||||
if command_split.len() == 1 {
|
|
||||||
// to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
|
|
||||||
gui2main_tx.send(Message::MainCmdOpen("".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
let args: Vec<String> = command_split[1..].to_vec().into_iter().map(|item| String::from(item)).collect();
|
|
||||||
gui2main_tx.send(Message::MainCmdOpen(args[0].clone())).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"close" => {
|
|
||||||
gui2main_tx.send(Message::MainCmdClose).unwrap();
|
|
||||||
}
|
|
||||||
"list" => {
|
|
||||||
to_ui.send(Message::UiUpdateLog(list_available_ports().0)).unwrap();
|
|
||||||
}
|
|
||||||
"send" => {
|
|
||||||
if command.len() <= 5 {
|
|
||||||
to_ui.send(Message::UiUpdateLog("no data!\n".parse().unwrap())).unwrap();
|
|
||||||
} else {
|
|
||||||
gui2main_tx.send(Message::MainCmdSend(command[5..].parse().unwrap())).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"loop" => {
|
|
||||||
if command.len() <= 5 {
|
|
||||||
to_ui.send(Message::UiUpdateLog("no data!\n".parse().unwrap())).unwrap();
|
|
||||||
} else {
|
|
||||||
gui2main_tx.send(Message::MainCmdSendPeriod(command[5..].parse().unwrap())).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"loopend" => {
|
|
||||||
gui2main_tx.send(Message::MainCmdStopPeriod).unwrap();
|
|
||||||
}
|
|
||||||
"clear" => {
|
|
||||||
to_ui.send(Message::UiClearReceiveMsg).unwrap();
|
|
||||||
to_ui.send(Message::UiClearLog).unwrap();
|
|
||||||
}
|
|
||||||
"show" => {
|
|
||||||
if command_split.len() == 1 {
|
|
||||||
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
match command_split[1] {
|
|
||||||
"log" => to_ui.send(Message::UiShowLog).unwrap(),
|
|
||||||
"hex" => to_ui.send(Message::UiShowHex).unwrap(),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"hide" => {
|
|
||||||
if command_split.len() == 1 {
|
|
||||||
to_ui.send(Message::UiUpdateLog("No enough argument\n".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
match command_split[1] {
|
|
||||||
"log" => to_ui.send(Message::UiHideLog).unwrap(),
|
|
||||||
"hex" => to_ui.send(Message::UiHideHex).unwrap(),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main_proc(to_main_tx: Sender<Message>, rx: Receiver<Message>, ui_upd: glib::Sender<Message>) {
|
|
||||||
let (mut main2port_tx, _rx_port_receive) = channel::<Message>();
|
|
||||||
let mut port_default_config = PortConfig {
|
|
||||||
baud_rate: 115_200,
|
|
||||||
data_bits: DataBits::Eight,
|
|
||||||
parity: Parity::None,
|
|
||||||
flow_control: FlowControl::None,
|
|
||||||
stopbit: StopBits::One,
|
|
||||||
timeout: 10,
|
|
||||||
};
|
|
||||||
let mut port_status_open = false;
|
|
||||||
let mut default_com_port = list_available_ports().1;
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarCom(default_com_port.clone())).unwrap();
|
|
||||||
loop {
|
|
||||||
if let Ok(msg) = rx.try_recv() {
|
|
||||||
match msg {
|
|
||||||
Message::UiClearReceiveMsg => {}
|
|
||||||
Message::MainCmdOpen(arg) => {
|
|
||||||
if port_status_open {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Port Already Open\n".to_string())).unwrap();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let (tmp_to_port, main2port_rx) = channel::<Message>();
|
|
||||||
main2port_tx = tmp_to_port;
|
|
||||||
|
|
||||||
let port_name = if arg.is_empty() { default_com_port.clone() } else {
|
|
||||||
let mut tmp = arg.clone();
|
|
||||||
if env::consts::OS == "linux" {
|
|
||||||
let prelude = "/dev/tty";
|
|
||||||
if !arg.contains("/dev/tty"){
|
|
||||||
tmp = prelude.to_owned() + &arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp
|
|
||||||
};
|
|
||||||
default_com_port = port_name.clone();
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarCom(default_com_port.clone())).unwrap();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
match port_open(port_name, port_default_config) {
|
|
||||||
Ok(port) => {
|
|
||||||
port_status_open = true;
|
|
||||||
std::thread::spawn(closure!(clone to_main_tx, || port_proc(port, to_main_tx, main2port_rx)));
|
|
||||||
ui_upd.send(Message::UiUpdateLog("open port succeed\n".to_string())).unwrap();
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
match e {
|
|
||||||
Error::PortOpenFailed(msg) => {
|
|
||||||
ui_upd.send(Message::UiUpdateLog(msg)).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message::MainCmdClose => {
|
|
||||||
if port_status_open {
|
|
||||||
main2port_tx.send(Message::PortCmdClose).unwrap();
|
|
||||||
} else {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("No port opened\n".to_string())).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message::MainCmdSend(msg) => main2port_tx.send(Message::PortCmdSend(msg)).unwrap(),
|
|
||||||
Message::MainCmdSendPeriod(msg) => { main2port_tx.send(Message::PortPeriodSend(msg)).unwrap() }
|
|
||||||
Message::MainCmdStopPeriod=> { main2port_tx.send(Message::PortPeriodStop).unwrap() }
|
|
||||||
Message::MainCmdSet(args) => {
|
|
||||||
match args[0].as_str() {
|
|
||||||
"baudrate" => {
|
|
||||||
if args.len() != 2 {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
if let Ok(value) = args[1].parse::<u32>() {
|
|
||||||
port_default_config.baud_rate = value;
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarBaudrate(value)).unwrap();
|
|
||||||
} else {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"databit" => {
|
|
||||||
if args.len() != 2 {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
if let Ok(value) = args[1].parse::<u32>() {
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarDatabit(value)).unwrap();
|
|
||||||
match value {
|
|
||||||
8 => port_default_config.data_bits = DataBits::Eight,
|
|
||||||
7 => port_default_config.data_bits = DataBits::Seven,
|
|
||||||
6 => port_default_config.data_bits = DataBits::Six,
|
|
||||||
5 => port_default_config.data_bits = DataBits::Five,
|
|
||||||
_ => { ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(); }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"parity" => {
|
|
||||||
if args.len() != 2 {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
if let Ok(value) = args[1].parse::<u32>() {
|
|
||||||
match value {
|
|
||||||
0 => {
|
|
||||||
port_default_config.parity = Parity::None;
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarParity("None".to_string())).unwrap();
|
|
||||||
}
|
|
||||||
1 => {
|
|
||||||
port_default_config.parity = Parity::Odd;
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarParity("Odd".to_string())).unwrap();
|
|
||||||
}
|
|
||||||
2 => {
|
|
||||||
port_default_config.parity = Parity::Even;
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarParity("Even".to_string())).unwrap();
|
|
||||||
}
|
|
||||||
_ => { ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(); }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"stopbit" => {
|
|
||||||
if args.len() != 2 {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
if let Ok(value) = args[1].parse::<u32>() {
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarStopbit(value)).unwrap();
|
|
||||||
match value {
|
|
||||||
1 => port_default_config.stopbit = StopBits::One,
|
|
||||||
2 => port_default_config.stopbit = StopBits::Two,
|
|
||||||
_ => ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"flowcontrol" => {
|
|
||||||
if args.len() != 2 {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
match args[1].as_str() {
|
|
||||||
"hard" => port_default_config.flow_control = FlowControl::Hardware,
|
|
||||||
"soft" => port_default_config.flow_control = FlowControl::Software,
|
|
||||||
"none" => port_default_config.flow_control = FlowControl::None,
|
|
||||||
_ => { ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap(); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"period" => {
|
|
||||||
if args.len() != 2 {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Invalid command!\n".to_string())).unwrap();
|
|
||||||
} else {
|
|
||||||
match args[1].parse::<u64>() {
|
|
||||||
Ok(value) => {
|
|
||||||
if port_status_open {
|
|
||||||
main2port_tx.send(Message::PortPeriodDuration(value)).unwrap();
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarPeriod(value)).unwrap();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
ui_upd.send(Message::UiUpdateLog("No port open\n".parse().unwrap())).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => ui_upd.send(Message::UiUpdateLog(format!("{:?}\n", e))).unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => { ui_upd.send(Message::UiUpdateLog("command does not support!\n".to_string())).unwrap(); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message::PortHaveData(data) => {
|
|
||||||
ui_upd.send(Message::UiUpdateReceiveMsg(data)).unwrap();
|
|
||||||
}
|
|
||||||
Message::PortCloseSucceed => {
|
|
||||||
ui_upd.send(Message::UiUpdateLog("Close port succeed\n".to_string())).unwrap();
|
|
||||||
port_status_open = false;
|
|
||||||
}
|
|
||||||
Message::PortError(msg) => {
|
|
||||||
ui_upd.send(Message::UiUpdateLog(format!("port closed by error: {}\n", msg))).unwrap();
|
|
||||||
port_status_open = false;
|
|
||||||
}
|
|
||||||
Message::PortPeriodDuration(value) => {
|
|
||||||
ui_upd.send(Message::UiUpdateStatusBarPeriod(value)).unwrap();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::thread::sleep(Duration::from_millis(20));
|
|
||||||
}
|
|
||||||
}
|
|
144
src/port.rs
144
src/port.rs
@ -1,144 +0,0 @@
|
|||||||
use std::sync::mpsc::{Sender, Receiver};
|
|
||||||
use serialport::{SerialPort, DataBits, Parity, FlowControl, StopBits};
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
|
|
||||||
pub enum Message {
|
|
||||||
UiUpdateLog(String),
|
|
||||||
UiUpdateReceiveMsg(Vec<u8>),
|
|
||||||
UiClearReceiveMsg,
|
|
||||||
UiClearLog,
|
|
||||||
UiShowLog,
|
|
||||||
UiHideLog,
|
|
||||||
UiShowHex,
|
|
||||||
UiHideHex,
|
|
||||||
|
|
||||||
UiUpdateStatusBarCom(String),
|
|
||||||
UiUpdateStatusBarBaudrate(u32),
|
|
||||||
UiUpdateStatusBarParity(String),
|
|
||||||
UiUpdateStatusBarStopbit(u32),
|
|
||||||
UiUpdateStatusBarPeriod(u64),
|
|
||||||
UiUpdateStatusBarDatabit(u32),
|
|
||||||
|
|
||||||
MainCmdOpen(String),
|
|
||||||
MainCmdClose,
|
|
||||||
MainCmdSend(String),
|
|
||||||
MainCmdSet(Vec<String>),
|
|
||||||
MainCmdSendPeriod(String),
|
|
||||||
MainCmdStopPeriod,
|
|
||||||
|
|
||||||
PortCmdClose,
|
|
||||||
PortCmdSend(String),
|
|
||||||
|
|
||||||
PortPeriodSend(String),
|
|
||||||
PortPeriodStop,
|
|
||||||
PortPeriodDuration(u64),
|
|
||||||
|
|
||||||
PortCloseSucceed,
|
|
||||||
PortHaveData(Vec<u8>),
|
|
||||||
PortError(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Error {
|
|
||||||
PortOpenFailed(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct PortConfig {
|
|
||||||
pub baud_rate: u32,
|
|
||||||
pub data_bits: DataBits,
|
|
||||||
pub parity: Parity,
|
|
||||||
pub flow_control: FlowControl,
|
|
||||||
pub stopbit: StopBits,
|
|
||||||
pub timeout: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn port_open(port: String, config: PortConfig) -> Result<Box<dyn SerialPort>, Error> {
|
|
||||||
|
|
||||||
let port_builder = serialport::new(port, config.baud_rate)
|
|
||||||
.data_bits(config.data_bits)
|
|
||||||
.parity(config.parity)
|
|
||||||
.flow_control(config.flow_control)
|
|
||||||
.stop_bits(config.stopbit)
|
|
||||||
.timeout(Duration::from_millis(config.timeout as u64));
|
|
||||||
match port_builder.open() {
|
|
||||||
Ok(port) => { return Ok(port); }
|
|
||||||
Err(e) => {
|
|
||||||
let err_msg = format!("Open port failed with error {}\n", e).to_string();
|
|
||||||
return Err(Error::PortOpenFailed(err_msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn port_proc(mut port: Box<dyn SerialPort>, to_main: Sender<Message>, from_main: Receiver<Message>) {
|
|
||||||
let mut buf: Vec<u8> = vec![0; 128];
|
|
||||||
let mut period_send = false;
|
|
||||||
let mut period_timeout = std::time::Duration::from_millis(100);
|
|
||||||
let mut period_send_msg = String::new();
|
|
||||||
let mut last_send = std::time::Instant::now();
|
|
||||||
to_main.send(Message::PortPeriodDuration(100)).unwrap();
|
|
||||||
loop {
|
|
||||||
if let Ok(msg) = from_main.try_recv() {
|
|
||||||
match msg {
|
|
||||||
Message::PortCmdClose => {
|
|
||||||
to_main.send(Message::PortCloseSucceed).unwrap();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Message::PortCmdSend(msg) => {
|
|
||||||
match port.write(msg.as_bytes()) {
|
|
||||||
Err(e) => {
|
|
||||||
to_main.send(Message::PortError(format!("{}", e).to_string())).unwrap();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message::PortPeriodSend(msg) => {
|
|
||||||
period_send = true;
|
|
||||||
period_send_msg = msg;
|
|
||||||
}
|
|
||||||
Message::PortPeriodStop => {
|
|
||||||
period_send = false;
|
|
||||||
}
|
|
||||||
Message::PortPeriodDuration(value) => {
|
|
||||||
period_timeout = std::time::Duration::from_millis(value);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match port.read(buf.as_mut_slice()) {
|
|
||||||
Ok(size) => to_main.send(Message::PortHaveData(buf[0..size].to_owned())).unwrap(),
|
|
||||||
Err(e) => {
|
|
||||||
if e.kind() != std::io::ErrorKind::TimedOut {
|
|
||||||
to_main.send(Message::PortError(format!("{}", e).to_string())).unwrap();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if period_send && (last_send.elapsed() > period_timeout) {
|
|
||||||
last_send = std::time::Instant::now();
|
|
||||||
match port.write(period_send_msg.as_bytes()) {
|
|
||||||
Err(e) => to_main.send(Message::PortError(format!("{}", e).to_string())).unwrap(),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn list_available_ports() -> (String, String) {
|
|
||||||
let mut ret = String::new();
|
|
||||||
let mut ret_portname = String::new();
|
|
||||||
match serialport::available_ports() {
|
|
||||||
Ok(ports) => {
|
|
||||||
for p in ports {
|
|
||||||
ret += &*String::from(format!("{:?}\n", p));
|
|
||||||
if ret_portname.is_empty() {
|
|
||||||
ret_portname = p.port_name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
ret = format!("{}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(ret, ret_portname)
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
entry.entry1 {
|
|
||||||
/*background: linear-gradient(to right, #f00, #0f0);*/
|
|
||||||
/*color: blue;*/
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 17pt;
|
|
||||||
}
|
|
||||||
textview.textview1 {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
397
src/test.ui
397
src/test.ui
@ -1,397 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Generated with glade 3.38.2 -->
|
|
||||||
<interface>
|
|
||||||
<requires lib="gtk+" version="3.24"/>
|
|
||||||
<object class="GtkWindow" id="hex_window">
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="default-width">900</property>
|
|
||||||
<property name="default-height">400</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkScrolledWindow" id="ui_hex_scroll">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkViewport">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="shadow-type">out</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkPaned">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkTextView" id="hex_view">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="editable">False</property>
|
|
||||||
<property name="monospace">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="resize">False</property>
|
|
||||||
<property name="shrink">True</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkTextView" id="ascii_view">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="editable">False</property>
|
|
||||||
<property name="monospace">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="resize">True</property>
|
|
||||||
<property name="shrink">True</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<object class="GtkWindow" id="log_window">
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="default-width">300</property>
|
|
||||||
<property name="default-height">400</property>
|
|
||||||
<property name="icon-name">network-server</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkScrolledWindow">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkTextView" id="log_view">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="editable">False</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<object class="GtkApplicationWindow" id="main_window">
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="default-width">600</property>
|
|
||||||
<property name="default-height">800</property>
|
|
||||||
<property name="icon-name">network-server</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkBox">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuBar" id="menu">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuItem">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes">_File</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<child type="submenu">
|
|
||||||
<object class="GtkMenu">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-new</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-open</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-save</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-save-as</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkSeparatorMenuItem">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-quit</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuItem">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes">_Edit</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<child type="submenu">
|
|
||||||
<object class="GtkMenu">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-cut</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-copy</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-paste</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-delete</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuItem">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes">_View</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<child type="submenu">
|
|
||||||
<object class="GtkMenu">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuItem" id="log_command">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes">log</property>
|
|
||||||
<accelerator key="l" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuItem" id="view_command">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes">command</property>
|
|
||||||
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuItem" id="hex_command">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes">hex</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkMenuItem">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="label" translatable="yes">_Help</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<child type="submenu">
|
|
||||||
<object class="GtkMenu">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkImageMenuItem">
|
|
||||||
<property name="label">gtk-about</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
<property name="use-stock">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkEntry" id="command_entry">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkScrolledWindow">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="vexpand">True</property>
|
|
||||||
<property name="shadow-type">in</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkTextView" id="receive_view">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">True</property>
|
|
||||||
<property name="editable">False</property>
|
|
||||||
<property name="monospace">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkStatusbar" id="statusbar">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="spacing">5</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="ui_com">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="label" translatable="yes">COM</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="ui_baudrate">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="label" translatable="yes">115200</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="ui_databit">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="label" translatable="yes">8</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="ui_parity">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="label" translatable="yes">None</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">4</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="ui_stopbit">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="label" translatable="yes">1</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">5</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkLabel" id="ui_period">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can-focus">False</property>
|
|
||||||
<property name="hexpand">True</property>
|
|
||||||
<property name="label" translatable="yes">100 ms</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">6</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">3</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</interface>
|
|
Loading…
x
Reference in New Issue
Block a user