使用go-sciter创建桌面应用

最近需要使用go-sciter创建一个桌面应用,以下为学习和记录的笔记,方便自己查阅。

一、环境准备

  1. 从https://sciter.com/download/地址下载sciter-sdk
  2. 由于使用到cgo,所以window下需要安装mingw或tdm-gcc(建议安装tdm-gcc)
  3. cmd进入gopath目录并运行

二、通过html,css编写简单UI

书写标准的HTMLY页面,我就不一一赘述了,大家写个demo跑一下即可。

三、事件处理,函数与方法定义,go与tiscript之间相互调用

sciter处理脚本tiscript,用于处理UI交互中的一些逻辑,跟js很像,但又有点区别,对前端熟悉的人比较容易上手.

以下的方法是调用go定义的方法

<script type="text/tiscript">
    //view是一个全局的视图对象,root是加载的根元素
    var root = view.root;

    //通过self.$()方法选择元素,类似jquery的$
    //self.$()这里面参数不要加双引号
    //我们调用在go中为btn1定义的方法
    $(#btn1).on("click", function() {
        //this指向的当前元素
        this.test("参数1", "参数2", "参数3");
    });

    //在go中也可以调用我们在tis中为btn2定义的方法
    $(#btn2).test2 = function(a, b, c) {
        return String.printf("我是tis中为btn2定义的方法test2 %v %v %v", a, b, c);
    };

    //我们定义一个函数(注意函数与方法的区别)
    //这里的函数并没有指定属于哪个对象
    function sum(num1, num2) {
        return num1 + num2;
    }

    //调用go中定义的函数
    $(#btn3).on("click", function() {
        view.msgbox(#alert, view.dec(5));
    });
    $(#btn4).on("click", function() {
        view.msgbox(#alert, view.inc(5));
    });
</script>

四、固定窗口大小

<script type="text/tiscript">
self.ready = function() {
    //设置view对象不能改变大小
    view.isResizeable = false;
};
</script>

五、加载元素资源

有些时候我们需要动态的给某个UI元素加载内容或数据。

.go代码

package main;

import (
"github.com/sciter-sdk/go-sciter/window"
"github.com/sciter-sdk/go-sciter"
"log"
"fmt"
)

func load(root *sciter.Element) {
frame, _ := root.SelectById("frame");
//load()类似jquery.load(),用于给元素加载指定内容
//加载html内容
frame.Load("http://www.qq.com", sciter.RT_DATA_HTML);

txt, _ := root.SelectById("txt");
//附加元素事件处理
txt.AttachEventHandler(&sciter.EventHandler{
    //OnDataArrived 当资源被加载但未使用时调用
    //返回true,取消资源使用
    //返回false,遵循正常过程
    OnDataArrived: func(he *sciter.Element, params *sciter.DataArrivedParams) bool {
        //设置元素html
        he.SetHtml(string(params.Data()), sciter.SIH_REPLACE_CONTENT);
        return false;
    },
});
//加载本地原始数据
txt.Load("file:///D:/gopath/src/gui/1.txt", sciter.RT_DATA_RAW);

img, _ := root.SelectById("img");
img.AttachEventHandler(&sciter.EventHandler{
    //OnDataArrived 当资源被加载但未使用时调用
    OnDataArrived: func(he *sciter.Element, params *sciter.DataArrivedParams) bool {
        //设置属性,给img标签设置src
        he.SetAttr("src", params.Uri());
        return false;
    },
});
img.Load("http://mat1.gtimg.com/www/images/qq2012/qqLogoFilter.png", sciter.RT_DATA_IMAGE);

script, _ := root.SelectById("script");
script.AttachEventHandler(&sciter.EventHandler{
    //OnDataArrived 当资源被加载但未使用时调用
    OnDataArrived: func(he *sciter.Element, params *sciter.DataArrivedParams) bool {
        fmt.Println(string(params.Data()));
        return false;
    },
});
//加载脚本资源
script.Load("http://apps.bdimg.com/libs/jquery/1.8.3/jquery.min.js", sciter.RT_DATA_SCRIPT);
}

func main() {
w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.DefaultRect);
if err != nil {
    log.Fatal(err);
}
//加载文件
w.LoadFile("demo6.html");
//设置标题
w.SetTitle("元素加载内容");
//获取根元素
root, _ := w.GetRootElement();
//元素加载资源
load(root);
w.Show();
w.Run();
}

.html代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>元素加载内容</title>
<style>
    #frame {
        width: 100%;
        height: 50%;
    }

    #txt {
        border: 1px solid #ccc;
        height: 50px;
        color: #000;
    }
  </style>
 </head>
  <body>
 <iframe id="frame">
</iframe>
<div id="txt"></div>
<img id="img">
<script type="text/javascript" id="script"></script>

六、Element元素操作和Event事件响应

<script type="text/tiscript">
//类似jquery的ready();
self.ready = function() {
    testDom();
    testEvent();
};

//测试Dom操作
function testDom() {
    //选择元素,不要加引号
    var box = self.$(#box);
    //效果同上,注意要加引号
    var box2 = self.select("#box");
    //选择多个元素
    var lis = self.$$(#box > ul > li);
    stdout.println(lis.length);
    //同上
    var lis2 = self.selectAll("#box > ul > li");
    stdout.println(lis2.length);
    //first表示元素的第一个子元素
    stdout.println(lis.first.text);
    //last表示元素的最后一个子元素
    stdout.println(lis.last.text);

    var li = self.$(#box > ul > li:nth-child(1));
    //next表示下一个兄弟元素
    stdout.println(li.next.text);

    //访问元素的属性
    stdout.println(box.attributes["id"]);
    //设置元素的属性
    box.attributes["status"] = "open";

    //设置元素的样式
    li.style["background"] = "#f00";

    //判断元素是否可见
    var li2 = self.$(#box > ul > li:nth-child(2));
    li2.style["display"] = "none";
    if(!li2.isVisible) {
        stdout.println("li2不可见");
    }

    //遍历元素
    for(var child in lis) {
        stdout.println(child.text);
    }

    //动态创建元素
    var li4 = new Element("li");
    //将li元素追加到ul元素内部
    $(#box > ul).append(li4);
    //设置元素的文本
    //注意这里需先将元素添加到dom树上,然后再设置元素文本
    li4.text = "444";

    //这里直接追加html内容,不要加引号
    $(#box > ul).$append(<li>555</li>);
    $(#box > ul).$prepend(<li>000</li>);
    //外部追加
    $(#box).$after(<div>after</div>);
    $(#box).$before(<div>before</div>);

    //删除元素
    $(#box > ul > li:nth-child(4)).remove();

    //设置元素的状态
    //设置只读
    $(input[name='id']).setState(Element.STATE_READONLY);
    //设置焦点
    $(input[name='name']).setState(Element.STATE_FOCUS);
    //设置选中
    $(input[name='sex'][value='1']).setState(Element.STATE_CHECKED);
    //设置禁用
    $(#btn1).setState(Element.STATE_DISABLED);

    //定时器
    var cnt = 5;
    $(#btn2).timer(1000, function() {
        if(cnt == 0) {
            //返回false则停止定时器
            return false;
        }
        this.text = "第" + cnt + "次";
        cnt--;
        return true;
    });
}

//测试元素事件
function testEvent() {
    //单击事件
    $(#btn3).onClick = function() {
        stdout.println("btn3被点击了");
    };
    //双击事件
    $(#btn4).on("dblclick", function() {
        stdout.println("btn4被双击了");
    });
    //按键弹起
    $(#ipt).on("keyup", function() {
        stdout.println(this.value);
    });
    //value值改变时
    $(#sel).on("change", function() {
        stdout.println(this.value);
    });

    //移除事件函数
    $(#btn4).off("dblclick");
    //或者如下
    $(#btn4).unsubscribe("dblclick");

    //判断事件类型和按键码值
    $(#ipt2).on("keyup", function(evt) {
        //evt.type表示事件类型
        //evt.keyCode表示键码值
        if(evt.type == Event.KEY_UP && evt.keyCode == Event.VK_RETURN) {
            stdout.println("你回车了");
        }
    });

   //鼠标的左右键 1-代表左键 2-代表右键

   $(#ipt2).on("mousedown", function(evt) {
     if(1 & evt.buttons) {
        view.msgbox(#alert,"left mouse");
    }
     if(2 & evt.buttons) {
        view.msgbox(#alert,"right mouse");
    }
});

    //鼠标移动事件
    $(#mouse).on("mousemove", function(evt) {
        var str = "";
        str += "相对于div本身的 x:" + evt.x + " y:" + evt.y + "<br>";
        str += "相对于根元素html本身的 x:" + evt.xRoot + " y:" + evt.yRoot + "<br>";
        str += "相对于window窗口本身的 x:" + evt.xView + " y:" + evt.yView + "<br>";
        this.html = str;
    });
}

七、view对象常用方法,文件选择,窗口弹出,请求

view对象的详细文档请看:

<script type="text/tiscript">
self.ready = function() {
    var file = "";
    var folder = "";

    //选择文件
    $(#selFile).on("click", function() {
        //文件筛选项
        const filter = "Image Files (*.jpg,*.jpeg,*.gif,*.png)|*.jpg;*.jpeg;*.gif;*.png|All Files (*.*)|*.*";
        //默认后缀
        const defaultExt = "jpg";
        //初始化路径,就是文件选择窗打开时所在路径
        const initialPath = System.path(#USER_DOCUMENTS);
        //标题
        const caption = "选择图片";
        file = view.selectFile(#open, filter, defaultExt, initialPath, caption );
        $(#filePath).text = file;
        return true;
    });
    //选择文件夹
    $(#selFolder).on("click", function() {
        folder = view.selectFolder("选择你的文件夹");
        $(#folderPath).text = folder;
    });
    //移动文件
    $(#moveFile).on("click", function() {
        if(file && folder) {
            //调用go中定义的函数进行移动文件处理
            var ret = view.moveFile(file, folder);
            $(#moveRet).text = ret;
        }
    });

    //消息框
    $(#msgbox1).on("click", function() {
        view.msgbox(#alert, "我是消息框");
    });
    //信息框
    $(#msgbox2).on("click", function() {
        view.msgbox(#information, "我是信息框", "信息框");
    });
    //问题框
    $(#msgbox3).on("click", function() {
        view.msgbox(#question,
                    "请选择是或否",
                    "问题框",
                    //按钮组
                    [{id:#yes,text:"是"},{id:#no,text:"否"}],
                    //onLoad,窗口加载时调用
                    function(root) {

                    },
                    //onClose,窗口关闭时调用
                    function(root, id) {
                        //id表示你选择按钮的ID
                        if(id == "yes") {
                            view.msgbox(#alert, "你选择的yes");
                        } else {
                            view.msgbox(#alert, "你选择的no");
                        }
                    });
    });
    //警告框
    $(#msgbox4).on("click", function() {
        view.msgbox(#warning, "我是警告框");
    });
    //错误框
    $(#msgbox5).on("click", function() {
        view.msgbox(#error, "我是错误框");
    });

    //新对话框
    $(#dlg1).on("click", function() {
        var dlg = view.dialog({
            //加载到对话框中的URL,可加载本地文件
            url: self.url("simple.html"),
            //对话框的x,y坐标
            x: 50,
            y: 50,
            //窗口的宽度,高度
            width: 200,
            height: 200,
            //是否是客户区,如果为真,那么x,y,width,height作为客户区坐标,而不是窗口
            client: false,
            //对话框参数
            parameters: {"test":"test"},
            //对话框标题
            caption: "新对话框",
            //相对于屏幕窗口对齐
            alignment: 3,
        });
    });

    //新窗口
    $(#win1).on("click", function() {
        var win = view.window({
            //窗口类型
            //View.FRAME_WINDOW 框架窗口
            //View.TOOL_WINDOW 工具窗口
            //View.POPUP_WINDOW 弹出窗口
            type: View.TOOL_WINDOW,
            //加载到窗口中的URL,可加载本地文件
            url: self.url("simple.html"),
            //窗口的x,y坐标
            x: 200,
            y: 200,
            //窗口的宽度,高度
            width: 400,
            height: 400,
            //是否是客户区,如果为真,那么x,y,width,height作为客户区坐标,而不是窗口
            client: false,
            //窗口状态
            //View.WINDOW_SHOWN 显示
            //View.WINDOW_HIDDEN 隐藏
            //View.WINDOW_MINIMIZED 最小化
            //View.WINDOW_MAXIMIZED 最大化
            //View.WINDOW_FULL_SCREEN 全屏
            state: View.WINDOW_SHOWN,
            //窗口参数
            parameters: {"test":"test"},
            //窗口标题
            caption: "新窗口",
            //相对于屏幕窗口对齐
            alignment: 3,
        });
        //访问窗口中设置的参数
        stdout.println(win.parameters["test"]);
    });

    //修改当前窗口的状态
    $(#state1).on("click", function() {
        //全屏
        view.state = View.WINDOW_FULL_SCREEN;
    });
    $(#state2).on("click", function() {
        //默认
        view.state = View.WINDOW_SHOWN;
    });
    $(#state3).on("click", function() {
        //关闭
        view.close();
    });

    //view的事件响应
    //视图窗口大小发生改变时
    view.on("sizing", function(sizingParams) {
        view.dump("大小改变", sizingParams.x, sizingParams.y, sizingParams.width, sizingParams.height);
    });
    //视图窗口移动时
    view.on("moving", function(movingParams) {
        view.dump("移动改变", movingParams.x, movingParams.y, movingParams.width, movingParams.height);
    });
    //视图窗口状态改变时
    view.on("statechange", function() {
        view.dump(view.state);
    });

    //请求方法类似jquery中的ajax
    $(#req).on("click", function() {
        view.request({
            //请求类型(#get, #post, #put, #delete)
            type: #get,
            //请求url
            url: "http://www.163.com",
            //协议(#basic, #multipart, #json)
            protocol: #basic,
            params: {
                "test": "test"
            },
            //成功回调函数
            success: function(data,status) {
                $(#reqRet).html = data;
            },
            //失败回调函数
            error: function(err,status) {

            }
        });
    });
};

共有 0 条评论

Top