【问题标题】:Python code works as module but not as classPython代码作为模块而不是类
【发布时间】:2016-06-21 13:15:37
【问题描述】:

我试图找出原因,但可能不知道正确的问题。我有一个项目,我正在尝试为我的汽车创建仪表板。问题是,当我尝试让另一个类中的画布对象出现时,我的 GUI 启动但不显示任何内容。如果我在不要求画布出现的情况下启动 GUI,则 GUI 工作并显示屏幕。我是 Python 新手。我的版本是 3.5

我的主程序:

from tkinter import*
from helperThingys import Helpers

root = Tk()
root.geometry("800x480")

bgLeft = Frame(root, bg="black", width=200, height=480)
bgLeft.pack_configure(fill=BOTH, expand=1, side=LEFT)
bgMiddle = Frame(root, bg="black", width=400, height=480)
bgMiddle.pack_configure(fill=BOTH, expand=1, side=LEFT)
bgRight = Frame(root, bg="black", width=200, height=480)
bgRight.pack_configure(fill=BOTH, expand=1, side=LEFT)

# These are really gif images read to labels to be able to grid them
# now just plain text labels for convenience. 
label_4hi = Label(bgLeft, text="ok", bg="green")
label_4lo = Label(bgLeft, text="ok", bg="green")
label_lock = Label(bgLeft, text="ok", bg="green")
label_batt = Label(bgMiddle, text="ok", bg="red")
label_fuelF = Label(bgLeft, text="ok", bg="orange")
label_glow = Label(bgLeft, text="ok", bg="yellow")
label_hb = Label(bgMiddle, text="ok", bg="blue")
label_indL = Label(bgMiddle, text="ok", bg="green")
label_indR = Label(bgMiddle, text="ok", bg="green")
label_lowFuel = Label(bgLeft, text="ok", bg="red")
label_lowOil = Label(bgLeft, text="ok", bg="red")
label_park = Label(bgMiddle, text="ok", bg="red")
label_pwrS = Label(bgLeft, text="ok", bg="red")
label_rFog = Label(bgLeft, text="ok", bg="orange")
label_temp = Label(bgLeft, text="ok", bg="red")
label_gauge = Label(bgMiddle, text="ok", bg="red")

# Middle frame
bgMiddle.rowconfigure(0, minsize=46, weight=1)
bgMiddle.rowconfigure(1, minsize=217, weight=5)
bgMiddle.rowconfigure(2, minsize=217, weight=5)
bgMiddle.columnconfigure(0, minsize=80)
bgMiddle.columnconfigure(1, minsize=80)
bgMiddle.columnconfigure(2, minsize=80)
bgMiddle.columnconfigure(3, minsize=80)
bgMiddle.columnconfigure(4, minsize=80)

label_indL.grid(row=0, column=0, sticky=E+N+W)
label_hb.grid(row=0, column=1, sticky=E+N+S+W)
label_park.grid(row=0, column=2, sticky=E+N+S+W)
label_batt.grid(row=0, column=3, sticky=E+N+S+W)
label_indR.grid(row=0, column=4, sticky=E+N+S+W)

# Left frame
bgLeft.rowconfigure(0, minsize=46, weight=1)
bgLeft.rowconfigure(1, minsize=46, weight=1)
bgLeft.rowconfigure(2, minsize=46, weight=1)
bgLeft.rowconfigure(3, minsize=46, weight=1)
bgLeft.rowconfigure(4, minsize=46, weight=1)
bgLeft.columnconfigure(0, minsize=100)
bgLeft.columnconfigure(1, minsize=100)

label_4hi.grid(row=0, column=0, sticky=E+N+S+W)
label_4lo.grid(row=0, column=1, sticky=E+N+S+W)
label_lock.grid(row=1, column=0, sticky=E+N+S+W)
label_pwrS.grid(row=1, column=1, sticky=E+N+S+W)
label_rFog.grid(row=2, column=0, sticky=E+N+S+W)
label_lowFuel.grid(row=2, column=1, sticky=E+N+S+W)
label_lowOil.grid(row=3, column=0, sticky=E+N+S+W)
label_temp.grid(row=3, column=1, sticky=E+N+S+W)
label_fuelF.grid(row=4, column=0, sticky=E+N+S+W)
label_glow.grid(row=4, column=1, sticky=E+N+S+W)

# Middle frame
speedo = helpers.Gauge()
speedo.makeGauge(bgMiddle, 150, "speed")
speedo.grid(row=1, columnspan=5, sticky=E+N+S+W)
#label_gauge.grid(row=1, columnspan=5, sticky=E+N+S+W)

# Right Frame

#oilPres = Gauge(bgRight, 150, "oilPres")

root.mainloop()

这里是 helperThingys 包中的“helpers.py”。

from tkinter import Canvas

class Gauge(Canvas):

    def __init__(self):
        Canvas.__init__(self)
        pass

    def makeGauge(self, window, value, gaugeType):
        if gaugeType == "speed":
            baseCanvas = Canvas(window, bg="black", width=400, height=217,
                                highlightthickness=0)
            baseCanvas.create_arc([10, 5, 390, 395], start=0, extent=180,
                                  fill="white")
            return baseCanvas

我使用画布作为仪表的背景。奇怪的是,当它不是一个类而是一个模块时,这个“helpers.py”工作并为我的 GUI 创建了画布:

def makeGauge(self, window, value, gaugeType):
    if gaugeType == "speed":
        baseCanvas = Canvas(window, bg="black", width=400, height=217,
                                highlightthickness=0)
        baseCanvas.create_arc([10, 5, 390, 395], start=0, extent=180,
                                  fill="white")
        return baseCanvas

... 以此类推(该模块与 GUI 位于同一个包中)。这就是为什么我知道画布可以与 GUI 一起使用。在课堂上使用它们时我做错了什么?

感谢您的回答。

【问题讨论】:

  • 是否真的需要所有这些代码来复制问题?请删除与问题不严格相关的任何内容。见stackoverflow.com/help/mcve
  • 感谢您的评论,不确定真正需要多少代码,因为它会影响 GUI 中的项目大小。编辑了一些不必要的。 (我认为)。

标签: python user-interface tkinter python-3.5 tkinter-canvas


【解决方案1】:

您的问题是Gauge 两者都是Canvas 的子类并且 创建一个或多个其他画布(奇怪的是,它们是某个其他窗口的子类)。

当您调用makeGauge 时,这将创建第二个画布并返回它。但是,您不保存引用,并且您永远不会在第二个画布上调用 packplacegrid,因此它永远不会出现。

我不知道你打算用这两张画布做什么,但我猜你真的只想要一张。我建议制作这样的类,在创建画布时传递所有参数,以便您可以一步创建仪表:

class Gauge(Canvas):
    def __init__(self, parent, value, gaugeType):
        Canvas.__init__(self, parent)
        self.makeGauge(value, gaugeType)

    def makeGauge(self, value, gaugeType):
        if gaugeType == "speed":
            self.configure(bg="black", width=400, height=217,
                           highlightthickness=0)
            self.create_arc([10, 5, 390, 395], start=0, extent=180,
                            fill="white")

        elif gaugeType == "rpm":
            ...

speedo = Gauge(bgMiddle, 150, "speed")
speedo.grid(...)

如果你想保留两个画布,或者你决定让Gauge从其他东西继承,你需要保存makeGauge返回的引用,然后将其添加到显示中:

gauge = speedo.makeGauge(bgMiddle, 150, "speed")
gauge.grid(row=1, columnspan=5, sticky=E+N+S+W)

【讨论】:

  • @TonninSeteli:是的,这是另一种解决方案。但是,您最终得到的画布对象数量是您需要的两倍。
  • 我认为我的问题是我没有保存参考。无法让它与上面的代码一起工作,但它在像这样调用时可以正常工作:speedo = Helpers.Gauge().makeGauge(bgMiddle, 150, "speed")
  • 但是 baseCanvas 对象在返回并离开 Helpers.py 后是否仍然“活着”?
  • @TonninSeteli:它仍然作为一个对象存在并且占用少量内存。
  • 主程序中一个Canvas对象如何调用makeGauge函数?那么它是否应该只使用:speedo.makeGauge(*args)?尝试学习制作没有垃圾对象的“干净”代码。学徒感谢师父。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 2022-01-25
  • 2023-03-28
相关资源
最近更新 更多