RSS Forums RSS
Please support our Python advertiser: Programming Forums
Views: 1593 | Replies: 8
Reply
Join Date: Mar 2006
Posts: 56
Reputation: Blujacker is an unknown quantity at this point 
Rep Power: 3
Solved Threads: 0
Blujacker Blujacker is offline Offline
Junior Poster in Training

wx.Paint

  #1  
Apr 15th, 2007
Hi, it's me again and i have new question:


This is my code:
# -*- coding: cp1250 -*-

import  string as _string
import  time as _time
import  wx
from math import*


class Canvas:
    def __init__(self,parent):
        self.okno=parent
        self.okno.SetBackgroundColour("#FCFCFE")
        self.radic = wx.FlexGridSizer(2,2,0,0)
        self.canvas = wx.ScrolledWindow(self.okno, -1)
       
        self.canvas.EnableScrolling(True, True)
        
        
        self.P_WIDTH = 1000
        self.P_HEIGHT = 1000
        self.canvas.SetScrollbars(20, 20, self.P_WIDTH/20, self.P_HEIGHT/20)

        self.radic.Add(self.canvas, 1, wx.EXPAND)
        self.radic.Add((0,0))
        sizer=wx.BoxSizer(wx.VERTICAL)
        self.radic.Add(sizer, 1, wx.EXPAND)
        self.radic.Add((0,0))
        self.radic.AddGrowableRow(0, 1)
        self.radic.AddGrowableCol(0, 1)
        sizer2=wx.BoxSizer(wx.HORIZONTAL)
        sizer2.Add(wx.StaticText(self.okno,label="  f(y)=   "),0,wx.ALIGN_CENTER)
        self.vstup=wx.TextCtrl(self.okno)
        sizer2.Add(self.vstup,1,0,wx.ALL)
        sizer.Add(sizer2,0,wx.EXPAND)
        sizer3=wx.BoxSizer(wx.HORIZONTAL)
        button1=wx.Button(self.okno,label="Show")
        sizer3.Add(button1,0,wx.ALIGN_RIGHT)
        sizer.Add(sizer3,0,wx.EXPAND)
        ##
        self.canvas.SetCursor(wx.CROSS_CURSOR)
        self.canvas.Bind(wx.EVT_PAINT, self.OnPaint)
        self.okno.SetSizer(self.radic)
        button1.Bind(wx.EVT_BUTTON,lambda e:self.vykresli())
        self.body=[(0,0,0,0)]
        self.pocet=0
        self.dc=False
    def vykresli(self):
        l=[]
        for prvek in self.vstup.GetValue().split(','):
            l.append(int(prvek))
        self.body=l
        self.dc.BeginDrawing()
        self.dc.DrawLineList([l])
        self.dc.EndDrawing()
    def OnPaint(self, evt):
        self.dc=wx.PaintDC(self.canvas)
        self.dc.BeginDrawing()
        self.dc.DrawLineList(self.body)
        self.dc.EndDrawing()
if __name__ == "__main__":
    okno = wx.App(0)
    parent=wx.MDIParentFrame(None,size=wx.Size(500,500))
    child=wx.MDIChildFrame(parent,title="Graf",id=-1)
    Canvas(child)
    child.Maximize()
    parent.Show()
    okno.MainLoop()

if i write in entry for example 4,5,4,40 than will becreated line at this coordinates. But if i press button Show, the line is showed, but i get some error. Do you can tell me please what i am doing bad?
AddThis Social Bookmark Button
Reply With Quote  
Join Date: Jul 2006
Posts: 562
Reputation: jrcagle is on a distinguished road 
Rep Power: 4
Solved Threads: 72
jrcagle jrcagle is offline Offline
Posting Pro

Re: wx.Paint

  #2  
Apr 15th, 2007
What error? What do you make of it?
Reply With Quote  
Join Date: Mar 2006
Posts: 56
Reputation: Blujacker is an unknown quantity at this point 
Rep Power: 3
Solved Threads: 0
Blujacker Blujacker is offline Offline
Junior Poster in Training

Re: wx.Paint

  #3  
Apr 16th, 2007
Well, try to write in entry coordinates "4,4,40,40" and press Show. There will create onle line, but i will get error:
TypeError: Expected a sequence of (x1,y1, x1,y2) sequences.
Traceback (most recent call last):
  File "C:\Documents and Settings\Blu\Plocha\MaRoWx\graf_zkouska.py", line 140,
in OnPaint
    self.dc.DrawLineList(self.body)
  File "C:\Python24\lib\site-packages\wx-2.6-msw-unicode\wx\_gdi.py", line 4100,
 in DrawLineList
    return self._DrawLineList(lines, pens, [])
  File "C:\Python24\lib\site-packages\wx-2.6-msw-unicode\wx\_gdi.py", line 4042,
 in _DrawLineList
    return _gdi_.DC__DrawLineList(*args, **kwargs)
Reply With Quote  
Join Date: Jul 2006
Posts: 562
Reputation: jrcagle is on a distinguished road 
Rep Power: 4
Solved Threads: 72
jrcagle jrcagle is offline Offline
Posting Pro

Re: wx.Paint

  #4  
Apr 17th, 2007
OK, buddy, you owe me one Just kidding; I'm learning wxPython, and it was helpful to work through the code.

Comments about your code:

(1) The reason it crashed and printed multiple error messages, I *think*, was that you were passing non-tuples to DrawLines.

And, if you are using IDLE and get an error while working with wxPython -- you may not get your system back. The error messages just kept scrolling down the screen, and I had to restart twice.

(2) In general, the code had a lot of unneeded stuff. BeginDrawing() and EndDrawing() are listed in the docs as doing nothing and are deprecated. The two separate paint methods (vykresli, OnPaint) were muddling the picture. I wasn't able to find a use for the Add((0,0)) calls.

(3) I recommend having all of your widgets be members of the parent class. That way, you can refer to them as needed in the code. See below for examples.

(4) jste cech?

Anyways, here's a working version:

  1. import wx
  2.  
  3. class MyFrame(wx.Frame):
  4.  
  5. PENS = ['blue','red','green','black','purple']
  6.  
  7. def __init__(self,parent=None,id=wx.ID_ANY,title="Line Drawer"):
  8. wx.Frame.__init__(self, parent, id, title)
  9.  
  10.  
  11. self.sizer = wx.FlexGridSizer(2,2,0,0)
  12.  
  13. # Add canvas
  14. self.canvas = wx.ScrolledWindow(self, id=wx.ID_ANY)
  15. self.canvas.EnableScrolling(True, True)
  16. self.P_WIDTH = 1000
  17. self.P_HEIGHT = 1000
  18. self.canvas.SetScrollbars(20, 20, self.P_WIDTH/20, self.P_HEIGHT/20)
  19. self.sizer.Add(self.canvas, 1, wx.EXPAND)
  20.  
  21. # Pad spacing to sizer
  22. self.pad_sizer=wx.BoxSizer(wx.VERTICAL)
  23. self.sizer.Add(self.pad_sizer, 1, wx.EXPAND)
  24.  
  25. self.sizer.AddGrowableRow(0, 1)
  26. self.sizer.AddGrowableCol(0, 1)
  27.  
  28. # Add text entry
  29. self.text_sizer=wx.BoxSizer(wx.HORIZONTAL)
  30. self.text_sizer.Add(wx.StaticText(self,label=" f(y)= "),0,wx.ALIGN_CENTER)
  31. self.entry=wx.TextCtrl(self,style=wx.TE_PROCESS_ENTER)
  32. self.text_sizer.Add(self.entry,1,0,wx.ALL)
  33. self.sizer.Add(self.text_sizer,0,wx.EXPAND)
  34.  
  35. # Add button
  36. self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
  37. self.button1=wx.Button(self,label="Show")
  38. self.button_sizer.Add(self.button1,0,wx.ALIGN_RIGHT)
  39. self.sizer.Add(self.button_sizer,0,wx.EXPAND)
  40.  
  41. self.SetSizer(self.sizer)
  42.  
  43. # housekeeping
  44. self.lines = []
  45. self.button1.Bind(wx.EVT_BUTTON,self.OnClick,self.button1)
  46. #self.entry.Bind(wx.EVT_COMMAND_ENTER,self.OnClick,self.entry) # <--- This doesn't work correctly. TO-DO: make TextCtrl respond to <Enter>.
  47. self.canvas.Bind(wx.EVT_PAINT, self.OnPaint)
  48.  
  49.  
  50.  
  51. def OnPaint(self, event):
  52. dc = wx.PaintDC(self.canvas)
  53.  
  54. # This does different colors.
  55. for line_no in range(len(self.lines)):
  56.  
  57. dc.SetPen(wx.Pen(self.PENS[line_no % len(self.PENS)],1))
  58. dc.DrawLine(*self.lines[line_no])
  59.  
  60. # If you want all one color, use this instead:
  61. # dc.SetPen('black',1)
  62. # for line in self.lines:
  63. # dc.DrawLine(*line)
  64.  
  65. def OnClick(self, event=None):
  66. text = self.entry.GetValue()
  67. coords = text.split(',')
  68. try:
  69. x0,y0,x1,y1 = [int(x) for x in coords]
  70. except:
  71. return
  72. else:
  73. self.lines.append((x0,y0,x1,y1))
  74. self.canvas.Refresh() # <-- The key to getting the drawing to work.
  75.  
  76. if __name__ == "__main__":
  77.  
  78. app = wx.PySimpleApp() # <-- much easier than MDIParentFrame...
  79. app.frame = MyFrame()
  80. app.frame.Show()
  81. app.MainLoop()

Hope it helps,
Jeff
Reply With Quote  
Join Date: Mar 2006
Posts: 56
Reputation: Blujacker is an unknown quantity at this point 
Rep Power: 3
Solved Threads: 0
Blujacker Blujacker is offline Offline
Junior Poster in Training

Re: wx.Paint

  #5  
Apr 18th, 2007
well, thanks a lot. it works fine now and i can finish my program...
I was using MDIParentFrame, because this is part of bigger application


btw, jsem čech
A tak ještě jednou díky moc!
Reply With Quote  
Join Date: Apr 2007
Posts: 8
Reputation: leeqiang is an unknown quantity at this point 
Rep Power: 0
Solved Threads: 0
leeqiang leeqiang is offline Offline
Newbie Poster

Re: wx.Paint

  #6  
Apr 18th, 2007
thanks
I learn more from your dicussion
Tomorrow is another day
Reply With Quote  
Join Date: Mar 2006
Posts: 56
Reputation: Blujacker is an unknown quantity at this point 
Rep Power: 3
Solved Threads: 0
Blujacker Blujacker is offline Offline
Junior Poster in Training

Re: wx.Paint

  #7  
Apr 18th, 2007
and i have another question. i tryed to find on web some manual on canas, but i failed. If you know any, please post here. I am trying to find answer on some thing, like "is possible to zoom canvas with some function, or i must write my own function?"

thanks a lot...
Reply With Quote  
Join Date: Mar 2006
Posts: 56
Reputation: Blujacker is an unknown quantity at this point 
Rep Power: 3
Solved Threads: 0
Blujacker Blujacker is offline Offline
Junior Poster in Training

Re: wx.Paint

  #8  
Apr 21st, 2007
omg, i found another problem. If i sroll canvas, is called functin OnPaint and all objects are redraw. If you have there 2 lines, its no problem, but if you have there around milion lines, each redraw takes several seconds......
For exapmle, same program in Tkinter is faster. I thought, that wx is waster then Tkinter, so i think there is some way to draw lines a scroll it without redrawing. Do you know how to solve it?


Thanks a lot...
Reply With Quote  
Join Date: Jul 2006
Posts: 562
Reputation: jrcagle is on a distinguished road 
Rep Power: 4
Solved Threads: 72
jrcagle jrcagle is offline Offline
Posting Pro

Re: wx.Paint

  #9  
Apr 22nd, 2007
I know generally how to solve it, but not specifically in wxPython (yet).

Basically, the OnPaint needs to distinguish between dirty and not-dirty: if you've drawn new lines since the last OnPaint, the canvas is dirty and has to be redrawn. If not, then you just need to blit the right area of the canvas onto the display screen.

That's the basic idea, but I'm not sure how to implement it specifically in wxPython. Let us know when you find out!

Jeff
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

Thread Tools Display Modes
Forums | Blogs | Tutorials | Code Snippets | Whitepapers | RSS Feeds | Advertising
All times are GMT -4. The time now is 3:55 am.
Newsletter Archive - Sitemap - Privacy Statement - Acceptable Use Policy - Contact Us
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC