问题 我如何实际进入GUI编程?


我是一个本科生。几年前我在学校接触过基本编程。到目前为止,我已经了解了Core Java,Core Python和基本的C和C ++。

每次我从一些GUI编程开始,以便我可以从我的一个项目开始,我会被要完成的数量,要学习的API,MVC架构和程序员谈论的所有内容,事件处理等所困惑。等等

研究了awt并挥了一会儿。试过Qt和Gtk的手,找不到太多的文档。试图理解pygame。我知道核心语言,最终到了同一个地方。

我的zenwalk Linux上的Tkinter已经破了,所以在Tkinter解释说我已经拥有一本关于python的书之后就永远无法启动它。

但我最终只是在对语言的基本理解的同一个地方。

想要重新开始,现在认真。我想选择python。我该如何研究GUI编程?

我需要一些互联网资源和方向,以便我不会在同一个地方!


2895
2017-12-07 19:42


起源

Python中的图形编程?真的吗? - 3Dave
@David Lively - 从那里出发有什么问题?他显然是图形的初学者,似乎只对编程有基本的了解(对不起,如果我错了)。 - gahooa
使用图形编程,您指的是图形用户界面编程吗?或者你的意思是计算机图形,如电子游戏和动画电影? - Josef Grahn
通过图形编程我的意思是基本的应用程序开发。 GUI。不是3D API - Nitish Upreti
重新“Qt <...>找不到太多的文件”:这是一种玩笑吗? (doc.trolltech.com/4.6/index.html)。 Qt的文档是我见过的最好的api文档之一。他们在记录框架方面做得很好 那 大。 - shylent


答案:


既然听起来你想要Python GUI编程,我可以建议 PyGTK的

对于熟悉Python的人来说,这可能是一个非常好的起点,并希望从一些基本的GUI应用程序开始。 GTK有时很复杂,但有了PyGTK,你可以学习很多开源示例应用程序,从简单到复杂。

编辑:本教程 来自LinuxJournal 看起来很有帮助。

编辑2:这是 来自PyGTK网站的教程,和 我从谷歌随机发现的另一个教程 (看起来整个博客对你想做的事情非常有用,实际上)。最后,底部的片段 这一页 Ubuntu论坛提供的帮助可能会有所帮助。


5
2017-12-07 19:59



谢谢雷诺兹。你的帖子很有帮助。 :) - Nitish Upreti
我可以为pygtk提供更多资源和电子书吗? - Nitish Upreti
试图为你添加更多,请告诉我这些是否有帮助。 - Reynolds


如果你更倾向于游戏......

我建议你安装 Pygame的 和 蟒蛇,并通过他们的 教程。选择一个简单的游戏或图形项目并编程吧!


2
2017-12-07 19:45





对于Python GUI我喜欢wxPython(www.wxpython.org)。简单的控件和布局很容易上手。它也是跨平台的。那里有很多教程。只需搜索wxPython教程。


2
2017-12-07 20:09



我自己没有用过它,但我经常听到有关wxPython的好消息。如果你发现PyGTK令人沮丧,这可能是一个很好的替代解决方案,虽然我不能给你任何第一手经验。 - Reynolds
wxPython很棒!我有一段时间没有使用它,但文档过去相当不完整。它曾经迫使你回到wxWindows C ++ API文档,如果你不了解C ++,这是一个问题。 - Chinmay Kanchi


许多人推荐了wxPython,我的热情是他的第二个 - 这是一个很棒的框架;它还包括一个严肃的演示(带代码和实时应用程序),这对学习非常有价值。

现在,小心!

将末端与手段混淆是非常简单的。编程GUI可能非常有吸引力,但效率不高。在我的早期,我花了几天时间试图获得一个简单的绘图应用程序(重新发明轮子);用于求解二次方程的简单GUI;通过点击地图上的某些位置等来调用数据库查询的简单GUI。在这段时间里,我从未真正挖掘过算法或更普遍和有效的计算机科学和计算机工程主题。回想起来,我应该有。当然,我确实学到了很多,我并不完全后悔,但我的建议是:首先担心你的算法,然后再考虑你的界面。这可能不适用于每个领域(我是NASA的工程师)。现在我使用数字运算应用程序,没有任何GUI;我不认为他们需要他们!

无论如何,我只是想用GUI编程分享我的两分钱 - 玩得开心,但不要过分。


2
2017-12-08 06:32



关于Web界面的最好的事情是它们的最小设计(由于Web编程的限制)。如果Larry和Page在编写谷歌界面时拥有的不仅仅是基本的网页设计技能,那么它可能会比结果更糟糕。少即是多。它也更便宜。 - wisty


你是什​​么意思“图形”?你的意思是游戏图形,还是仅仅意味着用户界面代码(表单,网页,那种东西)?在游戏图形的情况下,可以制作简单的东西是有限的,但是 http://www.gamedev.net例如,在2d和3d引擎上有大量的介绍性文章。对于应用程序行中的更多内容,您可能只需下载Visual Studio或Eclipse,并花一些时间查看由其所见即所得编辑器自动生成的代码。


1
2017-12-07 19:47





我知道你的感受 - 我在CS学位期间学到了很多计算机编程,但很少有关于GUI的知识。我最终为自己的Cocoa / Objective-C教学了一个项目。可可是 精彩 对于GUI的东西,但往往是一个陡峭的学习曲线的皇家痛苦。如果您对C编程没有任何经验,请不要打扰。

第一步:熟悉MVC(模型/视图/控制器)设计约定,因为几乎每个GUI框架都会引用它。 Google it - 它有很多资源。我的快速,简单的定义是:

模型级别定义应用程序的数据或逻辑模型。对于Web应用程序,这将是数据库。对于游戏,它可以是存储数据和游戏逻辑/规则。

视图级别是用户看到并与之交互的(GUI)。

控制器级别是连接两者的逻辑。例如,控制器知道当您单击视图级别中的“开始游戏”按钮时,它会对模型执行一些操作(例如,设置棋盘和玩家。)

第二步:找出你想要的东西。您是否特别对桌面应用程序感兴趣?游戏?网络应用?

如果您想要做的主要是能够开发人们实际使用的东西,另一种选择是学习Web开发框架。框架使您的工作变得简单。我个人喜欢Django,如果你知道一点点Python和一些HTML以及一些关于MVC的东西,你可以快速拿起它。 (只是不要混淆,因为Django称视图实际上是一个控制器。)

如果你想做的是游戏或图形/动画的东西,请查看pygame。我把它用于一个课堂项目 - 基本上是在几周内教给我自己 - 而且效果很好。

我会说尽可能远离Java Swing / awt /等。

我听说过关于wxPython的好东西 - 我几乎最终使用它而不是Cocoa,因为wx的东西可以用几种编程语言,而且它们都是跨平台的。

祝你好运!要坚强!我知道这真是令人生畏,因为我一直在你的鞋子里。你可以通过一些工作,练习和动力去做。


1
2017-12-08 05:43



顺便说一下为什么要远离Java Swing / awt / etc? - Nitish Upreti
根据我的经验,用Java开发GUI应用程序是一个巨大的痛苦。很难做出一个非常好看的界面,很难让你做你想做的事情,你必须为基本的GUI东西编写大量的代码。 (就像每个事件的事件监听器等) - Ellie P.
加上AWT现在已经过时了。 - Reynolds


对于GUI工作一般

少即是多

GUI工作(即使在高效的框架中)与使用牙刷绘制艾菲尔铁塔一样有趣和高效。寻求最小的设计。

避免像瘟疫一样的国家

您是将状态置于GUI中还是模型中?如果将它放在GUI中,您将会陷入冗余和不一致的代码路径。如果将其放入模型中,则当GUI无法从模型更新时,您会面临一个过于复杂的系统风险。两个都很糟糕。

wxPython的

如果你想学习wxPython,我注意到以下几个陷阱:

教程

使用本教程 - http://wiki.wxpython.org/AnotherTutorial

这是我发现的最好的一个。

但请记住切换行号,以便轻松粘贴。

活动

事件有点像异常,它们用于使事物互动。

在一个vanilla python程序中,你写了类似的东西:

 def doit(i): 
      print 'Doing i = ',i

for i in range(10):
    doit()

print 'Results = ',result

在GUI中,您执行以下操作:

 def doit(event): 
     print 'An event',event,'just happened!'
     event.Skip()

import wx
app = wx.App() 
frame = wx.Frame(None, -1, 'The title goes here') 
frame.Bind(wx.EVT_KEY_DOWN, doit)
frame.Show()
app.MainLoop()

每次用户按下键时,都会引发一个事件。以来 frame 与事件有关(frame.Bind(wx.EVT_KEY_DOWN, doit)), 功能 doit 将以事件作为参数调用。

在gui中打印到stderr并不是太热,但是也可以调用对话框,或者执行任何你想要的操作。

此外,您可以使用计时器生成自己的事件。

应用程序,框架,Windows,面板和Sizer

一切都有父母。如果事件被提出,并且孩子没有跳过它(使用 event.Skip()),然后父母也必须处理该事件。这类似于提升到更高级别功能的异常。

一个 wx.App 就像Main函数一样。

wx.Window 是不是真的用过。 Stuff继承自它,它有调整大小和布局的所有方法,但你不需要知道。

wx.Frame 是一个浮动框架,就像Firefox中的主窗口一样。您将在基本应用程序中拥有主框架。如果您想编辑多个文件,那么您可能还有更多文件。 wx.Frame通常不会有父母。

wx.Panel 是父窗口的一部分。框架内可以有多个面板。面板可以有一个 wx.Frame 作为父母,或者它可能是另一个小组的孩子。

wx.Sizers 用于自动布局框架(或其他面板)内的面板。

码:

def doit1(event):
    print 'event 1 happened'

def doit2(event): 
     print 'event 2 happened'

import wx
app = wx.App()
frame = wx.Frame(None, -1, 'The title goes here') 

panel_1 = wx.Panel(frame,-1,style=wx.SIMPLE_BORDER) 
panel_2 = wx.Panel(frame,-1,style=wx.SIMPLE_BORDER)

panel_1.Bind(wx.EVT_KEY_DOWN, doit1)
panel_2.Bind(wx.EVT_KEY_DOWN, doit2)

panel_1.SetBackgroundColour(wx.BLACK)
panel_2.SetBackgroundColour(wx.RED)

box = wx.BoxSizer(wx.HORIZONTAL)
box.Add(panel_1,1,wx.EXPAND)
box.Add(panel_2,1,wx.EXPAND)

frame.SetSizer(box)

frame.Show()

app.MainLoop()

我一直很糟糕,并没有使用OOP做法。请记住,即使你在大多数情况下讨厌OO,GUI编程也是OOP真正闪耀的地方。

MCV

我没有得到MCV。我认为你不需要MCV。我认为MW(模型 - 小部件)框架很好。

例如 - 编辑同一段文本的2帧:

class Model(object):
    def __init__(self):
        self.value = 'Enter a value'
        self.listeners = []

    def Add_listener(self,listener):
        self.listeners.append(listener)

    def Set(self,new_value):
        self.value = new_value
        for listener in self.listeners:
            listener.Update(self.value)


import wx
app = wx.App() 

class CVFrame(wx.Frame):
    def __init__(self, parent, id, title, model):
        wx.Frame.__init__(self, parent, id, title, size = (100,100))
        self.button = wx.Button(self, -1, 'Set model value')
        self.textctrl = wx.TextCtrl(self, -1,model.value)
        self.button.Bind(wx.EVT_BUTTON,self.OnSet)

        self.model = model
        model.Add_listener(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.button,0,wx.EXPAND)
        sizer.Add(self.textctrl,1,wx.EXPAND)

        self.SetSize((300,100))
        self.SetSizer(sizer)
        self.Center()
        self.Show()

    def OnSet(self,event):
        self.model.Set(self.textctrl.GetValue())

    def Update(self,value):
        self.textctrl.SetValue(value)

model = Model()
frame1 = CVFrame(None, -1, 'Frame 1',model)
frame2 = CVFrame(None, -1, 'Frame 2',model) 
app.MainLoop()

wxPython有一个监听器 - 订阅者框架,这是我刚刚勾勒出的模型的更好版本(它使用弱引用,因此删除的侦听器不会挂起,等等),但这应该有助于你理解。


1
2017-12-08 05:23



不应该是MVC,而不是MCV? - Joel