Avoid command events blocking a kill focus event in wxPython - focus

I'm writing a class to generate a frame on left click of a taskbar icon. The desired behaviour is for this frame to disappear on loss of focus, so I have bound a wx.EVT_KILL_FOCUS event to the panel in my LeftClickFrame() object.
This works fine if I only have a wx.StaticText widget in the frame, but if I add a wx.HyperlinkCtrl the wx.EVT_KILL_FOCUS event no longer fires. I get the same blocking behaviour with wx.RadioButton widgets, but not with wx.StaticBitmap.
I believe this is something to do with the fact that wx.HyperlinkCtrl and wx.RadioButton widgets are both controls and emit command events, but I'm not clear on what I have to do to rearrange my class so the wx.EVT_KILL_FOCUS event is still processed when one or both of these controls are present.
I have the following code:
class LeftClickFrame(wx.Frame):
def __init__(self, frame):
super(LeftClickFrame, self).__init__(frame,
style=wx.FRAME_NO_TASKBAR|
wx.CAPTION)
self.tbicon = frame.taskbar_icon
self.tbicon.options_window = self
self.InitUI()
def InitUI(self):
self.panel = wx.Panel(self, wx.ID_ANY)
self.panel.Bind(wx.EVT_KILL_FOCUS, self.Close)
self.main_vbox = wx.BoxSizer(wx.VERTICAL)
statuses_hbox = self.GetStatusesVBox()
self.main_vbox.Add(statuses_hbox)
self.main_vbox.Add((-1, 10))
links_vbox = self.GetLinksVBox()
self.main_vbox.Add(links_vbox, flag=wx.TOP|wx.CENTER, border=20)
self.panel.SetSizer(self.main_vbox)
def GetStatusesVBox(self, statuses):
statuses_vbox = wx.BoxSizer(wx.VERTICAL)
for status in statuses:
battery_statuses_txt = wx.StaticText(self.panel,
wx.ID_ANY, status)
statuses_vbox.Add(battery_statuses_txt,
flag=wx.TOP|wx.LEFT, border=10)
return statuses_vbox
def GetLinksVBox(self):
links_vbox = wx.BoxSizer(wx.VERTICAL)
link1 = wx.HyperlinkCtrl(self.panel, wx.ID_ANY, 'Adjust screen brightness')
link1.Bind(wx.EVT_HYPERLINK, self.tbicon.LaunchPowerOptions)
links_vbox.Add(link1, flag=wx.CENTER|wx.TOP, border=5)
return links_vbox
def Close(self):
self.tbicon.options_window.Destroy()
self.Destroy()

You can try EVT_ACTIVATE instead of EVT_KILL_FOCUS since it does not work in your case.
And you can use event.GetActive() to check if this frame is in focus.
def InitUI(self):
self.panel = wx.Panel(self, wx.ID_ANY)
self.Bind(wx.EVT_ACTIVATE, self.Close) #bind it to Frame
def Close(self, evt):
if evt.GetActive() != True:
#do window close

Related

How does this bit of code work? Someone said this is a solution

frame.buttons = {}
frame.AddButton = function()
frame.buttons[#frame.buttons + 1] = frame:Add("DButton")
local button = frame.Buttons[#frame.buttons]
end
I know it's simple, but it's the only part so far that I do not understand.
How do you add now buttons and how do you access them?
This code adds a button to a Frame instance. It also creates a list of buttons in that Frame. You need to replace that "DButton" by a DButton instance.
Ideally you change the code like that:
frame.buttons = {}
frame.AddButton = function(button)
frame.buttons[#frame.buttons + 1] = frame:Add(button)
local button = frame.Buttons[#frame.buttons]
end
If you want to add a button, create it, then call frame.AddButton(myButton).

Julia PlotlyJS delay show plot, update plot

I'm trying to include a plot using the PlotlyJS package in a small application using Blink.
So far, whenever I use the plot function, it opens a new window, which I want to avoid..
Furthermore, when updating the plot, another window pops up - also not wanted.
Does anyone know how to avoid these new windows? Thanks in advance!
Sample code:
using PlotlyJS,Blink
scatter_1 = scatter(;x=rand(10),y=rand(10))
p = plot(scatter_1) # first unwanted window
w = Window()
body!(w,p)
scatter_2 = scatter(;x = 2*rand(10), y = 2*rand(10))
addtraces(p, scatter_2) #second unwated window
Try adding ; at the end of the line.
using PlotlyJS,Blink
scatter_1 = scatter(;x=rand(10),y=rand(10))
p = plot(scatter_1);
w = Window()
body!(w,p)
scatter_2 = scatter(;x = 2*rand(10), y = 2*rand(10))
addtraces(p, scatter_2);

Awesome wm setting size for the tasklist item

I'm coding a custom vertical wibox that contains my tasklist, I want it to look like this:
but instead of being fixed height, the tasklist items just take up all the available space. Here's the result:
Here's my code so far:
function render_task_box(s)
myotherbox[s] = awful.wibox({ position = "left", screen = s, ontop =
true, width = 200 })
mytasklist[s] = awful.widget.tasklist(
s,
awful.widget.tasklist.filter.currenttags,
mytasklist.buttons,
nil,
nil,
wibox.layout.flex.vertical())
local middle_layout = wibox.layout.fixed.vertical()
middle_layout:add(mytasklist[s])
local layout = wibox.layout.align.vertical()
layout:set_middle(middle_layout)
myotherbox[s]:set_widget(layout)
end
So how do I get wanted result? (or at least set height of tasklist icon)
Update
Looked up some docs and tried this:
local l = wibox.layout.flex.vertical();
l:set_max_widget_size(20)
It did nothing.
After reading some of the awesome's source code I've found a solution.
Somewhere in your script require this
local common = require("awful.widget.common")
Then create a function that overrides task update function:
function list_update(w, buttons, label, data, objects)
-- call default widget drawing function
common.list_update(w, buttons, label, data, objects)
-- set widget size
w:set_max_widget_size(20)
end
Then pass this function to tasklist
mytasklist[s] = awful.widget.tasklist(s,
awful.widget.tasklist.filter.currenttags,
mytasklist.buttons,
nil,
list_update,
wibox.layout.flex.vertical())
Thats it!

Changing to display object position in corona

I am new to programming this question might sound very simple.
I have created a object as a module called box
box = {}
m={}
m.random = math.random
function box:new(x,y)
box.on=false
local box = display.newRect(0,0,100,100)
box:setFillColor(m.random(120,200),m.random(120,200),m.random(120,200))
box.x = x
box.y = y
box.type = "box"
return box
end
return box
in my main.lua I want to create as many boxes and ,like an adventure game how can I switch two of the boxes position,example I click on one of them,then it is selected,and simply I click on the other one and they change position with each other.
Thanks in advance
I don't know Corona, but the general logic for what you're doing is this:
Add an event handler which allows you to detect when a box is clicked.
Add some way of tracking the selected box.
When a box is clicked:
if no box is yet selected, select the current box
if another box was previously selected, swap with the current box
if the already-selected box was clicked, ignore (or toggle off selected)
General idea (not sure if this is valid Corona event handling, but should get you close):
box = {}
m={}
m.random = math.random
-- track the currently selected box
local selected = nil
function box:new(x,y)
box.on=false
local box = display.newRect(0,0,100,100)
box:setFillColor(m.random(120,200),m.random(120,200),m.random(120,200))
box.x = x
box.y = y
box.type = "box"
function box:touch(event)
if not selected then
-- nothing is selected yet; select this box
selected = self
-- TODO: change this box in some way to visually indicate that it's selected
elseif selected == self then
-- we were clicked on a second time; we should probably clear the selection
selected = nil
-- TODO: remove visual indication of selection
else
-- swap positions with the previous selected box, then clear the selection
self.x, self.y, selected.x, selected.y
= selected.x, selected.y, self.x, self.y
selected = nil
end
end
return box
end

Getting a button reference?

I'm working on an app in Lua + Corona. As a complete beginner, I've managed to hack together a little script for a carousel, but now I've got a question.
function forwardButtonPress()
if carousel.getCurImage() < #myImages then
carousel.slideToImage(carousel.getCurImage() + 1)
end
end
function backButtonPress()
if carousel.getCurImage() > 1 then
carousel.slideToImage(carousel.getCurImage() - 1)
end
end
--Here's where we do the actual initilization of the page.
local fwbutton = display.newImage("buttonArrow.png")
fwbutton.x = 260
fwbutton.y = 120
fwbutton:addEventListener("tap", forwardButtonPress )
local bkbutton = display.newImage("buttonBackArrow.png")
bkbutton.x = 60
bkbutton.y = 120
bkbutton:addEventListener("tap", backButtonPress )
If you look at the code, you'll see that I have two buttons, a back button and a forward one. Those are for sliding the images. So, say you get to the end of the carousel. The script takes care of making sure that it doesn't go past the end already, but how do I access the button to set the alpha to zero or fade it? It's linear, so I can't just put the button above its event function, so that the event function can reference the button... is there a way to pass the event function a reference to the button?
You can forward declare the event handler functions like this at the top of the file:
local forwardButtonPress
local backButtonPress
Then create your buttons and attach the event handlers (This is your code copied & pasted):
local fwbutton = display.newImage("buttonArrow.png")
fwbutton.x = 260
fwbutton.y = 120
fwbutton:addEventListener("tap", forwardButtonPress )
local bkbutton = display.newImage("buttonBackArrow.png")
bkbutton.x = 60
bkbutton.y = 120
bkbutton:addEventListener("tap", backButtonPress )
Add a function to manage setting the appearance of the buttons when either button is clicked:
local function setButtons()
if carosel.getCurImage() < #myImages then
fwbutton.alpha = 1.0
else
fwbutton.alpha = 0.5
end
if carosel.getCurImage() > 1 then
bkbutton.alpha = 1.0
else
bkbutton.alpha = 0.5
end
end
Now, you can write the function implementations, which will be able to deal with the buttons via the setButtons function:
forwardButtonPressed = function()
if carousel.getCurImage() < #myImages then
carousel.slideToImage(carousel.getCurImage() + 1)
end
setButtons()
end
backButtonPress = function()
if carousel.getCurImage() > 1 then
carousel.slideToImage(carousel.getCurImage() - 1)
end
setButtons()
end
Disclaimer: I'm not able to test this now, so there might be a syntax error somewhere, but organizing the code this way will work for what you're doing.
You can create/define the buttons above the function, and attach the EventListener below, no? If not, I don't really understand the problem.

Resources