draw rectangle on Clicking Button with wxPython - python

I am developing a test bench, in which on clicking a button, a specific test will be done, and accordingly if test is done successfully, then it should be indicated by colored rectangle. But the problem is that how can I bind 2 events with one button clicking event. And also when i execute the attached code, open clicking the button, rectangle wont show up on panel.
import wx
class MyClass(wx.Frame):
def __init__(self,parent,id):
wx.Frame.__init__(self,parent,id, "GUI", size =(500,300))
panel=wx.Panel(self)
button=wx.Button(panel,label = 'Exit', pos = (250,180), size = (50,50))
button1=wx.Button(panel,label = 'Open', pos = (50,50), size = (50,50))
self.Bind(wx.EVT_PAINT, self.Rectangle,button1)
self.Bind(wx.EVT_BUTTON,self.CloseButton,button)
self.Bind(wx.EVT_CLOSE,self.CloseProgram)
def Rectangle(self,e):
dc = wx.PaintDC(self.panel)
dc.SetPen(wx.Pen('RED'))
dc.SetBrush(wx.Brush('BLUE'))
dc.DrawRectangle(130, 15, 90, 60)
def CloseButton(self,e):
self.Close(True)
def CloseProgram(self,e):
self.Destroy()
if __name__ == '__main__':
app=wx.App()
frame=MyClass(parent=None,id=-1)
frame.Show()
app.MainLoop()

Related

How to change wxpython gizmo LED color when button is clicked

I want to change the colour of a wx gizmos led when the wx button is clicked.
My example is as follows.
import wx
import wx.lib.gizmos.ledctrl as led
class Main(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent = None, title ="LED test")
panel = wx.Panel(self)
self.myLED = led.LEDNumberCtrl(panel, -1, pos = (150,50), size = (100,100))
self.myLED.SetBackgroundColour("gray")
self.myButton = wx.Button(panel, -1, "myButton", pos =(50, 50))
self.myButton.Bind(wx.EVT_BUTTON, self.changeLEDColor)
def changeLEDColor(self,event):
self.myLED.SetBackgroundColour("green")
if __name__ == "__main__":
app = wx.App()
frame = Main()
frame.Show()
app.MainLoop()
I expected the led colour to change to 'green', when I click 'mybutton', but it is still 'gray'.
What's wrong with my example?
Adding self.Refresh() or self.myLED.Refresh() will trigger the repaint. Here's the link to the docs. If it flickers, look into wx.Frame.SetDoubleBuffered(True) - docs

wxPython (wxWidgets): how to customize scrollbars look'n'feel?

I found examples for styling tabs (notebook), menus, windows, forms and many other but didn't see any example for scrollbars. Can anyoune show or prompt something about this?
I have idea about creating special wxPanel with slider and arrows but I don't know is it possible to hide system scrollbar and move content by dragging and clicking inside the pannel?
I think the closest to what you are trying to do is wx.lib.dragscroller.
This is an example you find in wxPython demo from the official site:
import wx
import wx.lib.dragscroller
#-------------------------------------------------------------------------------
def runTest(frame, nb, log):
win = DragScrollerExample(nb, -1)
return win
class DragScrollerExample(wx.ScrolledWindow):
def __init__(self, parent, id=-1):
wx.ScrolledWindow.__init__(self, parent, id)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
self.SetScrollbars(1, 1, 2000, 2000, 0, 0)
self.scroller = wx.lib.dragscroller.DragScroller(self)
def OnPaint(self, event):
dc = wx.PaintDC(self)
self.DoPrepareDC(dc)
pen = wx.Pen(wx.BLACK, 5)
dc.SetPen(pen)
for y in range(10):
for x in range(10):
dc.DrawCircle(x*400+20, y*400+20, 200)
dc.DrawText('Right click and drag in the direction you want to scroll.',
20, 20)
dc.DrawText('The distance from the start of the drag determines the speed.',
20, 50)
def OnRightDown(self, event):
self.scroller.Start(event.GetPosition())
def OnRightUp(self, event):
self.scroller.Stop()
#-------------------------------------------------------------------------------
overview = """<html><body>
<h2>DragScroller</h2>
<p>
A helper class that adds scrolling to a wx.ScrolledWindow in the direction
of the drag.
</body></html>
"""
if __name__ == '__main__':
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])])

Python win32api.SetCursorPos dual screen issue

I am trying to create simple program which will click to specific coordinates every x seconds based on your choose if you need to click on Left screen or Right screen. My issue here is that win32api.SetCursorPos which is moving with my cursor is not moving to the secondary screen (right in my case). It stays in the main screen.
And I am having one more issue with my code, when Exit button inside GUI is pressed, window will close however program is still running in background. I am using self.Destroy() function to kill all process.
Thank you for your advice.
Here is my code:
import time
import pyautogui
import wx
import threading
import sys
import win32api
class bucky(wx.Frame):
def __init__(self,parent,id):
self.positionx = ""
self.positiony = ""
wx.Frame.__init__(self,parent,id,'AutoClick 2.0', size=(300,200))
panel=wx.Panel(self)
self.buttonpos=wx.Button(panel,label="Left Screen",pos=(30,10),size=(80,40))
self.buttonpos2=wx.Button(panel,label="Right Screen",pos=(180,10),size=(80,40))
self.button=wx.Button(panel,label="Start",pos=(120,90),size=(60,30))
self.button2=wx.Button(panel,wx.ID_EXIT,label="Exit",pos=(120,120),size=(60,30))
self.Bind(wx.EVT_BUTTON, self.action, self.button)
self.Bind(wx.EVT_BUTTON, self.closebutton, self.button2)
self.Bind(wx.EVT_BUTTON, self.position, self.buttonpos)
self.Bind(wx.EVT_BUTTON, self.position, self.buttonpos2)
self.Bind(wx.EVT_CLOSE, self.closewindow)
def position(self, event):
label = event.GetEventObject().GetLabel()
if label == "Left Screen":
self.positionx = 1640
self.positiony = 183
self.buttonpos.Disable()
self.buttonpos2.Enable()
elif label == "Right Screen":
self.positionx = 3308
self.positiony= 186
self.buttonpos.Enable()
self.buttonpos2.Disable()
def closebutton(self,event):
self.Destroy()
def closewindow(self,event):
self.Destroy()
def action(self,event):
self.button.Disable()
def callback():
while 1:
pos = pyautogui.position()
time.sleep(10)
pos1 = pyautogui.position()
if (pos1[0] == pos[0]) and (pos1[1] == pos[1]):
win32api.SetCursorPos((self.positionx, self.positiony))
pyautogui.click()
else:
pass
t = threading.Thread(target=callback)
t.start()
if __name__=='__main__':
app=wx.PySimpleApp()
frame=bucky(parent=None,id=1)
frame.Show()
app.MainLoop()
EDIT: Problem have been solved. Thank you for help.
Looking at this reddit post, I think the x coordinates for the secondary monitor are simply added to the resolution of the primary monitor (ex if you had two 1920x1080 monitors, the middle of the second monitor will be at 2880,520)
Try using (win32api.GetSystemMetrics(MONITOR_NUMBER) to see how the differences are represented.

image won't show even after image.Show()

Code below.
If you execute the program as is (just change "moresco.jpg" to any image on your computer), it will first show a black square, and if you click on the search button the image you hardcoded (moresco.jpg in my case) will be displayed.
What I want is to hide the black square at startup and show moresco.jpg when I click on search. So I thought of putting a .Show() over there.
If you uncomment line 22, the black square doesn't show (which is what we want), but then when you click on search moresco.jpg doesn't show.
If you have any suggestions on how to fix this code I would be grateful !
import wx
class gui(wx.Panel):
def __init__(self,parent):
self.parent=parent
wx.Panel.__init__(self,parent)
vsizer = wx.BoxSizer(wx.VERTICAL)
hsizer1 = wx.BoxSizer(wx.HORIZONTAL)
button = wx.Button(self,-1,"search")
self.Bind( wx.EVT_BUTTON,self.display,button)
hsizer1.Add(button,.1,wx.EXPAND)
vsizer.Add(hsizer1,.1,wx.EXPAND)
hsizer2 = wx.BoxSizer(wx.HORIZONTAL)
vsizer.Add(hsizer2,1,wx.EXPAND)
self.pnl=wx.Panel(self)
img = wx.EmptyImage(500,500)
self.imageCtrl = wx.StaticBitmap(self.pnl, wx.ID_ANY,
wx.BitmapFromImage(img))
# uncomment this line and the image won't show even after
# click on search button
#-----------------------------
# print self.imageCtrl.Hide()
#-----------------------------
hsizer3 = wx.BoxSizer(wx.HORIZONTAL)
hsizer3.Add(self.pnl,2,wx.ALIGN_BOTTOM|wx.ALIGN_CENTER_HORIZONTAL,wx.EXPAND)
vsizer.Add(hsizer3,2,wx.EXPAND)
self.SetSizer(vsizer)
self.pnl.Layout()
def display(self,strip):
self.Refresh()
self.Update()
self.imageCtrl.Refresh()
self.imageCtrl.Update()
print self.imageCtrl.Show()
self.imageCtrl.Refresh()
self.imageCtrl.Update()
self.Refresh()
self.Update()
imageFile = "moresco.jpg"
jpg1 = wx.Image(imageFile, wx.BITMAP_TYPE_ANY)
# bitmap upper left corner is in the position tuple (x, y) = (5, 5)
self.imageCtrl.SetBitmap(wx.BitmapFromImage(jpg1))
self.Refresh()
self.Update()
if __name__ == "__main__":
app = wx.App()
w,h=wx.DisplaySize()
frame = wx.Frame(parent=None, id=-1, title="transmorgripy",size=(w/1.2,h/1.2 ))
frame.Center()
panel = gui(frame)
frame.Show()
app.MainLoop()
Using Hide() and Show() on a control does not simply set it to being transparent or not. When it is hidden it does not have a place in its parent panel's Sizer. After you show the image control, it needs a chance to be fit into the parent panel. Depending on exactly how you want it to be displayed you may want to call Fit or Layout.
To show the image and trigger the Sizer giving it a position you could do something like this:
def display(self, strip):
print self.imageCtrl.Show()
imageFile = "moresco.jpg"
jpg1 = wx.Image(imageFile, wx.BITMAP_TYPE_ANY)
# bitmap upper left corner is in the position tuple (x, y) = (5, 5)
self.imageCtrl.SetBitmap(wx.BitmapFromImage(jpg1))
self.Layout()

How to detect right click in Python GUI?

I am making a minesweeper game in python with GUI. I want to use the right click of the mouse to flag a field on the GUI. I have a graphics.py library (give to me by my teacher) which has a function to detect left-clicks. How can I detect right click?
The function for detecting left-click is:
def getMouse(self):
self.update() # flush any prior clicks
self.mouseX = None
self.mouseY = None
while self.mouseX == None or self.mouseY == None:
self.update()
if self.isClosed(): raise GraphicsError("getMouse in closed window")
time.sleep(.1) # give up thread
x,y = self.toWorld(self.mouseX, self.mouseY)
self.mouseX = None
self.mouseY = None
return Point(x,y)
Point(x,y) will give me the click-coordinates.
You need to catch MouseEvents, as described here. You can follow the tutorial I've pasted from here
The flags for the different mouse buttons are as follows: wx.MOUSE_BTN_LEFT
wx.MOUSE_BTN_MIDDLE and wx.MOUSE_BTN_RIGHT
#!/usr/bin/python
# mousegestures.py
import wx
import wx.lib.gestures as gest
class MyMouseGestures(wx.Frame):
def __init__ (self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 500))
panel = wx.Panel(self, -1)
mg = gest.MouseGestures(panel, True, wx.MOUSE_BTN_LEFT)
mg.SetGesturePen(wx.Colour(255, 0, 0), 2)
mg.SetGesturesVisible(True)
mg.AddGesture('DR', self.OnDownRight)
def OnDownRight(self):
self.Close()
class MyApp(wx.App):
def OnInit(self):
frame = MyMouseGestures(None, -1, "mousegestures.py")
frame.Show(True)
frame.Centre()
return True
app = MyApp(0)
app.MainLoop()

Categories