在python GUI中实现python函数

时间:2018-06-19 21:09:08

标签: python tkinter

我是python GUI的新手,以前从未使用过python GUI。我只是决定尝试一下。 这是我将本地日期时间转换为纪元的函数,eg.py是两个函数都位于的文件名

def epochConverter(a):
    return datetime(*a).timestamp()

此函数采用日期时间的两个参数,并以时间戳(毫秒)为单位返回

def DateExtraction(fromTime, toTime):
    convertedFromTime = int(epochConverter(fromTime)*1000)
    convertedtoTime = int(epochConverter(toTime)*1000)

    time = {'from':convertedFromTime,'to':convertedtoTime}
    return time

这按预期工作

print(DateExtraction((2018,6,8,0,0,0), (2018,6,8,1,0,0)))

现在,我想在python GUI中实现此功能,并且正在使用appjar库。这个简单的GUI代码看起来像这样

from appJar import gui
from eg import DateExtraction

class MyApplication():
    # Build the GUI
    def Prepare(self, app):
        # Form GUI
        app.setTitle("Simple Application")
        app.setFont(16)
        app.setStopFunction(self.BeforeExit)

        app.addLabel('oneTime',"From Time:", 0, 0)
        app.addEntry("fromTime", 0, 1)
        app.addLabel('twoTime',"To Time:", 1, 0)
        app.addEntry("toTime", 1, 1)
        app.addButtons(["Submit"], self.Submit, colspan=2)
        return app


    def Start(self):
        # Creates a UI
        app = gui()
        app = self.Prepare(app)
        self.app = app
        app.go()

    def BeforeExit(self):
        return self.app.yesNoBox("Confirm Exit", "Are you sure you want to exit?")


    def Submit(self, btnName):
        if btnName == "Submit":
            timefrom = self.app.getEntry("fromTime")
            timeto = self.app.getEntry("toTime")

            DateExtraction(timefrom, timeto)

if __name__ == '__main__':
    App = MyApplication()
    App.Start()

运行GUI时,我会同时填写两个文本字段

2018,6,8,0,0,0
2018,6,8,1,0,0

它会引发错误

TypeError: function takes at most 9 arguments (14 given)

为了以防万一

(2018,6,8,0,0,0)
(2018,6,8,1,0,0)

并再次引发相同的错误

type error, functions takes bla bla arguments (bla bla given)

我是python GUI的新手,欢迎任何建议。同样,有关tkinter实现以上功能的任何建议也将有所帮助。

1 个答案:

答案 0 :(得分:2)

我对appJar一无所知,但是文本输入字段的内容几乎肯定是字符串,而不是数字元组。因此,您最终没有呼叫epochConverter((2018,6,8,0,0,0)),而是呼叫epochConverter("(2018,6,8,0,0,0)"),这显然行不通。

具体问题是*a。对于一个由6个数字组成的元组,这将变成6个参数。对于14个字符的字符串,它将变成14个参数。

无论如何,您都需要编写一些代码来接收输入字符串,并将其解析为正确的格式。


做到这一点的一种方法(尽管是一种很怪诞的方法)是使用literal_eval,它可以将用作Python源代码文字的任何字符串转换为等效值:

timefrom = ast.literal_eval(self.app.getEntry("fromTime"))

您当然想要添加一些错误处理:

try:
    timefrom = ast.literal_eval(self.app.getEntry("fromTime"))
except SyntaxError as e:
    # pop up an error box, or whatever seems appropriate

此外,即使literal_eval成功,也仅意味着您具有一些有效的有效Python,而不一定是由6个整数组成的元组—例如,由两个字符串和一个复数。


更干净的方法是为您的特定格式编写解析器。这听起来可能有点吓人,但是您的格式却相当琐碎:您必须精确地使用6个整数,中间用逗号对不对?所以:

def parse_input_date(s):
    parts = s.split(',')
    if len(parts) != 6: raise ValueError(f'Wrong number of parts: {len(parts)} instead of 6')
    return [int(part) for part in parts]

所以现在:

timefrom = parse_input_date(self.app.getEntry("fromTime"))

再次,您将需要一些错误处理。在这种情况下,无效的字符串将为您提供ValueError而不是SyntaxError,但是在其他方面,它是相同的。

当然,即使现在我们可以确定我们有六个数字的列表,但您仍然可以从日期解析中得到一个错误-例如,用户可能要求输入2018,40,5,0,0,0


您可能还需要考虑将转换逻辑转移到epochConverterDateExtraction而不是GUI中。 \

例如,假设您想在命令行工具中使用相同的“引擎”代码。该命令行工具将从sys.argvinput()或类似的名称中获取参数,因此它最终还将以与GUI条目相同的格式获取一个字符串,对吗?因此,您可能希望它共享相同的字符串到元组转换逻辑。