创建一个悬浮按钮可以通过点击后改变按钮文字

已存档
j9349u8rkq · 2 个月前
第 1 条补充
·
2 个月前

创建悬浮窗按钮 点击调用function方法闪退有什么办法可以调用到function

第 2 条补充
·
2 个月前

悬浮按钮点击调用方法报错,不能再UI线程执行阻塞操作,请使用setTimeout代替怎么解决

回答

Hamibot AI
1
· 2 个月前

文档地址 https://docs.hamibot.com/

可以通过创建一个悬浮窗,并在点击按钮时修改按钮的文字。下面是一个完整的示例代码:

// 创建悬浮窗
var floatyWin = floaty.window(
  <vertical>
    <button id="changeTextBtn" text="点击我" />
  </vertical>
);

// 按钮点击事件监听
floatyWin.changeTextBtn.click(function () {
  // 修改按钮文字
  floatyWin.changeTextBtn.setText("文字已改变");
});

// 保持悬浮窗不被关闭
setInterval(function () {}, 1000);

在这个示例中,悬浮窗包含一个按钮,初始显示为“点击我”。当点击按钮时,会将按钮的文字修改为“文字已改变”。


补充回答 1

文档地址 https://docs.hamibot.com/

如果你在点击悬浮窗按钮时调用了一个函数(function),但脚本闪退了,很可能是由于以下原因导致的:

常见原因及解决办法

1. 函数未定义或拼写错误

确保你调用的函数已经正确定义,并且名称拼写一致。

// 示例:正确使用函数
var floatyWin = floaty.window(
  <vertical>
    <button id="btn" text="点击" />
  </vertical>
);

function myFunction() {
  toast("函数被调用了");
}

floatyWin.btn.click(myFunction); // 正确绑定函数

2. 在非UI线程操作UI组件

悬浮窗相关的回调是在 UI 线程中执行的,但是如果你启动了新的线程或异步操作,请确保修改 UI 的部分在 UI 线程中执行。

如果必须在其他线程调用 UI 操作,请使用 ui.run()

floatyWin.btn.click(function () {
  threads.start(function () {
    // 模拟耗时操作
    sleep(1000);
    
    // 回到UI线程更新UI
    ui.run(function () {
      toast("这是一个跨线程的调用");
    });
  });
});

3. 函数内部抛出异常

如果函数内部出现异常(例如访问了不存在的对象、空指针等),会导致脚本崩溃。建议使用 try...catch 来捕获异常:

function myFunction() {
  try {
    // 可能会出错的代码
    var value = someUndefinedVariable.toUpperCase();
  } catch (e) {
    toast("发生错误:" + e.message);
  }
}

4. 函数中有无限循环或阻塞主线程的操作

避免在点击事件中执行长时间任务(如死循环、sleep(10000)等),否则可能导致悬浮窗无响应甚至闪退。

推荐做法是开启新线程处理耗时操作:

floatyWin.btn.click(function () {
  threads.start(function () {
    // 执行耗时操作
    for (var i = 0; i < 5; i++) {
      toast("执行中..." + i);
      sleep(1000);
    }
  });
});

5. 对象引用已释放

如果你在点击时引用了某些已经被关闭或释放的对象(例如悬浮窗已关闭但仍尝试修改其内容),也会导致闪退。请确保操作的对象仍然有效。


完整示例代码

var floatyWin = floaty.window(
  <vertical>
    <button id="btn" text="点击调用函数" />
  </vertical>
);

floatyWin.btn.click(function () {
  try {
    myCustomFunction();
  } catch (e) {
    toast("调用函数失败:" + e.message);
  }
});

function myCustomFunction() {
  toast("函数成功执行!");
}

总结

  • 确保函数存在且没有语法错误。
  • 不要在点击回调中执行阻塞操作。
  • 使用 threads.start 处理耗时任务。
  • 使用 ui.run 在 UI 线程更新界面。
  • 使用 try...catch 防止意外崩溃。

如果问题依旧存在,可以发送邮件到 support@hamibot.cn 获取进一步帮助。


补充回答 2

文档地址 https://docs.hamibot.com/

你遇到的错误提示是:

不能在 UI 线程执行阻塞操作,请使用 setTimeout 代替

这是因为在 Hamibot 的 UI 线程中,不允许执行会“卡住”线程的操作(如 sleep()、长时间循环等)。如果你在点击悬浮按钮时直接执行这些操作,会导致脚本崩溃。


✅ 解决方案:将耗时操作移出 UI 线程

你可以通过以下两种方式解决这个问题:


✅ 方法一:使用 threads.start() 启动新线程执行耗时操作

var floatyWin = floaty.window(
  <vertical>
    <button id="btn" text="点击执行" />
  </vertical>
);

floatyWin.btn.click(function () {
  // 点击事件在UI线程中触发,不能在这里直接 sleep 或做耗时操作
  threads.start(function () {
    // 在新的线程中执行阻塞操作
    toast("开始执行任务");
    sleep(3000); // 模拟耗时操作
    toast("任务完成");
  });
});

✅ 方法二:使用 setTimeout 延迟执行(适合轻量级异步操作)

如果你只是想延迟执行某个动作而不阻塞 UI,可以使用 setTimeout

var floatyWin = floaty.window(
  <vertical>
    <button id="btn" text="点击执行" />
  </vertical>
);

floatyWin.btn.click(function () {
  toast("点击了按钮");

  setTimeout(function () {
    toast("3秒后执行的任务");
    // 可以放一些非阻塞操作
  }, 3000);
});

❌ 错误示例(会导致崩溃)

floatyWin.btn.click(function () {
  toast("开始等待...");
  sleep(5000); // ⚠️ 错误!这会在UI线程中阻塞,导致崩溃
  toast("结束等待");
});

✅ 推荐组合:点击 → 启动线程 → 更新 UI 使用 ui.run

如果你需要在子线程中执行完任务后更新 UI,记得用 ui.run() 回到 UI 线程:

floatyWin.btn.click(function () {
  threads.start(function () {
    toast("后台执行中...");
    sleep(2000);

    ui.run(function () {
      toast("更新UI");
      floatyWin.btn.setText("已完成");
    });
  });
});

总结

场景 解决方式
阻塞或耗时操作(如 sleep 使用 threads.start()
延迟执行一个简单任务 使用 setTimeout()
子线程中修改 UI 使用 ui.run()

这样就能避免“不能在 UI 线程执行阻塞操作”的错误。

ℹ️ 本回答由 AI 生成,内容仅供参考
熊神大人小迷弟 · 2 个月前

创建悬浮窗按钮 点击调用function方法闪退