Save
Saving
  • 裸奔的de饺子

    如今web开发,为达到较高的开发效率以及适应前端高频迭代的速度,基本上都是前后端分离。vue-js是我认为国人开发效率较快的最快的语言之一,上手简单,大幅省去了以往jquery对DOM的操作,如果熟悉了他的开发模式及ES6的语法写法,会使页面组件话的操作更加顺手,另外再加上element-ui的模板配合,快速搭建一个你想要的web布局,非常容易。

    例子上手:

    #如若没有安装过vue-cli,先全局安装一下vue-cli
    $ cnpm i -g vue-cli
    #到自己喜欢的目录下创建一个基于 webpack 模板的新项目
    $ vue init webpack my-project
    #
    #
    #之后会有如下询问
    ? Project name (my-project) #回车
    ? Project description  #回车,也可以写点项目描述
    ? Author #回车,或者输入作者
    ? Vue build standalone #回车
    ? Install vue-router? (Y/n) #这里是官方推荐的路由,果断yes
    ? Use ESLint to lint your code? #No
    ? Set up unit tests #No
    ? Setup e2e tests with Nightwatch? #No
    ? Should we run `npm install` for you after the project has been created? (recommended)
    > Yes, use NPM #可以按上下方向键选择,这里我选第一个NPM,按回车确认
      Yes, use Yarn
      No, I will handle that myself
    #等待完成
    
    
    $ cd my-project #进入刚新建的文件夹
    $ cnpm install  #这里用的是淘宝的NPM镜像,不懂可以自行搜索cnpm
    $ npm run dev 
    

    现在打开src\componnets\HelloWorld.vue 把大部分代码删除,剩余如下:

    <template>
        <h1>{{ msg }}</h1> 
    </template>
    <script>
    export default { //ES6语法,用于输出到外部,这样就可以在其他文件内用import输入
      name: 'HelloWorld',
      data () {    //由于是组件,data必须是个函数,这是ES6写法,data后面加括号相当于data: function () {}
        return {   //记得return不然接收不到数据
          msg: 'Welcome' //上面的 msg 就是这里输出的
        }
      }
    }
    </script>
    <style>
    h1 {
      font-weight: normal;
    }
    a {
      color: #42b983;
    }
    </style>
    

    可以看到,之前打开的页面变了样:
    0_1540167870199_10907b12-856d-4624-bdf2-d33a4fd38548-image.png
    这里写图片描述
    现在来安装一下element-ui,这是我用过跟vue配合最好的一个模板

    可以按照官方方法使用npm i element-ui -S命令进行安装
    也可以在package.json中添加,后通过cnpm install进行安装
    

    这里我们选择2,打开package.json,找到devDependencies并在最后加上”element-ui”: “^2.2.1”

    "devDependencies": {
    ...
    ...
    "element-ui": "^2.2.1"
    

    打开命令行停止服务,再通过cnpm install进行安装,安装完成后npm run dev启动
    打开main.js在里面添加三行内容

    import ElementUI from 'element-ui' //新添加
    import 'element-ui/lib/theme-chalk/index.css' //新添加,避免后期打包样式不同,要放在import App from './App';之前
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    
    
    Vue.use(ElementUI)   //新添加
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      components: { App },
      template: '<App/>'
    })
    

    添加了这三行,我们就可以使用element-ui了
    接下来在components文件夹内新建一个NewContact.vue 文件,添加如下代码

    <template>
      <el-row>
        <el-button type="success">1</el-button>
      </el-row>
    </template>
    <script>
    
    </script>
    <style>
    
    </style>
    

    打开之前的HelloWorld.vue对内容进行修改(router是官方路由插件,router-link to是router的语法):

    <template>
    <!-- 这里router-link to="newcontact"会把路由导航到http://localhost:8080/#/newcontact   -->
        <router-link to="newcontact"><h1>{{ msg }}</h1></router-link>
    </template>
    

    打开router/index.js,添加新路由(router是官方路由插件,深入学习请查看文档)

    import Vue from 'vue'
    import Router from 'vue-router'
    import HelloWorld from '@/components/HelloWorld'
    import NewContact from '@/components/NewContact'//新添加,之后在下方的component: NewContact才会生效
    Vue.use(Router)
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: HelloWorld
        },
        {
          path: '/newcontact',//和router-link to相呼应,导航到/newcontact
          name: 'NewContact',
          component: NewContact
        }
      ]
    })
    

    保存后打开页面可以看到如下:
    0_1540168070899_bb6cf203-2070-417b-80e3-e7f1a3f1683f-image.png

    之前的welcome变成了可点击的链接,点击后跳转看到如下页面
    0_1540168092454_f3528a13-a550-426f-9084-448d768aea81-image.png
    0_1540168107737_3850f250-5800-417b-96a8-1143175bfd36-image.png

    打开NewContact.vue键入如下代码:

    <template>
      <el-row>
        姓名:{{info.name}}
        <el-input v-model="info.name" placeholder="请输入姓名"></el-input>
        年龄:{{info.age}}
        <el-input v-model="info.age" placeholder="请输入年龄"></el-input>
        性别:{{info.sex}}
        <el-select v-model="info.sex" placeholder="请选择">
          <el-option v-for="item in options" :key="item" :value="item"></el-option><!-- 这里的key官方推荐在v-for时使用,不然会警告,但不影响使用 -->
        </el-select>
      </el-row>
    </template>
    <script>
    export default {
      name: "NewContact",
      data(){
        return {
          info: {
            name: '',
            age: null,
            sex: ''
          },
          options: [
            '女','男','保密'
          ]
        }
      }
    }
    </script>
    <style>
    
    </style>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    <el-input v-model="info.name"></el-input> 
    el-input是element-ui的组件,以el-开头的是element-ui的组件 
    v-model这里的v-model是Vue的指令,官方说法是——在表单控件或者组件上创建双向绑定。 
    ="info.name"就是v-model绑定的数据,在data中return的内容里看到info.name对应的是'';info.age对应的是null
    
    return {
          info: {
            name: '',
            age: null,
            sex: ''
          }
    

    当我们打开http://localhost:8080/#/newcontact

    在输入框输入内容时可见,姓名:{{info.name}}双花括号里的内容也跟着改变,这就是双向绑定

    0_1540168157979_506c7f65-ce20-4cd2-be4f-e0e707543455-image.png

    0_1540168168452_733d0c95-bb6f-461b-b211-b12a36fb8ebb-image.png

    <el-option v-for=“item in options” :key=“item” :value=“item”>
    v-for="item in options"就是循环options这个数组的内容

    options: [
            '女','男','保密'
          ]
    

    如果在里面添加内容,那么下拉菜单的内容会一起变化,一 一对应
    :value="item"会把你选的(’女’,’男’,’保密’)传给<el-select v-model=“info.sex”>
    v-model="info.sex"会传给data中的info.sex

    return {
          info: {
            name: '',
            age: null,
            sex: ''
          }
    

    接下来在加入新代码,NewContact.vue目前的代码如下:

    .....
        </el-select>
        <el-button @click="create">创建</el-button>
        <template>
          <el-table :data="tabledata" align="left">
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="sex" label="性别"></el-table-column>
            <el-table-column label="操作">
              <template slot-scope="a">
                <el-button size="mini" type="danger" @click="del(a.$index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </template>
      </el-row>
    </template>
    <script>
    export default {
      name: "NewContact",
      data(){
        return {
          info: {
            name: '',
            age: null,
            sex: ''
          },
          options: [
            '女','男','保密'
          ],
          tabledata:[
            {name: 'Leo', age: 12, sex: 'man'},
            {name: 'Lei', age: 22, sex: 'women'},
            {name: 'Lii', age: 65, sex: 'men'}
          ]
        }
      }
    }
    </script>
    <style>
    
    </style>
    

    <el-button @click=“create” type=“success”>创建</el-button>
    这里就是创建了一个按钮,@是v-on的缩写,点击后会出发create这个函数

    <el-table :data=“tabledata”>
    就是表格要绑定的数据

    <el-table-column prop=“name”>
    在表格绑定数据情况下prop用于数据传递,tabeldata里的name

    <template slot-scope=“a”>
    是Vue2.5.0后替代之前scope的作用域插槽,”a”是随便的名字,就用用来后去table的状态,可以获取的row, column, $index和store,这里我们只需要获取index就行了,相关具体内容点这里

    @click="del(a.$index)
    @是v-on的缩写,表示点击后调用del函数,a.$index表示slot-scope获取到的index值

    tabledata:[//这里的内容是方便我们看到table的变化,可见页面上的table有了如下的内容
            {name: 'Leo', age: 12, sex: 'man'},
            {name: 'Lei', age: 22, sex: 'women'},
            {name: 'Lii', age: 65, sex: 'men'}
          ]
    

    打开页面可以看到
    0_1540168273550_72d363d1-16ce-49cf-bec1-ad6b86bf4095-image.png

    我们点击创建和删除按钮并没有反应,所以我们要添加methods,在它内部添加两个方法,一个是创建,一个是删除

    data(){
    ...
    },
      methods: {//添加在data(){...},的后面
        create(){
          this.tabledata.push(this.info)//给tabledata添加一个对象(之前我们创建的info)
          this.info =  {name: '', age: null, sex: ''}//点击创建后,让option还原,而不是停留在所选的项
        },
        del(index){
          this.tabledata.splice(index,1)//删除点击的对象,index是lot-scope="a" a.$index传过来的
        }
      }
    

    到这里已经完成了添加和删除,为了在我们刷新页面后,数据依然保存着,我们可以用localStorage本地存储数据
    关于localStorage可以点击这里了解

    接下来我们在src内新建一个store文件夹,和App.vue、components同一个层级,在里面新建一个store.js,内容如下

    const STORAGE_KEY = 'tabale-vuejs'//名字随便起
    export default {//向往输出,以便组件接收
        fetch() {//我们定义的获取数据的方法
            return JSON.parse(window.localStorage.getItem(STORAGE_KEY)
             || '[]')
        },
        save(items) {//我们定义的保存数据的方法
            window.localStorage.getItem(STORAGE_KEY, JSON.stringify(items))
        }
    }
    

    getItem和getItem是window.localStorage的获取和保存数据的方法
    我们用JSON.stringify和JSON.parse把数据转成字符串和解析,这样就方便我们写入tabledata
    接下来我们添加新代码

    <script>
    import Storage from '../store/store'//新添加,把刚写的localStorage导入
    export default {
    name: "NewContact",
      data(){
        return {
          info: {
            name: '',
            age: null,
            sex: ''
          },
          options: [
            '女','男','保密'
          ],
          tabledata: Storage.fetch()//把之前的删除,写入这个获取数据的方法
        }
      },
      methods: {
        create(){
          this.tabledata.push(this.info)
          this.info =  {name: '', age: null, sex: ''}
        },
        del(index){
          this.tabledata.splice(index,1)
        }
      },
      watch:{//新添加,watch是vue的监听,一旦监听对象有变化就会执行相应操作
        tabledata{//新添加,被监听的对象
          handler(items){Storage.save(items)},//新添加,监听对象变化后所做的操作,一个函数,保存数据
          deep: true//深度监听,避免数据的嵌套层数太多,我们要使用深度监听,这样即使数据层级过多监听不到
        }
      }
    

    tabledata:由于fetch()得到的是数组,所以直接tabledata: 后写入就行类似于

    tabledata:[{...},{...}]
    

    当我们添加删除数据时,可以打开chrmoe浏览器的F12>Application>Local Storage进行查看

    0_1540168375066_907dffdf-b254-40ff-af06-6f97dbce15c5-image.png

    总的来说就是我们点击页面上的创建按钮,watch监听到tabledata有变化,就执行savedata(items){Storage.save(items)}进行数据保存,点击删除时,tabledata也有变化,同样会执行保存
    可能之前写的内容会有不小心写错字母的情况,最后把NewContact.vue稍稍修改样式后,把完整的内容拷贝到下方:
    NewContact.vue

    <template>
      <el-row>
        <el-col :xs="24" :sm="18" :md="14" :lg="10" id="main">
        <label>姓名:</label>  
        <el-input v-model="info.name" placeholder="请输入姓名"></el-input>
        <label>年龄:</label>
        <el-input v-model="info.age" placeholder="请输入年龄"></el-input>
        <label>性别:</label>
        <el-select v-model="info.sex" placeholder="请选择">
          <el-option v-for="item in options" :key="item" :value="item"></el-option><!-- 这里的key官方推荐在v-for时使用,不然会警告,但不影响使用 -->
        </el-select>
        <el-button  class="btn-auto" @click="create" type="success">创建</el-button>
        <template>
          <el-table :data="tabledata" align="left">
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="sex" label="性别"></el-table-column>
            <el-table-column label="操作">
              <template slot-scope="a">
                <el-button size="mini" type="danger" @click="del(a.$index)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </template>
        </el-col>
      </el-row>
    </template>
    <script>
    import Storage from '../store/store'
    export default {
      name: "NewContact",
      data(){
        return {
          info: {
            name: '',
            age: null,
            sex: ''
          },
          options: [
            '女','男','保密'
          ],
          tabledata: Storage.fetch()
        }
      },
      methods: {
        create(){
          this.tabledata.push(this.info)
          this.info =  {name: '', age: null, sex: ''}
        },
        del(index){
          this.tabledata.splice(index,1)
        }
      },
      watch:{
        tabledata:{
          handler(items){Storage.save(items)},
          deep: true
        }
      }
    }
    </script>
    <style>
        #main{
          float: none;
          margin: 0 auto;
      }
      .el-input{
        padding-bottom: 5px;
      }
      .el-select {
          display: block;
      }
      .btn-auto{
          width: 100%;
          margin-top: 12px;
      }
    </style>
    

    这里是localStorage:

    const STORAGE_KEY = 'tabale-vuejs'
    export default {
        fetch() {
            return JSON.parse(window.localStorage.getItem(STORAGE_KEY)
             || '[]')
        },
        save(items) {
            window.localStorage.setItem(STORAGE_KEY, JSON.stringify(items))
        }
    }
    

    完成后我们要进行打包,方便直接在浏览器中运行
    打开/config/index.js

    build: {
        // Template for index.html
        index: path.resolve(__dirname, '../dist/index.html'),
    
        // Paths
        assetsRoot: path.resolve(__dirname, '../dist'),
        assetsSubDirectory: 'static',
        assetsPublicPath: './',//加了个. 避免生产路径的错误
    
        /**
         * Source Maps
         */
    
        productionSourceMap: false, //改为false
    

    然后运行$ npm run build
    等待完成,会生成dist文件夹,直接打开里面的index.html就可以在浏览器运行了

    posted in GuaiK实验室 read more
  • 裸奔的de饺子

    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和制动器(比如通过Twitter让房屋联网)的通信协议。

    好用,好使:
    它的底层工作协议分两种:一种是webscoket,一种是TCP。
    websocket协议主要用于移动端与服务端及Web端的发布订阅。
    tcp主要用于非以上的发布订阅。

    先看看web端的mqtt订阅端Demo吧:
    需要引入的JS:
    <script src=“static/js/mqttws31.js” type=“text/javascript”></script>
    要的找我,上传不了

    var client;
    
    function MQTTconnect(out_trade_no) {
        client = new Paho.MQTT.Client(mqtthost, mqttport, "ai");
        client.onMessageArrived = onMessageArrived;
        client.connect({
            onSuccess: function () {
                console.log("Host=" + mqtthost + ", port=" + mqttport);
                client.subscribe('+/+/+/+/+/'+out_trade_no);    //以订单号订阅频道
                console.log("onConnect succeeds");
            }
        });
    };
    
    function onMessageArrived(message) {
        var topic = message.destinationName;
        var payload = message.payloadString;
        console.log("onMessageArrived:" + payload);
        insert_order(JSON.parse(payload));
        remove_load();
        clear();
        $('#submit').html('支付成功');
        $('#submit').addClass('paySuccess');
        setTimeout(function () {
            $('#submit').html('收款');
            $('#submit').removeClass('paySuccess');
        }, 3000);
        off_alert = false;
        iziToast.success({
                        message: '金额:'+parseFloat(JSON.parse(payload).receipt_amount)/100,
                        position: 'bottomRight',
                        transitionIn: 'bounceInRight',
                        color:'green',
                        title:'到账提醒'+new Date().toLocaleString(),
                        timeout:5000
                    });
        client.unsubscribe(out_trade_no);
        client.disconnect();
    
    
    }
    

    再看看服务端的MQTT发布订阅吧:

    #-*- coding:utf-8 -*-
    
    client 端
    
    # 当连接上服务器后回调此函数
    import paho.mqtt.client as mqtt
    
    def on_connect(client, userdata, flags, rc):
        print("Connected with result code " + str(rc))
        # 放在on_connect函数里意味着
        # 重新连接时订阅主题将会被更新
        client.subscribe("qrcode")
    # 从服务器接受到消息后回调此函数
    def on_message(client, userdata, msg):
        res=str(msg.payload,'utf-8')
        print("主题:" + msg.topic + " 消息:" + res)
    '''
    client = mqtt.Client(transport='webscoket')  transport默认为tcp协议
    '''
    client = mqtt.Client()
    client.on_connect = on_connect  # 设置连接上服务器回调函数
    client.on_message = on_message  # 设置接收到服务器消息回调函数
    client.connect("mqtt.ahtyt.com", 1883)  # 连接服务器,端口为1883,维持心跳为60秒
    client.loop_forever()
    
    服务端:
    client = paho.Client()
    client.connect("xxx.xxx.com", port=1883)
    client.publish(topic="qrcode", payload=json.dumps("hello cy", ensure_ascii=False), qos=1)
    
    关于qos消息等级的说明,百度下就知道了。
    另外Mqtt协议支持多级通道推送,类似这样:
    
    client.publish(topic="q1/q2/q3/q4", payload=json.dumps("hello cy", ensure_ascii=False), qos=1)
    

    客户端需要以通配符的形式进行订阅类似这样:

    +/+/+/+/+/q2
    这样才能收听到q2的频道
    

    posted in GuaiK实验室 read more
  • 裸奔的de饺子

    忘了上传训练好的金额识别库了tesseract-ocr-setup-3.05.00dev.exe,要的找我

    posted in GuaiK实验室 read more
  • 裸奔的de饺子

    import pytesseract
    def getNumber(start_point_array, end_point_array):
        money = ''
    
        try:
            finalDic = None
            if start_point_array[0] not in ['',0] and start_point_array[1] not in ['',0] and end_point_array[0]not in ['',0] and  end_point_array[1]not in ['',0]:
                start_x_point = start_point_array[0]
                start_y_point = start_point_array[1]
                end_x_point = end_point_array[0]
                end_y_point = end_point_array[1]
                window_capture('demo2',start_x_point,start_y_point,end_x_point,end_y_point)
                image = Image.open('demo2.png')
                finalCode = pytesseract.image_to_string(image, lang="eng",config="-psm 7")
                '''识别纠错'''
                ocr_body =finalCode.strip().replace(' ', '').replace(',', '.').replace('O', '0').replace('o','0').replace('\n', '')
                for _m in ocr_body:
                    if _m.isdigit():
                        money += _m
                    elif _m == '.':
                        money += _m
                float(money)
                return True, money
            else:
                return False, money
        except Exception as e:
            print( 'do not recongize money{},prepare to query location'.format(money))
            print(str(traceback.format_exc()))
            return False, money
    

    代码片段,用到的,自己改下就好了。
    start_point_array,end_point_array分别为左上角和又下角元组坐标

    posted in GuaiK实验室 read more
  • 裸奔的de饺子

    package com.cy.xpaycore;
    
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.cy.xpaycore.base.Util;
    import org.junit.Test;
    import sun.security.provider.MD5;
    
    import java.net.URLEncoder;
    import java.util.*;
    
    public class Demo {
        @Test
        public void run1() {
            String gs="[{\"name\":\"apple\",\"price\":\"100\"},{\"name\":\"banana\",\"price\":\"20\"}]";
            Map<String, Object> map = new HashMap<String, Object>() {{
                put("outTradeNo", "123");
                put("authCode", "1232132");
                put("totalAmount", "100");
                put("goodsDetail",JSON.parseArray(gs));
            }};
            //对Map进行ASCII升序排序
            Set<Map.Entry<String, Object>> set=map.entrySet();
            List<Map.Entry<String,Object>> list=new ArrayList<Map.Entry<String, Object>>(set);
            Collections.sort(list, new Comparator<Map.Entry<String, Object>>() {
                @Override
                public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                    return o1.getKey().compareTo(o2.getKey());
                }
            });
            StringBuilder str=new StringBuilder();
            for(Map.Entry<String,Object> m:list){
                str.append(String.format("%s=%s&",m.getKey(),m.getValue()));
            }
            String str2=str.substring(0,str.length()-1);
            System.out.println("排序前:"+JSON.toJSONString(map));
            System.out.println(String.format("待签名字符串:%s",str2));
    
        }
    
    
    }
    输出:
    {"totalAmount":"100","authCode":"1232132","outTradeNo":"123","goodsDetail":[{"price":"100","name":"apple"},{"price":"20","name":"banana"}]}
    待签名字符串:authCode=1232132&goodsDetail=[{"price":"100","name":"apple"},{"price":"20","name":"banana"}]&outTradeNo=123&totalAmount=100
    
    Process finished with exit code 0
    

    posted in GuaiK实验室 read more
  • 裸奔的de饺子

    #-*- coding:utf-8 -*-
    import Tkinter
    import threading
    import time
    from libs import util
    from libs.db import reds
    from libs.widnows import cW
    
    
    class Title():
    
        def __init__(self,amount,msg):
            '''像素单元'''
            self.relWidthUnit = 400 / float(1920)
            self.relHeightUnit =200 / float(1080)
            self.relTextUnit =100 / float(1920*1080)
            self.relText2Unit =50 / float(1920*1080)
            self.top = Tkinter.Tk()
            self.top.title('xlife')
            '''禁止最大化'''
            self.top.resizable(False, False)
            '''置顶'''
            self.top.wm_attributes('-topmost', 1)
            '''获取系统分辨率'''
            self.w=self.top.winfo_screenwidth()
            self.h=self.top.winfo_screenheight()
            self.top.bind('<Button-1>',self.callback)
            self.top.geometry('{}x{}+{}+2'.format(int(self.relWidthUnit*self.w),int(self.relHeightUnit*int(self.h)),int(self.w-self.relWidthUnit*self.w)))  #初始化窗口大小
            self.top.attributes("-alpha", 0.6)#窗口透明度60 %
            self.label = Tkinter.Label(self.top, text=amount, font='Helvetica -{} bold'.format(int(self.relTextUnit*self.h*self.w)))  # 创建标签
            self.label2 = Tkinter.Label(self.top, text=msg, font='Helvetica -{} bold'.format(int(self.relTextUnit*self.h*self.w)),bg='WhiteSmoke')  # 创建标签
            self.label.pack(fill=Tkinter.Y, expand=1)  # 填充到界面
            self.label2.pack(fill=Tkinter.Y, expand=1)  # 填充到界面
    
        def callback(self,event):
            cW.swh_window()
    
        def display(self):
            # 进入消息循环
            self.top.mainloop()
    
        def wait(self):
    
            while True:
                try:
                    task = reds.blpop(util.get_mac_address())
                    if str(task[1]).find(',') > -1:
                        task = list(str(task[1]).split(','))
                        self.label.config(text='%.2f'%(float(task[0])))
                        t2 = threading.Thread(target=self.default)
                        t2.setName('titleDefault')
                        t2.setDaemon(True)
                        print '1.线程{}状态:{};{}'.format(t2.getName(), t2.isAlive(), t2.isDaemon())
                        if task[2]=='1':
                            self.label2.config(text=task[1],bg='green')
                            t2.start()
                        elif task[2]=='0':
                            self.label2.config(text=task[1],bg='yellow')
                        elif task[2]=='-1':
                            self.label2.config(text=task[1], bg='red')
                            t2.start()
                        elif task[2]=='-2':
                            self.label2.config(text=task[1],bg='yellow')
                            t2.start()
                        else:
                            self.label2.config(text=task[1])
                        print '2.线程{}状态:{};{}'.format(t2.getName(), t2.isAlive(), t2.isDaemon())
                    else:
                        print util.get_time()+'   received window ping .'
                except Exception:
                    continue
    
        def default(self):
            time.sleep(3)
            self.label.config(text='%.2f' % (0.00))
            self.label2.config(text='AI小助手',bg='WhiteSmoke')
    
    if __name__ == '__main__':
        Title('10.00','正在支付...').display()
    

    注意:wait函数需要多线程触发,因为tkinter的display()属于消息循环,消息的显示需要外部触发,我这里用的是redis的消息队列,实时获取pyhook传递过来的内容。

    posted in GuaiK实验室 read more
  • 裸奔的de饺子

    上代码,自己玩去:

    # -*- encoding: utf-8 -*-
    import uuid
    from win32api import *
    from win32gui import *
    import win32con
    import  os
    import time
    
    from concurrent.futures import ThreadPoolExecutor
    from tornado.concurrent import run_on_executor
    
    '''windows托盘提醒'''
    class WindowsBalloonTip:
        executor=ThreadPoolExecutor(10)
        @run_on_executor
        def alert(self, title, msg,delay=1):
            message_map = {
                win32con.WM_DESTROY: self.OnDestroy,
            }
            # Register the Window class.
            wc = WNDCLASS()
            hinst = wc.hInstance = GetModuleHandle(None)
            wc.lpszClassName = str(uuid.uuid1())
            wc.lpfnWndProc = message_map  # could also specify a wndproc.
            classAtom = RegisterClass(wc)
            # Create the Window.
            style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
            self.hwnd = CreateWindow(classAtom, "Taskbar", style, \
                                     0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \
                                     0, 0, hinst, None)
            UpdateWindow(self.hwnd)
            iconPathName = os.path.dirname(os.path.abspath('.'))+'\\logo.ico'
            icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
            try:
                hicon = LoadImage(hinst, iconPathName, \
                                  win32con.IMAGE_ICON, 0, 0, icon_flags)
            except:
                hicon = LoadIcon(0, win32con.IDI_APPLICATION)
            flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
            nid = (self.hwnd, 0, flags, win32con.WM_USER + 20, hicon, "tooltip")
            Shell_NotifyIcon(NIM_ADD, nid)
            Shell_NotifyIcon(NIM_MODIFY, \
                             (self.hwnd, 0, NIF_INFO, win32con.WM_USER + 20, \
                              hicon, "Balloon  tooltip", title, 200, msg))
            '''延时几秒后销毁消息及托盘图标'''
            time.sleep(delay)
            DestroyWindow(self.hwnd)
    
        @run_on_executor
        def OnDestroy(self, hwnd, msg, wparam, lparam):
            nid = (self.hwnd, 0)
            Shell_NotifyIcon(NIM_DELETE, nid)
            PostQuitMessage(0)  # Terminate the app.
    
    windows_alert=WindowsBalloonTip()
    # def balloon_tip(title, msg):
    #     w = WindowsBalloonTip(msg, title)
    
    if __name__ == '__main__':
        windows_alert.alert(u'提醒',u'what are you 弄撒咧.')
    

    posted in GuaiK实验室 read more
  • 裸奔的de饺子

    tornado是单进程单线程的,往往网络请求当中涉及IO耗时的操作,都会阻塞其他请求,这与美其名曰的“c10k”,相差甚远。其实tornado这种讲究精简极致的框架,是需要开发者充分发挥它的潜能的
    直接上代码:异步非阻塞

    # -*- coding:utf-8 -*-
    import traceback
    
    import time
    import tornado
    from concurrent.futures import ThreadPoolExecutor
    from tornado import web, concurrent
    from tornado.concurrent import run_on_executor
    from tornado.ioloop import IOLoop
    
    
    class Async():
        def __init__(self):
            self.io_loop = IOLoop.current()
            self.executor = ThreadPoolExecutor(max_workers=10)
    
        @run_on_executor
        def cmd(self,func,*args,**kwargs):
            return func(args,**kwargs)
    
    async=Async()
    
    
    class BaseHandler(web.RequestHandler):
        @tornado.web.asynchronous
        @tornado.gen.coroutine
        def get(self,*args):
            try:
                yield async.cmd(self._get,*args)
            except Exception:
                print traceback.format_exc()
                self.finish('network error')
    
    class ReqHandler(BaseHandler):
        def _get(self,*args):
            print 'wait for moment.'
            '''阻塞喽'''
            time.sleep(3)
            print 'rec http1.'
            self.finish('copy that1.')
    
    class ReqHandler2(BaseHandler):
        def _get(self,*args):
            print 'rec http2.'
            self.finish('copy that2.')
    
    def run_main():
        app = tornado.web.Application(handlers=[
            (r'/get',ReqHandler),
            (r'/get2',ReqHandler2),
        ])
        app.listen(9999)
        tornado.ioloop.IOLoop.current().start()
    
    if __name__ == "__main__":
        with concurrent.futures.ProcessPoolExecutor(max_workers=None) as executor:
            '''启动主程序'''
            executor.submit(run_main)
    
    
    
    
    

    posted in GuaiK实验室 read more