猫史档案馆


【Python作品分享】文字作品转GUI的工具

用户:tq_xyytq_xyy查看:2 回复:2 评论:2 创建时间:2020-09-05T19:31:45


你是否还在创作命令行文字作品,游戏,工具呢?

你是否想有简单易懂的图形界面呢?

这些都不是问题!

先来看看效果:

(以官方作品大黄鸡的发动机为例)

center_image

生成后的代码时这样子的:

import tkinter as __gui_tk
from tkinter import ttk as __gui_ttk
from tkinter.messagebox import showinfo as __gui_showstring_orig

# 实现函数

def __gui_showstring(*values, title='', parent=None, sep='', end='', file=None, flush=False):
    output = sep.join(values) + end
    if file == None:
        __gui_showstring_orig(title, output, parent=parent)
    else:
        file.write(output)
        if flush:
            file.flush()

def __gui_askstring(title, prompt, initialvalue=None, parent=None):
    def cancel(event=None):
        nonlocal result
        result = initialvalue
        top.destroy()
    def ok(event=None):
        value = entry.get()
        if value == '':
            value = initialvalue
        nonlocal result
        result = value
        top.destroy()
    result = None
    top = __gui_tk.Toplevel(parent)
    top.title(title)
    screen_width = top.winfo_screenwidth()
    screen_height = top.winfo_screenheight()
    top.geometry('+%d+%d' % ((screen_width) / 2 - 110,(screen_height) / 2 - 50))
    __gui_ttk.Label(top, text=prompt, font=(None, 13)).grid(column=0, row=0, padx=3, pady=3)
    entry = __gui_ttk.Entry(top, show=None)
    entry.grid(column=0, row=1, padx=10, columnspan=3)
    entry.focus()
    btn1 = __gui_ttk.Button(top, text='取消', command=cancel, default='active')
    btn2 = __gui_ttk.Button(top, text='确定', command=ok)
    btn1.grid(column=0, row=2, padx=10)
    btn2.grid(column=1, row=2, padx=10)
    top.protocol("WM_DELETE_WINDOW", cancel)
    top.bind("<Return>", ok)
    top.bind("<Escape>", cancel)
    top.wait_window(top)
    return result

# 常量定义
GUI_TITLE = '提示'    # 窗口标题
GUI_PROMPT = '请输入:'    # 默认提示符
GUI_WINDOW = __gui_tk.Tk()
GUI_WINDOW.withdraw()

# 以下是代码逻辑实现


# 寻找发动机
# 试试创作属于你自己的文字游戏吧!
__gui_showstring('Hi,训练师,欢迎进入大黄鸡的飞行空间!', title=GUI_TITLE, parent=GUI_WINDOW)
__gui_showstring('准备好出发冒险了吗?', title=GUI_TITLE, parent=GUI_WINDOW)
__gui_showstring('1、准备好了,继续!', title=GUI_TITLE, parent=GUI_WINDOW)
__gui_showstring('2、并没有,我要傲娇地再等等~', title=GUI_TITLE, parent=GUI_WINDOW)
start = __gui_askstring(prompt='请输入数字选项:', title=GUI_TITLE, parent=GUI_WINDOW, initialvalue='')
while (start != '1'):
    start = __gui_askstring(prompt='现在准备好了吗?请输入数字选项:', title=GUI_TITLE, parent=GUI_WINDOW, initialvalue='')
__gui_showstring('糟糕,大黄鸡的发动机坏了,你能帮它找一个新的发动机吗?', title=GUI_TITLE, parent=GUI_WINDOW)
__gui_showstring('1. 好,包在我身上!', title=GUI_TITLE, parent=GUI_WINDOW)
__gui_showstring('2. 不,我懒得找~', title=GUI_TITLE, parent=GUI_WINDOW)
start_1 = __gui_askstring(prompt='请输入数字选项:', title=GUI_TITLE, parent=GUI_WINDOW, initialvalue='')
if (start_1 == '2'):
    __gui_showstring('懒惰是没有办法在冒险中生存下来的,很遗憾,你没有通过考验。', title=GUI_TITLE, parent=GUI_WINDOW)
elif (start_1 == '1'):
    __gui_showstring('据说在这两个地方找到发动机的几率比较大,你想去哪里找呢?。', title=GUI_TITLE, parent=GUI_WINDOW)
    __gui_showstring('1. 飞机工厂(这里应该会有发动机吧)。', title=GUI_TITLE, parent=GUI_WINDOW)
    __gui_showstring('2. 科学走廊。(感觉不会有发动机)', title=GUI_TITLE, parent=GUI_WINDOW)
    place = __gui_askstring(prompt='请输入数字选项:', title=GUI_TITLE, parent=GUI_WINDOW, initialvalue='')
    if (place == '1'):
        __gui_showstring('你来到了飞机工厂...', title=GUI_TITLE, parent=GUI_WINDOW)
        __gui_showstring('发现这里竟然一片狼藉!你没有找到发动机~', title=GUI_TITLE, parent=GUI_WINDOW)
        __gui_showstring('1. 这是遭小偷了?算了,去科学走廊看看!', title=GUI_TITLE, parent=GUI_WINDOW)
        __gui_showstring('2. 什么破工厂,哪有什么发动机啊!喵的吧!', title=GUI_TITLE, parent=GUI_WINDOW)
        place_1 = __gui_askstring(prompt='请输入数字选项:', title=GUI_TITLE, parent=GUI_WINDOW, initialvalue='')
        if (place_1 == '1'):
            __gui_showstring('你来到了科学走廊...', title=GUI_TITLE, parent=GUI_WINDOW)
            __gui_showstring('发现飞电鼠正在科学走廊搞破坏!刚刚飞机工厂肯定也是它干的', title=GUI_TITLE, parent=GUI_WINDOW)
            __gui_showstring('1. 抓住飞电鼠再说。', title=GUI_TITLE, parent=GUI_WINDOW)
            __gui_showstring('2. 再大的事也不能阻挡我找发动机。', title=GUI_TITLE, parent=GUI_WINDOW)
            place_2 = __gui_askstring(prompt='请输入数字选项:', title=GUI_TITLE, parent=GUI_WINDOW, initialvalue='')
            if (place_2 == '1'):
                __gui_showstring('成功抓住飞电鼠!还发现藏在它身上的发动机一枚。', title=GUI_TITLE, parent=GUI_WINDOW)
                __gui_showstring('任务完成!', title=GUI_TITLE, parent=GUI_WINDOW)
            elif (place_2 == '2'):
                __gui_showstring('一点正义感都没有,大黄鸡才不要带你去冒险呢!游戏结束!', title=GUI_TITLE, parent=GUI_WINDOW)
            else:
                __gui_showstring('随便行动是找不到发动机的...你在源码世界里迷路了...', title=GUI_TITLE, parent=GUI_WINDOW)
        elif (place_1 == '2'):
            __gui_showstring('鉴于你对游戏产生了质疑,不跟你玩啦~游戏结束,再见!', title=GUI_TITLE, parent=GUI_WINDOW)
        else:
            __gui_showstring('随便行动是找不到发动机的...你在源码世界里迷路了...', title=GUI_TITLE, parent=GUI_WINDOW)
    elif (place == '2'):
        __gui_showstring('糟糕!你发现飞电鼠正在破坏科学走廊!', title=GUI_TITLE, parent=GUI_WINDOW)
        __gui_showstring('1. 抓住飞电鼠再说。', title=GUI_TITLE, parent=GUI_WINDOW)
        __gui_showstring('2. 再大的事也不能阻挡我找发动机。', title=GUI_TITLE, parent=GUI_WINDOW)
        place_2 = __gui_askstring(prompt='请输入数字选项:', title=GUI_TITLE, parent=GUI_WINDOW, initialvalue='')
        if (place_2 == '1'):
            __gui_showstring('恭喜你抓到飞电鼠,成功保护了科学走廊。', title=GUI_TITLE, parent=GUI_WINDOW)
            __gui_showstring('飞电鼠藏起了大黄鸡发动机,你找到了!恭喜你完成任务!', title=GUI_TITLE, parent=GUI_WINDOW)
        elif (place_2 == '2'):
            __gui_showstring('一点正义感都没有,大黄鸡才不要带你去冒险呢!游戏结束!', title=GUI_TITLE, parent=GUI_WINDOW)
        else:
            __gui_showstring('随便行动是找不到发动机的...你在源码世界里迷路了...', title=GUI_TITLE, parent=GUI_WINDOW)
    else:
        __gui_showstring('看来你和发动机没有缘分啊,游戏结束', title=GUI_TITLE, parent=GUI_WINDOW)
else:
    __gui_showstring('随便行动是找不到发动机的...你在源码世界里迷路了...', title=GUI_TITLE, parent=GUI_WINDOW)
# __gui_askstring(prompt=GUI_PROMPT, title=GUI_TITLE, parent=GUI_WINDOW, initialvalue='')

是不是有亿点长?没事,又不是要你自己打,都是全自动生成的!

只要你的代码书写规范,都可以正常转换。

源代码

源代码如下:

import re

headers = '''
# This is @generated code; do not edit!

import tkinter as __gui_tk
from tkinter import ttk as __gui_ttk
from tkinter.messagebox import showinfo as __gui_showstring_orig

# 实现函数

def __gui_showstring(*values, title='', parent=None, sep='', end='', file=None, flush=False):
    output = sep.join(values) + end
    if file == None:
        __gui_showstring_orig(title, output, parent=parent)
    else:
        file.write(output)
        if flush:
            file.flush()

def __gui_askstring(title, prompt, initialvalue=None, parent=None):
    def cancel(event=None):
        nonlocal result
        result = initialvalue
        top.destroy()
    def ok(event=None):
        value = entry.get()
        if value == '':
            value = initialvalue
        nonlocal result
        result = value
        top.destroy()
    result = None
    top = __gui_tk.Toplevel(parent)
    top.title(title)
    screen_width = top.winfo_screenwidth()
    screen_height = top.winfo_screenheight()
    top.geometry('+%d+%d' % ((screen_width) / 2 - 110,(screen_height) / 2 - 50))
    __gui_ttk.Label(top, text=prompt, font=(None, 13)).grid(column=0, row=0, padx=3, pady=3)
    entry = __gui_ttk.Entry(top, show=None)
    entry.grid(column=0, row=1, padx=10, columnspan=3)
    entry.focus()
    btn1 = __gui_ttk.Button(top, text='取消', command=cancel, default='active')
    btn2 = __gui_ttk.Button(top, text='确定', command=ok)
    btn1.grid(column=0, row=2, padx=10)
    btn2.grid(column=1, row=2, padx=10)
    top.protocol("WM_DELETE_WINDOW", cancel)
    top.bind("<Return>", ok)
    top.bind("<Escape>", cancel)
    top.wait_window(top)
    return result

# 常量定义
GUI_TITLE = '提示'    # 窗口标题
GUI_PROMPT = '请输入:'    # 默认提示符
GUI_WINDOW = __gui_tk.Tk()
GUI_WINDOW.withdraw()

# 以下是代码逻辑实现
'''

def repl(match):
    args = match.group(1)
    if 'print' in match.group(0) and 'input' in match.group(0):
        args = re.sub(r'input\(([\W\w]*)\)', repl, args)
        rep = '__gui_showstring(' + args +', title=GUI_TITLE, parent=GUI_WINDOW)'
    elif match.group(0).startswith('print'):
        if args == '':
            args = "''"
        rep = '__gui_showstring(' + args +', title=GUI_TITLE, parent=GUI_WINDOW)'
    elif match.group(0).startswith('input'):
        if args == '':
            args = 'GUI_PROMPT'
        rep = '__gui_askstring(prompt=' + args + ', title=GUI_TITLE, parent=GUI_WINDOW, initialvalue=\'\')'
    else:
        rep = match.group(0)
    return rep

def replaceline(line):
    newline = re.sub(r'print\(([\W\w]*)\)', repl, line)
    if newline != line:
        return newline
    newline = re.sub(r'input\(([\W\w]*)\)', repl, line)
    if newline != line:
        return newline
    return line

def generate(string):
    res = ''
    res += headers
    for line in string.splitlines():
        rep = replaceline(line)
        res += rep
        res += '\n'
    return res

怎么样,是不是比你自己敲代码好多了。

教程

使用起来像这样:

code = '''
# 这里写你的代码
print('Hello, World')
'''
program = generate(code)
print(program)

输出为:

# This is @generated code; do not edit!

import tkinter as __gui_tk
from tkinter import ttk as __gui_ttk
from tkinter.messagebox import showinfo as __gui_showstring_orig

# 实现函数

def __gui_showstring(*values, title='', parent=None, sep='', end='', file=None, flush=False):
    output = sep.join(values) + end
    if file == None:
        __gui_showstring_orig(title, output, parent=parent)
    else:
        file.write(output)
        if flush:
            file.flush()

def __gui_askstring(title, prompt, initialvalue=None, parent=None):
    def cancel(event=None):
        nonlocal result
        result = initialvalue
        top.destroy()
    def ok(event=None):
        value = entry.get()
        if value == '':
            value = initialvalue
        nonlocal result
        result = value
        top.destroy()
    result = None
    top = __gui_tk.Toplevel(parent)
    top.title(title)
    screen_width = top.winfo_screenwidth()
    screen_height = top.winfo_screenheight()
    top.geometry('+%d+%d' % ((screen_width) / 2 - 110,(screen_height) / 2 - 50))
    __gui_ttk.Label(top, text=prompt, font=(None, 13)).grid(column=0, row=0, padx=3, pady=3)
    entry = __gui_ttk.Entry(top, show=None)
    entry.grid(column=0, row=1, padx=10, columnspan=3)
    entry.focus()
    btn1 = __gui_ttk.Button(top, text='取消', command=cancel, default='active')
    btn2 = __gui_ttk.Button(top, text='确定', command=ok)
    btn1.grid(column=0, row=2, padx=10)
    btn2.grid(column=1, row=2, padx=10)
    top.protocol("WM_DELETE_WINDOW", cancel)
    top.bind("<Return>", ok)
    top.bind("<Escape>", cancel)
    top.wait_window(top)
    return result

# 常量定义
GUI_TITLE = '提示'    # 窗口标题
GUI_PROMPT = '请输入:'    # 默认提示符
GUI_WINDOW = __gui_tk.Tk()
GUI_WINDOW.withdraw()

# 以下是代码逻辑实现

# 这里写你的代码
__gui_showstring('Hello, World', title=GUI_TITLE, parent=GUI_WINDOW)

很简单,对不对。

可以看到,注释和空行被最大限度的保留了。

FAQ

: 如何更改窗口标题?

: 很简单,修改常量中的 GUI_TITLE 即可。

 

问: 为什么定义的函数和模块都带上 __ 前缀?

答: 因为怕你们重名。

 

问: 为什么我的代码运行失败?

答: 请见下一个问题。

 

问: 为什么我的代码无法完全转换?

答: 可能是因为无法识别多行字符串,可以用抽象语法树(AST)来解决这个问题。

     但是注释和空行会全部消失,并且可能出现各种奇奇怪怪的问题。

 

问: 如果上面没有我想要的答案呢?

答: 请在评论区下留言!


回复

上一页1 页 / 共 1下一页
蒟蒻OIer1048576蒟蒻OIer1048576

建议价格反编译

点赞0


评论


禁止挖坟后果自负禁止挖坟后果自负

GUI是啥

点赞0


评论