有一个test.json
[
[1000,800,1],
[1500,0,2],
[1600,0,3],
[2500,300,4]
]
第一个元素是启动时间(毫秒)。
第二个元素是时间的长度(毫秒)。
第三个元素是键,1\2\3\4分别表示a\b\c\d。
当开始时间到达第一个元素的值时,我希望按下相应的键,并保持第二个元素的长度。
以第一组数据为例:
当时间到1000毫秒时,按“a”键800毫秒。
只有少量的自定义代码。使用关键字Here is my code start
进行搜索。另一种代码是计时示例中的模板。
Cargo.toml
[dependencies]
delay_timer = "0.10.1"
enigo = "0.0.14"
serde_json = "1.0"
anyhow = "1.0.51"
smol = "1.2.5"
main.rs
use anyhow::Result;
use delay_timer::prelude::*;
use enigo::*;
use serde_json::{Result as SResult, Value};
use smol::Timer;
use std::fs::File;
use std::io::BufReader;
use std::thread;
use std::time::Duration;
fn main() -> Result<()> {
let delay_timer = DelayTimerBuilder::default().build();
// Create the task
// A chain of task instances.
let task_instance_chain = delay_timer
.insert_task(build_task_async_print().unwrap())
.unwrap();
// Get the running instance of task 1.
let task_instance = task_instance_chain.next_with_wait().unwrap();
// This while loop avoids removing the task before it completes
while task_instance.get_state() != delay_timer::prelude::instance::COMPLETED {}
// Remove task which id is 1.
delay_timer.remove_task(1).unwrap();
Ok(())
}
fn build_task_async_print() -> Result<Task, TaskError> {
let mut task_builder = TaskBuilder::default();
let body = create_async_fn_body!({
//Here is my code start
let json_data = get_json().unwrap();
for element in json_data.as_array().unwrap().iter() {
Timer::after(Duration::from_millis(element[0].as_f64().unwrap() as u64)).await;
println!("the value is: {}", element[0]);
//How to complete the code that uses enigo to press the corresponding keys?
let mut enigo = Enigo::new();
enigo.key_down(Key::Layout('a'));
thread::sleep(Duration::from_millis(element[1].as_f64().unwrap() as u64));
enigo.key_up(Key::Layout('a'));
}
//Here is my code end
});
// Build the task and assign 1 to it
task_builder.set_task_id(1).spawn(body)
}
//Get json data from json file
fn get_json() -> SResult<Value> {
let file = File::open("test.json").expect("file should open read only");
let reader = BufReader::new(file);
let mut v: Value = serde_json::from_reader(reader)?;
Ok(v.take())
}
问题:
如何完成使用enigo按下相应键的代码?
发布于 2021-12-07 10:58:51
又快又脏
假设您只使用小写ASCII字符,您可以这样做:
use anyhow::Result;
use delay_timer::prelude::*;
use enigo::*;
use serde_json::{Result as SResult, Value};
use smol::Timer;
use std::fs::File;
use std::io::BufReader;
use std::thread;
use std::time::Duration;
fn main() -> Result<()> {
let delay_timer = DelayTimerBuilder::default().build();
// Create the task
// A chain of task instances.
let task_instance_chain = delay_timer
.insert_task(build_task_async_print().unwrap())
.unwrap();
// Get the running instance of task 1.
let task_instance = task_instance_chain.next_with_wait().unwrap();
// This while loop avoids removing the task before it completes
while task_instance.get_state() != delay_timer::prelude::instance::COMPLETED {}
// Remove task which id is 1.
delay_timer.remove_task(1).unwrap();
Ok(())
}
fn build_task_async_print() -> Result<Task, TaskError> {
let mut task_builder = TaskBuilder::default();
let body = create_async_fn_body!({
//Here is my code start
let json_data = get_json().unwrap();
for element in json_data.as_array().unwrap().iter() {
Timer::after(Duration::from_millis(element[0].as_f64().unwrap() as u64)).await;
println!("the value is: {}", element[0]);
//How to complete the code that uses enigo to press the corresponding keys?
let mut enigo = Enigo::new();
enigo.key_down(Key::Layout(((element[2].as_u64().unwrap() + 96) as u8) as char));
thread::sleep(Duration::from_millis(element[1].as_f64().unwrap() as u64));
enigo.key_up(Key::Layout(((element[2].as_u64().unwrap() + 96) as u8) as char));
}
//Here is my code end
});
// Build the task and assign 1 to it
task_builder.set_task_id(1).spawn(body)
}
//Get json data from json file
fn get_json() -> SResult<Value> {
let file = File::open("test.json").expect("file should open read only");
let reader = BufReader::new(file);
let mut v: Value = serde_json::from_reader(reader)?;
Ok(v.take())
}
较好方法
如果您控制了JSON,我将直接将字符放在数组中(或者至少使用它们的十进制ASCII代码),或者更好地使用易于解析为生锈结构的JSON对象。
所以我提议的JSON应该是这样的:
[
{
"startTime": 1000,
"duration": 800,
"key": "a"
},
{
"startTime": 1500,
"duration": 0,
"key": "b"
},
{
"startTime": 1600,
"duration": 0,
"key": "c"
},
{
"startTime": 2500,
"duration": 300,
"key": "d"
}
]
然后您就可以像这样轻松地解析它:
use anyhow::Result;
use delay_timer::prelude::*;
use enigo::*;
use serde::Deserialize;
use smol::Timer;
use std::thread;
use std::time::Duration;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct EnigoCommand {
pub start_time: u64,
pub duration: u64,
pub key: char
}
fn main() -> Result<()> {
let delay_timer = DelayTimerBuilder::default().build();
let task_instance_chain = delay_timer
.insert_task(build_task_async_print().unwrap())
.unwrap();
let task_instance = task_instance_chain.next_with_wait().unwrap();
while task_instance.get_state() != delay_timer::prelude::instance::COMPLETED {}
delay_timer.remove_task(1).unwrap();
Ok(())
}
fn build_task_async_print() -> Result<Task, TaskError> {
let mut task_builder = TaskBuilder::default();
let body = create_async_fn_body!({
let commands = get_commands().expect("Failed to read commands from json file.");
for command in commands.iter() {
Timer::after(Duration::from_millis(command.start_time)).await;
let mut enigo = Enigo::new();
enigo.key_down(Key::Layout(command.key));
thread::sleep(Duration::from_millis(command.duration));
enigo.key_up(Key::Layout(command.key));
}
});
task_builder.set_task_id(1).spawn(body)
}
fn get_commands() -> Result<Vec<EnigoCommand>, Box<dyn std::error::Error>> {
let file = std::fs::read_to_string("test.json")?;
let commands: Vec<EnigoCommand> = serde_json::from_str(file.as_str())?;
Ok(commands)
}
请注意,这还需要具有serde
特性的derive
依赖项:
[dependencies]
delay_timer = "0.10.1"
enigo = "0.0.14"
serde={version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0.51"
smol = "1.2.5"
https://stackoverflow.com/questions/70251830
复制相似问题