此代码适用于其他计算机上的其他人,但它似乎不适合我。我使用的是python 2.7.7。它适用于其他两个人,但它似乎不喜欢我或我的电脑,因为每当我运行它,它给我一个错误信息。你们觉得怎么样?
Traceback (most recent call last):
File "C:\Python27\python projects\client with gui.py", line 43, in <module>
frame = WindowFrame(None, 'ChatClient')
File "C:\Python27\python projects\client with gui.py", line 10, in __init__
self.dc = wx.PaintDC(self.panel) # <<< This was changed
File "C:\Python27\python projects\lib\site-packages\wx-3.0-msw\wx\_gdi.py", line 5215, in __init__
_gdi_.PaintDC_swiginit(self,_gdi_.new_PaintDC(*args, **kwargs))
PyAssertionError: C++ assertion "Assert failure" failed at ..\..\src\msw\dcclient.cpp(277) in wxPaintDCImpl::wxPaintDCImpl(): wxPaintDCImpl may be created only in EVT_PAINT handler!
import socket
import wx
class WindowFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title = title, size=(500, 400))
self.panel=wx.Panel(self)
self.panel.SetBackgroundColour("#0B3861")
self.control = wx.TextCtrl(self.panel, style = wx.TE_MULTILINE, size =(410, 28), pos=(0,329))
self.dc = wx.PaintDC(self.panel) # <<< This was changed
# Sets up the socket connection
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "127.0.0.1"
port = 6667
self.s.connect((host,port))
# creates send button and binds to event
sendbutton=wx.Button(self.panel, label ="Send", pos =(414,325), size=(65,35))
self.panel.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_BUTTON, self.SendPress, sendbutton )
self.Centre()
self.Show()
#Draws white rectangle
def OnPaint(self, event):
self.dc.SetPen(wx.Pen('black'))
self.dc.SetBrush(wx.Brush('white'))
self.shapeRectangle=self.dc.DrawRectangle(20, 20, 444, 280)
self.Show(True)
# Sets the function of the send button
def SendPress(self, event):
self.sent = self.control.GetValue()
self.s.send(self.sent)
self.control.Clear()
self.dc.DrawText(self.sent, 0, 300 )
self.s.close()
if __name__=="__main__":
app = wx.App(False)
frame = WindowFrame(None, 'ChatClient')
app.MainLoop()
答案 0 :(得分:0)
运行此代码时出现与您相同的错误。查看下面链接的文档&#34;如果应用程序希望在EVT_PAINT事件处理程序内的窗口的客户区域上绘制,则必须构造wx.PaintDC。&#34;
http://www.wxpython.org/docs/api/wx.PaintDC-class.html
您会考虑将其更改为客户端DC吗? &#34;如果应用程序希望在EVT_PAINT事件外部绘制窗口的客户区域,则必须构造wx.ClientDC&#34;
http://www.wxpython.org/docs/api/wx.ClientDC-class.html
通常我认为你会在绑定到EVT_PAINT事件的方法中创建PaintDC,我检查了一些我的代码示例,当我希望查找属性或影响外部的画布时,我通常似乎使用ClientDC。油漆方法。
要做到这一点,我会改变:
self.dc = wx.PaintDC(self.panel)
为:
self.dc = wx.ClientDC(self.panel)
以下是使用原始PaintDC执行我认为您尝试执行的代码的完整修改版本。
import socket
import wx
class WindowFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title = title, size=(500, 400))
self.panel=wx.Panel(self)
self.panel.SetBackgroundColour("#0B3861")
self.control = wx.TextCtrl(self.panel, style = wx.TE_MULTILINE, size =(410, 28), pos=(0,329))
self.textLog = []
# Sets up the socket connection
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "127.0.0.1"
port = 6667
self.s.connect((host,port))
# creates send button and binds to event
sendbutton=wx.Button(self.panel, label ="Send", pos =(414,325), size=(65,35))
self.panel.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_BUTTON, self.SendPress, sendbutton )
self.Centre()
self.Show()
#Draws white rectangle
def OnPaint(self, event):
dc = wx.PaintDC(self.panel)
dc.SetPen(wx.Pen('black'))
dc.SetBrush(wx.Brush('white'))
dc.Clear()
x, y = 20,20
self.shapeRectangle=dc.DrawRectangle(x, y, 444, 280)
fnt = dc.GetFont()
for i,line in enumerate(self.textLog):
if i%2:
dc.SetTextForeground(wx.RED)
else:
dc.SetTextForeground(wx.BLUE)
dc.SetFont(fnt)
dc.DrawText(line, x, y)
y += dc.GetCharHeight()
# Sets the function of the send button
def SendPress(self, event):
self.sent = self.control.GetValue()
self.s.send(self.sent)
self.control.Clear()
self.textLog.append(self.sent)
self.panel.Refresh()
self.s.close()
if __name__=="__main__":
app = wx.App(False)
frame = WindowFrame(None, 'ChatClient')
app.MainLoop()
答案 1 :(得分:0)
这个例子有很多问题:
i%2
???)在这种情况下,使用适当的控件来制作彩色文本会更合适。根据需要插入发送/接收机制
import wx
from wx.stc import StyledTextCtrl
class WindowFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title = title, size=(500, 400))
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour("#0B3861")
self.stc = StyledTextCtrl(self.panel, -1)
self.control = wx.TextCtrl(self.panel, style = wx.TE_MULTILINE)
sendbutton=wx.Button(self.panel, label ="Send")
recvbutton=wx.Button(self.panel, label ="Receive")
sendbutton.Bind(wx.EVT_BUTTON, self.SendPress)
recvbutton.Bind(wx.EVT_BUTTON, self.RecvPress)
szmain = wx.BoxSizer(wx.VERTICAL)
szmain.Add(self.stc, 1, wx.EXPAND|wx.ALL, 4)
szsub = wx.BoxSizer(wx.HORIZONTAL)
szsub.Add(self.control, 1, wx.EXPAND|wx.ALL, 4)
szsub.Add(sendbutton, 0, wx.EXPAND|wx.ALL, 4)
szsub.Add(recvbutton, 0, wx.EXPAND|wx.ALL, 4)
szmain.Add(szsub, 0, wx.EXPAND|wx.ALL, 0)
self.panel.SetSizer(szmain)
self.Centre()
self.Show()
# define styles for stc, 0 red fore color, 1 blue fore color
self.stc.StyleSetSpec(0, "fore:#FF0000")
self.stc.StyleSetSpec(1, "fore:#0000FF")
self.stc.SetWrapMode(True) #autowrap
def add_text(self, text, style):
curpos = self.stc.GetCurrentPos()
self.stc.AddText(text)
self.stc.AddText('\r\n')
newpos = self.stc.GetCurrentPos()
delta = newpos-curpos
# consult the Scintilla doc (stc is based on it) to understand how styling works
# http://www.scintilla.org/ScintillaDoc.html#Styling
self.stc.StartStyling(curpos, 31) # mask 31 allows setting of styles
self.stc.SetStyling(delta, style)
self.stc.ScrollToEnd() # keep last line visible
# Sets the function of the send button
def SendPress(self, event):
self.add_text(self._get_text(), 0)
# Sets the function of the recv button
def RecvPress(self, event):
self.add_text(self._get_text(), 1)
def _get_text(self):
text = self.control.GetValue()
self.control.Clear()
return text
if __name__=="__main__":
app = wx.App(False)
frame = WindowFrame(None, 'ChatClient')
app.MainLoop()
在wxPython演示中查看如何使用StyledTextControl
(基于Scintilla)。最后但并非最不重要的是,它让我学会了STC
。