今天我们来讲讲用Scala实现Qt QWidget对象的Eventable接口。这个Eventable接口是我项目中常用的一个东西,Scala强调FP,但是Qt Jambi本身是基于OOP的,事件重载需要在类里面进行。在前面展示的例子中,大家可以看到经常会这样展开一个类去重载:
, n5 l3 y O$ p+ ^3 U new QLabel { R& w0 r; Q: O: d
override def xxxxEvent } 这种声明的方法多了其实很容易让人觉得不规范,而且阅读也是不易。所以我萌生了让将js那种声明事件风格的代码加入至此,js是一个可以很fp的语言,而scala也是,这不是一个很好的决定吗?献上具体的代码:2 R* l+ x! y% ~2 }/ n" l* o
package yourporject.package6 T) U, K7 d0 M8 s: \
import scala.collection.mutable.{ ArrayBuffer, HashMap } import com.trolltech.qt.gui._ import com.trolltech.qt.core._ import com.trolltech.qt.core.QEvent import com.trolltech.qt.QSignalEmitter._ import com.agiers.mvc.Base /*
: j( J( v( L" B * Base类里面封装了的是对于Java和Scala既有类的方法扩展,使用的是隐式混入的方式,不会改变对象本身。
W) y2 {0 z- ?! O * 如
$ l" e7 h- t$ l# ?$ Q * "onClick".toEventName => click5 A' U k; m4 `" S' H2 o
* "中文字".encode => url encode4 C1 R1 K. s+ ?2 J
* "繁体字".encodeSys => 这个是根据客户端操作系统默认的字符编码进行urlencode
K, \& Y0 p. k; v# f* ^ * "繁体字".toSimplified => 繁体转简体
. H, K! G# _/ G& {& X * "简体字".toTraditional => 简体转繁体
/ p$ z; R4 G* G2 A; R | * "hello_world".toCamelCase => HelloWorld
8 Q2 O, M% J$ _% }) B4 E3 ]: } * "good guys".dump("temp.txt") => 将字符串内容输入到一个io文件中
5 D9 ]9 L- N. J8 D: l, M * "hello world".md5 => 将字符串md5加密
4 I7 ]+ {# Q* J+ I0 s# _( R */
" k: z) M" U% U$ r( ~ R trait Eventable[T Unit
- V( v' r- ~* j. m) \9 ?. y // 定义一个event的类型组合
* R, Q& S7 |5 f! m' y$ F) \ // 这个代表的实际上是String -> Fn或者(String, Fn)( c" _2 \. z# `; u1 H8 C
type Ev = (String, Fn)
/ r# O- @* ^: `( b9 g. y /**% N* Y& L: f* x2 W. p6 R' V# E2 I* T
* 事件接管对象
: C' H: P, Y, T * 用于接管声明事件时的闭包处理,并临时寄存该闭包中的各种状态和变量! s2 E6 u& I5 U- `
* @TODO 要逐渐增加他的寄存和读取的接口2 E( Y& p( Y5 o9 h7 R: J4 v! |: W
* @author Janpoem
* {) @& M+ d+ A) h* {$ r5 z */$ H1 m7 L+ l- [- ~/ ?( D) K
sealed case class EventHandle(val widget : T, val event : QEvent) {; J8 j7 x- W0 t3 n) x d: o' G
// 这个是用来获取该widget执行event时的状态的
; g' J+ [0 ~; }+ w private var _break = false' r' w7 ]- n% H- A; p
// 以下0 @) U3 w0 N- n2 F! c
def isBreak = _break* _. F+ n# u T9 F
def isBreak_=(is : Boolean) = _break = is5 k* j6 }2 K+ W( z& T* y
def break(fn : EventHandle => Boolean) = isBreak = fn(this)5 G9 X& g. k9 ^ F9 d$ |
} |