Trouble auto labelling buttons from database then centering them in a frame - python-2.7

class ManageExistingColleaguePanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
main_sizer = wx.BoxSizer(wx.VERTICAL)
con = sqlite3.connect("hs_audit.sqlite")
con.text_factory = str
cur = con.cursor()
cur.execute("SELECT engineer FROM T1")
myList = [r[0] for r in cur.fetchall()]
con.close()
main_sizer.AddStretchSpacer()
for n in range(0, len(myList)):
main_sizer.Add(wx.Button(self, wx.CENTER, label = str(myList[(n)]), size = (200, 35)))
main_sizer.AddStretchSpacer()
self.SetSizer(main_sizer)
I have been trying to get a column of buttons centered in the frame labeled with the contents of a column in a mysqlite3 table.
I can get the buttons in a column all labelled but can't get them centered. I have tried loads of different combinations to get this right, but get errors regarding undefined label or size variables. I can get a centered column of buttons but then I am unable to label them.
Any help please this is driving me mad.

At last. Can't seem to get the hang of the wxpython sizer syntax's.
Anyways here was the answer.
class ManageExistingColleaguePanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
main_sizer = wx.BoxSizer(wx.VERTICAL)
con = sqlite3.connect("hs_audit.sqlite")
con.text_factory = str
cur = con.cursor()
cur.execute("SELECT engineer FROM T1")
myList = [r[0] for r in cur.fetchall()]
con.close()
main_sizer.AddStretchSpacer()
for n in range(0, len(myList)):
main_sizer.Add(wx.Button(self, label=str(myList[(n)]), size=(200, 35)), 0, wx.CENTER)
main_sizer.AddStretchSpacer()
self.SetSizer(main_sizer)

Related

Capture the current value in ComboBox. wxpython

In the code below I am trying to capture the current value of the ComboBox when the Save button is clicked.
Ive defined the function that is triggerd by the EVT_BUTTON that captures the values in the TextCtrl fields but does not work for ComboBox.
I've tried a few different approaches such as just trying to assign to audit_engineer = self.engineer_name.
Can anyone help me?
Regards
Paul.
class CreateAudit(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.lblname = wx.StaticText(self, label = "Site Name :", pos=(20,60))
self.site_name = wx.TextCtrl(self, value = "Enter site name here.", pos=(150, 60), size=(140,-1))
self.lblname = wx.StaticText(self, label = "Job Number", pos=(20,120))
self.job_number = wx.TextCtrl(self, value = "4 digit number only.", pos=(150, 120), size=(140,-1))
con = sqlite3.connect("hs_audit.sqlite")
con.row_factory = lambda cursor, row: row[0]
myList = con.execute('SELECT engineer FROM T1').fetchall()
self.lblname = wx.StaticText(self, label="Select Engineer :", pos=(20,180))
self.engineer_name = wx.ComboBox(self, pos=(150, 180), size=(140,-1)).SetItems(myList)
self.save_button =wx.Button(self, label="Save", pos=(150, 400))
self.save_button.Bind(wx.EVT_BUTTON, self.save_details)
self.Show()
def save_details(self, event):
audit_site = self.site_name.GetValue()
audit_engineer = self.engineer_name.GetValue() #<-- DOES NOT WORK NONE VALUE ERROR
audit_jobnumber = self.job_number.GetValue()
print audit_site
print audit_engineer
print audit_jobnumber
Changing
self.engineer_name = wx.ComboBox(self, pos=(150, 180), size=(140,-1)).SetItems(myList)
to
self.engineer_name = wx.ComboBox(self, pos=(170, 180), size=(170,-1), choices = myList)
Did the trick. Over complicated syntax in first effort I think.
Fixing these little things takes an age, but I'm enjoying the learning curve.

Tkinter cell location (x,y)?

Is there a way to get the cell size and x,y location of a cell's corner?I have radio buttons on the left side of my frame and I would like to resize an image based on the size of the frame.
What I'm going to end up doing is creating a block that takes up a large group of cells that will allow me to zoom in on my .tif and scroll left/right and up/down. Does this type of widget already exist?
Here's a very rough outline of what I currently have
from tkinter import *
from PIL import Image,ImageTk
import os
file_path = "C:/Users/..."
dirs = os.listdir(file_path)
root = Tk()
# Set window size slightly below screen size
width = int(root.winfo_screenwidth() - root.winfo_screenwidth()/9)
height = int(root.winfo_screenheight() - root.winfo_screenheight()/9)
root.geometry(str(width)+"x"+str(height))
class Application(Frame):
def __init__(self,master):
Frame.__init__(self,master)
os.chdir(file_path)
self.grid()
self.create_widgets()
def create_widgets(self):
Label(self,
text = "Available Files"
).grid(row=0,column=0,sticky=W)
Label(self,
text = "Select one:"
).grid(row=1,column=0,sticky=W)
self.filelist = StringVar()
self.filelist.set(0)
# Radio buttons of files in directory
i = 1
for files in dirs:
if os.path.isfile(os.path.join(file_path, files)):
i += 1
Radiobutton(self,
text=files,
variable=self.filelist,
value=files,
command=self.update_text
).grid(row=i,column=0,sticky=W)
# Message box
self.result = Text(self, width=40, height=5, wrap=WORD)
self.result.grid(row=i, column=0, columnspan=3)
def update_text(self):
message = "File selected is "
message += self.filelist.get()
self.display_image()
self.result.delete(0.0, END)
self.result.insert(0.0, message)
def display_image(self):
try:
self.image = Image.open(self.filelist.get())
except:
message += self.filelist.get() + " doesn't exist. This is awkward..."
img_width,img_height = self.image.size
self.preview_image = ImageTk.PhotoImage(self.image)
self.preview = Label(self, image=self.preview_image)
self.preview.grid(row=0, column=3, rowspan=20)
app = Application(root)
root.mainloop()

GTKMM: GtkPopOver in a cell of Gtk TreeView

How I can put a GtkPopOver in a cell of Gtk TreeView. When I click in the cell I need that Popover appears.
I can not find any examples in GTKMM than associating a cell of GtkTreeView with one GtkPopover.
Thanks.
Having gone through a similar situation, I was able to solve this with (simplified version in python):
def click_callback(..., event):
rect = Gdk.Rectangle()
rect.x = event.button.x
rect.y = event.button.y
rect.width = rect.height = 1
popover = Gtk.Popover.new_from_model(treeview, model)
popover.set_pointing_to(rect)
popover.show()
I've solved it and here is a simplified version from the code that I used:
class Table(Gtk.TreeView):
# Gtk stuff ...
#GtkTemplate.Callback
def on_button_press_event(self, widget, event):
path, path_iter, col = self.__get_path_at_position(event)
btn = event.button
if btn == 3:
pop = Gtk.Popover()
# Customize
pop.set_pointing_to(self.get_cell_area(path, col))
pop.set_relative_to(self)
pop.popup()
return True
return False
def __get_path_at_position(self, event):
path_info = self.get_path_at_pos(event.x, event.y)
if path_info:
path, column, cell_relative_x, cell_relative_y = path_info
path_iter = self.__model.get_iter(path)
return path, path_iter, column,
return None, None, None
It is not C++ though but I think it should be enough to do it in C++. It turned out that both functions
pop.set_pointing_to(self.get_cell_area(path, col))
pop.set_relative_to(self)
are required.

Aligning Label in Frame Tkinter

I am new to Python and even newer to Tkinter.
I am currently practicing how to use Frames and Labels and
the problem I am encountering is, when I put Labels on a frame with some buttons next to each label,
the alignment is not good to look at.
Here is the code:
from Tkinter import *
class GUI():
def __init__(self):
self.namelist = ["Mark","Anna","Jason","Lenna","Leo","Zucharich","Robinson","AReallyLongNameThatMightExist"]
self.canvas = Canvas(width=1200,height=700)
self.canvas.pack(expand=YES,fill=BOTH)
def Friends(self):
controlframe = Frame(self.canvas)
controlframe.place(x=600,y=300)
#Frame for showing names of friends
for x in self.namelist:
frame = Frame(controlframe)
frame.pack()
Name = Label(frame,text="%s "%x).pack(side=LEFT)
chatButton = Button(frame,text="Chat").pack(side=LEFT)
delButton = Button(frame,text="Delete").pack(side=LEFT)
setcloseButton = Button(frame,text="Set Close").pack(side=LEFT)
setgroupButton = Button(frame,text="Set Group").pack(side=LEFT)
mainloop()
GUI = GUI()
GUI.Friends()
What should I do so that the alignment of the Label(=name) and the button is equal to the other ones so that they will form a shape of a rectangle and not some zigzag?
It is almost always better in Tk to use the grid geometry manager. It is much more flexible once you come to understand how it works. Converting your example to use grid solves your problem as shown below but you should experiment with it a bit. Try removing the 'sticky="W"' from the label for instance and see that the centering of the widgets within the row or column can be controlled. To get your frame responding to resizes sensibly you should investigate the columnconfigure and rowconfigure options for the grid geometry management as well.
from Tkinter import *
class GUI():
def __init__(self):
self.namelist = ["Mark","Anna","Jason","Lenna",
"Leo","Zucharich","Robinson",
"AReallyLongNameThatMightExist"]
self.canvas = Canvas(width=1200,height=700)
self.canvas.pack(expand=YES,fill=BOTH)
def Friends(self):
frame = Frame(self.canvas)
frame.place(x=600,y=300)
#Frame for showing names of friends
row = 0
for x in self.namelist:
label = Label(frame,text="%s "%x)
chatButton = Button(frame,text="Chat")
delButton = Button(frame,text="Delete")
setcloseButton = Button(frame,text="Set Close")
setgroupButton = Button(frame,text="Set Group")
label.grid(row=row, column=0, sticky="W")
chatButton.grid(row=row, column=1)
delButton.grid(row=row, column=2)
setcloseButton.grid(row=row, column=3)
setgroupButton.grid(row=row, column=4)
row = row + 1
mainloop()
GUI = GUI()
GUI.Friends()

Keep a Frame in an other window Frame

My programm create a Frame with three panels in an horizontal boxsizer. A menu with "new window" item for create a seconde Frame. I give the seconde panel as parent of the seconde window. I wante the seconde Frame stays in the seconde panel area of my first frame.
if user move one of the two windows, the seconde stays in the panel screen area.
Do you know a way or something for that?
I tried a little something, but using is not very aesthetic.
and
import wx
class MainWindow(wx.Frame):
def __init__(self,parent,id):
wx.Frame.__init__(self,parent,id,'Python Test App',size=(600,400))
#Widgets
panel_gch = wx.Panel(self,-1,size = (150,-1))
panel_gch.SetBackgroundColour('white')
self.panel=wx.Panel(self,-1,size=(300,400))
self.panel.SetBackgroundColour((200,230,200))
panel_drt = wx.Panel(self,-1,size = (150,-1))
panel_drt.SetBackgroundColour('white')
box = wx.BoxSizer(wx.HORIZONTAL)
self.SetSizer(box)
#Add
box.Add(panel_gch,0,wx.EXPAND)
box.Add(self.panel,1,wx.EXPAND)
box.Add(panel_drt,0,wx.EXPAND)
#Menu
status=self.CreateStatusBar()
menubar=wx.MenuBar()
file_menu=wx.Menu()
ID_FILE_NEW = 1
file_menu.Append(ID_FILE_NEW,"New Window","This is a new window")
menubar.Append(file_menu,"File")
self.SetMenuBar(menubar)
#bind and layout
self.Bind(wx.EVT_MENU, self.get_new_window)
panel_gch.Layout()
self.panel.Layout()
panel_drt.Layout()
self.Layout()
def get_new_window(self,event): # create new window
self.new = NewWindow(self.panel,-1)
self.new.Show(True)
self.new.Bind(wx.EVT_MOVE,self.window2_on_move)
def window2_on_move(self,event): # Window2 must stay in
x, y = event.GetPosition()
v,w =self.panel.GetScreenPosition()
s,t = self.panel.GetClientSizeTuple()
if x < v:
self.new.Move((v,-1))
if y < w:
self.new.Move((-1,w))
if x+200 > v+s:
self.new.Move((v+s-200,-1))
if y+200 > w+t:
self.new.Move((-1,w+t-200))
class NewWindow(wx.MiniFrame):
def __init__(self,MainWindow,id):
wx.MiniFrame.__init__(self, MainWindow, id, 'New Window', size=(200,200),\
style = wx.MINIMIZE | wx.CAPTION | wx.CLOSE_BOX | wx.CLOSE_BOX)
self.CenterOnParent()
if __name__=='__main__':
app=wx.PySimpleApp()
frame=MainWindow(parent=None,id=-1)
frame.Show()
app.MainLoop()
What you probably want is AUI. I personally recommend the wx.lib.agw.aui set rather than wx.aui as the former is pure Python and has had a LOT more recent work done on it. There are multiple examples in the wxPython demo package. You can also read about it here:
http://wxpython.org/Phoenix/docs/html/lib.agw.aui.framemanager.AuiManager.html
Thanks you very much Mike, exactly what I needed.
With wxpython I found This way:
the child stays in the panel area and it follows the window parent when moving.
import wx
class MainWindow(wx.Frame):
def __init__(self,parent,id):
wx.Frame.__init__(self,parent,id,'Python Test App',size=(600,400))
self.new = None
#Widgets
self.position = (0,0)
panel_gch = wx.Panel(self,-1,size = (150,-1))
panel_gch.SetBackgroundColour('white')
self.panel=wx.Panel(self,-1,size=(300,400))
self.panel.SetBackgroundColour((200,230,200))
panel_drt = wx.Panel(self,-1,size = (150,-1))
panel_drt.SetBackgroundColour('white')
box = wx.BoxSizer(wx.HORIZONTAL)
self.SetSizer(box)
#Add
box.Add(panel_gch,0,wx.EXPAND)
box.Add(self.panel,1,wx.EXPAND)
box.Add(panel_drt,0,wx.EXPAND)
#Menu
status=self.CreateStatusBar()
menubar=wx.MenuBar()
file_menu=wx.Menu()
ID_FILE_NEW = 1
file_menu.Append(ID_FILE_NEW,"New Window","This is a new window")
menubar.Append(file_menu,"File")
self.SetMenuBar(menubar)
#bind and layout
self.Bind(wx.EVT_MENU, self.get_new_window)
panel_gch.Layout()
self.panel.Layout()
panel_drt.Layout()
self.Layout()
def get_new_window(self,event): # create new window
if self.new == None:
self.win_one_move = False
self.new = NewWindow(self.panel,-1)
self.new.Show(True)
self.new.Bind(wx.EVT_MOVE,self.window2_on_move)
self.Bind(wx.EVT_MOVE,self.window1_on_move)
v,w =self.GetPosition()
x, y = self.new.GetPosition()
self.get_windows_position((x-v),(y-w))
def get_windows_position(self,x,y):
self.position = (x,y)
print "check",self.position
def window2_on_move(self,event): # Window2 must stay in
if self.win_one_move == False:
x, y = event.GetPosition()
v,w =self.panel.GetScreenPosition()
s,t = self.panel.GetClientSizeTuple()
new_x,new_y = self.new.GetClientSizeTuple()
if x < v:
self.new.Move((v,-1))
if y < w:
self.new.Move((-1,w))
if x+new_x > v+s:
self.new.Move((v+s-new_x,-1))
if y+new_y > w+t:
self.new.Move((-1,w+t-new_y))
v,w =self.GetPosition()
x,y = self.new.GetPosition()
self.get_windows_position((x-v),(y-w))
if self.win_one_move == True:
self.win_one_move = False
def window1_on_move(self,event):
self.win_one_move = True
print "1 move"
x,y = self.GetPosition()
self.new.Move((x+self.position[0],y+self.position[1]))
print self.position
class NewWindow(wx.MiniFrame):
def __init__(self,MainWindow,id):
wx.MiniFrame.__init__(self, MainWindow, id, 'New Window', size=(200,200),\
style = wx.CAPTION | wx.CLOSE_BOX | wx.CLOSE_BOX)
self.CenterOnParent()
if __name__=='__main__':
app=wx.PySimpleApp()
frame=MainWindow(parent=None,id=-1)
frame.Show()
app.MainLoop()
Can be use by another.Thanks