这个年代居然是VB6最王道
NND。这个年代居然是VB6最王道。
“博学女生”竞赛委员会的Huanyu MM委托Shellex开发一款抢答器。Shellex用Python + GTK快速搞了一个。TCPServer + Socket Client,简洁又优雅(汗)。
但是往Windows移植的时候(用py2exe),Vista能运行Server端不能运行Client端,log提示是<string>的错误(??!!!)。XP则是什么都运行不了,直接死那儿了,也没有log。NND。
然后跟Rod同学探讨这个事情,我说,你看现在为Windows开发程序什么最快速部署方便?他说,.Net?我说.Net还需要.Net Framework,就现在XP上的版本和覆盖水准实在不行,我还不如直接去配置pygtk呢。
也是,什么好呢?Java需要JVM,Borland用VCL那套没有兴趣,MFC…我不如直接用Win32 SDK呢,况且手头也没有VS(话说我连个正常的Windows都没有,不愿折腾VS)。Adobe AIR貌似是个不错的选择,但是我还不会。Mozilla的extension,时间不够。
最后我说,看现在搞得,Windows作为一个最流行的桌面系统,为它开发一些GUI小工具这么麻烦…要全是Linux Desktop就好了。Windows上还是VB6最王道…Rod同学也得同意吧。
后记:
VB6出来的程序一直87运行时错误…据说是与卡巴有关,话说我身边还没有没装卡巴的Windows机器(这世道!),Shellex不玩了,去网上找一个现成的拉倒。Huanyu Zhao MM,非常抱歉。
下面是我的python代码,大家看看就得了,写得乱七八糟,不必太在意。
Server:
# -*- coding=utf-8 -*-
import SocketServer
import gtk, gtk.glade
import threading
import gobject
import sys
import threading
from random import randint
players = {
1: (1, "Shellex"),
2: (2, "小明"),
3: (3, "大名"),
4: (4, "大白菜"),
5: (5, "李鹏"),
6: (6, "普京"),
7: (7, "拉登"),
8: (8, "卡拉赞"),
9: (9, "太懒得"),
10: (10, "大泉"),
11: (11, "解决"),
12: (12, "可看"),
13: (13, "懒了"),
14: (14, "文我"),
15: (15, "轻轻"),
16: (16, "仍然"),
17: (17, "一样"),
18: (18, "喔喔"),
19: (19, "批评"),
20: (20, "信息"),
}
father = None
class waiter(SocketServer.BaseRequestHandler):
def handle(self):
global father
print "handle:"
while 1:
data = self.request.recv(32)
if data.strip() == 'bye':
return
if data.strip().isdigit():
father.add(int(data.strip()))
def finish(self):
print "finish"
def setup(self):
print "setup", self.client_address
class server(threading.Thread):
def __init__(self):
threading.Thread.__init__(self, name='server')
self.father = None
self.working = False
def run(self):
self.working = True
s = SocketServer.ThreadingTCPServer(("", 1234), waiter);
while self.working:
s.handle_request()
class main_win():
def refresh_btn_clicked_cb(self, widget):
self.queue = []
self.ui.get_widget('first_label').set_markup('%s' % '☣')
self.update()
def update(self):
model = self.ui.get_widget('queue_view').get_model()
model.clear()
for idx, each in enumerate(self.queue):
n, name = each
if idx == 0:
self.ui.get_widget('first_label').set_markup('%s' % self.num[n])
print each
col = model.append()
model.set(col, 0, n, 1, name, 2, "shit")
def add(self, id):
if not players.has_key(id):
return
if self.queue.count(self.players[id]) == 1:
pass
else:
self.queue.append(self.players[id])
print self.queue[-1]
self.update()
def start_server(self):
self.s = server()
self.s.win = self.ui
self.s.queue = self.queue
self.s.setDaemon(True)
self.s.start()
def toolbutton1_clicked_cb(self, widget):
self.add(randint(1, 20))
self.update()
def quit_me(self, args):
self.s.working = False
gtk.main_quit()
def init_tree_view(self):
# create columns
queue_view = self.ui.get_widget('queue_view')
renderer = gtk.CellRendererText()
queue_view.insert_column_with_attributes(-1, 'No.', renderer, text=0)
queue_view.insert_column_with_attributes(-1, 'Name', renderer, text=1)
queue_view.insert_column_with_attributes(-1, 'Time', renderer, text=2)
# create model
list_stroe = gtk.ListStore(
gobject.TYPE_STRING,
gobject.TYPE_STRING,
gobject.TYPE_STRING)
iter = list_stroe.append()
queue_view.set_model(list_stroe)
def __init__(self):
global father
# load ui and connect signals
self.ui = gtk.glade.XML('server.glade')
self.ui.signal_autoconnect(self)
self.win = self.ui.get_widget('main_win')
self.win.show()
self.win.connect("destroy", self.quit_me)
self.init_tree_view()
self.num = ['○','①','②','③','④','⑤','⑥','⑦','⑧','⑨','⑩','⑪','⑫','⑬','⑭','⑮','⑯','⑰','⑱','⑲','⑳']
self.players = players
self.queue = []
father = self
self.start_server()
try:
gtk.main()
except:
print "Shit. A fucking exception caught. Dying a death."
sys.exit(1)
if __name__ == '__main__':
gtk.gdk.threads_init()
mw = main_win()
Client:
import gtk, gtk.glade
import sys
import socket
class main_win():
def rush_btn_clicked_cb(self, widget):
if self.s != None:
self.s.send(self.id + '\n')
def connect_tbtn_clicked_cb(self, widget):
print self.do_connection(self.host, self.port)
def quit_me(self, args):
gtk.main_quit()
def do_connection(self, host, port):
res = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM)[0]
af, socktype, proto, canonname, sa = res
try:
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, proto)
except socket.error,(errno, err_msg):
self.s = None
self.ui.get_widget('status_label').set_text( err_msg)
try:
self.s.connect(sa)
except socket.error, (errno, err_msg):
self.s.close()
self.s = None
self.ui.get_widget('status_label').set_text(err_msg)
if self.s != None:
self.ui.get_widget('status_label').set_text('Connected!')
return self.s
def __init__(self):
global father
# load ui and connect signals
self.ui = gtk.glade.XML('client.glade')
self.ui.signal_autoconnect(self)
self.win = self.ui.get_widget('main_win')
self.win.show()
self.win.connect("destroy", self.quit_me)
# id
if len(sys.argv) < 2:
sys.exit()
self.id = sys.argv[1]
# connect
self.host = 'localhost'
self.port = 1234
self.do_connection('localhost', 1234)
try:
gtk.main()
except:
print "Shit. A fucking exception caught. Dying a death."
sys.exit(1)
if __name__ == '__main__':
gtk.gdk.threads_init()
mw = main_win()
