I am using wxPython to make a gui. Currently I have a menubar, and three panels. I want to have a grid show up in the second panel when I click a button. However. When I click on the button, all I get is a small grey rectangle.
Here is the code for the button:
self.Bind(wx.EVT_BUTTON, self.OnCo, id=self.submit.GetId())
and here is the code for the "OnCo" event when the button is clicked:
def OnCo(self, e):
#to get rid of stuff that was previously in the panel
for child in self.panel2.GetChildren():
child.Destroy()
for child in self.panel3.GetChildren():
child.Destroy()
mygrid = gridlib.Grid(self.panel2, -1)
mygrid.CreateGrid(500,7)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(mygrid, -1, wx.EXPAND)
self.panel2.SetSizer(sizer)
mygrid.SetColLabelValue(0, 'S')
mygrid.SetColLabelValue(1, 'PB')
mygrid.SetColLabelValue(2, 'P')
mygrid.SetColLabelValue(3, 'T')
mygrid.SetColLabelValue(4, 'D')
Any help on how I can get my grid to show? Thanks.
It's possible that the grid is not sizing correctly; your items may be there, but it's not showing everything. After changing values in a grid, I always make sure to update the sizing of it. I usually just add a simple function to the class like this:
def SetGridSize(self):
self.mygrid.AutoSizeRows()
self.mygrid.AutoSizeColumns()
self.sizer.Fit(self)
and then call SetGridSize() whenever I change the values to make sure the whole thing shows on the screen instead of getting cut off.
Of course, you'll have to adapt it a bit to your names and whatnot. This implementation assumes the class is a wx.Frame object.
Related
The button size should be controlled by packing HBox in VBox but my two buttons still have size depending on text:
first=Gtk.VBox()
second=Gtk.HBox()
third=Gtk.VBox()
fourth=Gtk.HBox()
but1=Gtk.Button(label="any title")
first.pack_start(second,False,False,0)
third.pack_start(fourth,False,False,0)
first.pack_start(but1,False,False,0)
self.data_wp="title of label"
self.label_data=Gtk.Label(label=self.data_wp)
Gtk.Widget.set_size_request(but1,85,15)
but2=Gtk.Button(label=self.data_wp)
Gtk.Container.add(but2,self.label_data)
Gtk.Widget.set_size_request(but2,85,15)
What am I doing wrong? I add button title from label but it shoudn't be the problem, and I tried to set title directly on button - nothing changed. I tried to use only one set of VBox,HBox, but it gave no effect too.
I think the problem here is that you're trying to resize the button using the set_size_request() method of the Gtk.Widget. But set_size_request() only set the minimum size of the widget, so it can still be larger.
I don't know if there is a method to resize the button, but there are the properties width-request and height-request of the Gtk.Widget that you can use.
In your code, it would be:
bt1.set_property("width-request", 85)
bt1.set_property("height-request", 15)
I am trying to develop a GUI that contains a QTextEdit widget. When the gui loads, it pulls in data from a file where the data is in columns of fixed widths.
I want the user to be able to click at various points in the QTextEdit widget, to mark the positions where new columns start, and I want vertical lines to be drawn on the widget at those positions, to show the columns.
In my GUI init() method I had the following line to intercept the paintEvent from the text widget:
self.mytextviewer.paintEvent = self.handlePaintEvent
and I had a handlePaintEvent() method:
def handlePaintEvent(self, event):
painter = QPainter(self.mytextviewer)
pen = QPen(Qt.SolidLine)
pen.setColor(Qt.black)
pen.setWidth(1)
painter.setPen(pen)
painter.drawLine(20, 0, 20, 100)
However when I tried to run the code I started to get QPainter errors about the painter not being active.
I then tried a different direction, subclassing QTextEdit and adding basically the same code as above to the paintEvent() method of my subclass. However I am still getting the errors.
I then tried adding painter.begin(self) and painter.end()to the paintEvent() method, but had no joy with that either.
Also, the text that was initially being displayed in the widget is no longer displayed since I added my custom paintEvent() method.
Am I doing something really stupid here, or is there a better/easier way to go about this?
Thanks.
I found an answer, hopefully it might help someone else....
You need to supply QPainter with the widgets viewport when creating an instance of QPainter in the paintEvent().
To get it to display the text, include the super() method of the parent class.
def paintEvent(self, event):
painter = QPainter(self.viewport())
pen = QPen(Qt.SolidLine)
pen.setColor(Qt.black)
pen.setWidth(1)
painter.setPen(pen)
painter.drawLine(20, 0, 20, 100)
super(TextWidgetWithLines, self).paintEvent(event)
I'm taking the first steps to move from .NET to Python but I'm already having a few headaches regarding the GUI design.
For some reason, passing the size attribute to a wx.Button seems to be kind of ignored. And I say "kind of" because the actual space seems to change but the actual button keeps occupying the same space:
import wx
class Example(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
self.SetSize((800, 600))
self.SetTitle('Main Menu')
self.Centre()
self.Show(True)
''' Fill the form '''
self.lblUsername = wx.StaticText(self, size=(80, -1), pos=(20,20), label="Username:" )
self.txtUsername = wx.TextCtrl(self, size=(140, -1), pos=(100,20), style=wx.TE_PROCESS_ENTER)
self.lblPassword = wx.StaticText(self, size=(80, -1), pos=(20,50), label="Password:" )
self.txtPassword = wx.TextCtrl(self, size=(140, -1), pos=(100,50), style=wx.TE_PROCESS_ENTER)
self.btnOK = wx.Button( self, label="OK", pos=(260, 16), size=(50,50))
self.btnOK.Bind(wx.EVT_BUTTON, self.onClickOK)
self.statusbar = self.CreateStatusBar()
self.statusbar.SetStatusText('Ready')
def onClickOK(self, e):
print "Button triggered"
def main():
ex = wx.App()
Example(None)
ex.MainLoop()
if __name__ == '__main__':
main()
No matter what size I set, the Button won't stretch (it will be centered as if all the space was actually being used, but will still be small).
Can anyone spot what am I doing wrong?
This is a limit imposed by OSX. The way the native button widget is drawn only allows it to be stretched horizontally, and the vertical size is fixed. Or rather, as you've discovered, the widget itself can be larger than normal vertically, but it will only draw itself at a fixed height within that space. It seems less neccessary with modern versions of OSX, but if you look at buttons in OSX from a few years ago you can probably see why this is so. The esthetic graphical effect of the "tic-tack" or "capsule" buttons would be totally ruined if they were a non-standard vertical size, causing the images used to draw the buttons to be stretched. wxWidgets follows the native plaform look and feel standards where possible, in this case it happens that Apple's standard is imposed upon us and wx can't offer the same level of flexibility that it usually does.
You do have some options however if you really want taller than normal buttons. The native widgets have a few different standard sizes, which you can select using the SetWindowVariant method, although I don't think the variants would get as tall as you want. Or you could use a generic button widget instead of a native one, such as wx.lib.buttons.ThemedGenButton.
Same problem in my little Software EventSoundControl.
Just a workaround: Use a multiline label and sizes of wxButton will work as desired!
If you want the button to stretch when you resize the frame, then you cannot use static sizes and positioning. You will need to put your widgets in a sizer. Then the sizer will manage the position / size of the widget(s) as you change the size of the frame. There are many examples on the wxPython wiki that demonstrate how to use sizers. You might also find the following tutorial helpful:
http://zetcode.com/wxpython/layout/
So, I'm trying to write a program using wxPython which will have a notebook with tabs that each have the user enter some data into textboxes. This is for a physics related project so I want each textbox to have a "units" label after it displaying what units it should be entered in. The problem is: When the program runs, I get a black rectangle in the upper left corner of each textctrl which is the size of the label that the units are in. The black box disappears forever immediately after any of the following:
press tab onto the textctrl
move the cursor onto the textctrl
switch tabs in the notebook
resize the window until the textctrl has to shrink with it.
functionally everything works fine, I just want to get rid of the black rectangles on startup.
This is my code:
#! usr/bin/python
import wx
class MainWindow(wx.Frame):
def __init__(self, title):
wx.Frame.__init__(self, None, title=title, size=(400,300))
self.make_gui()
self.Show()
def make_gui(self):
self.panel=wx.Panel(self,wx.ID_ANY)
sizer=wx.BoxSizer(wx.VERTICAL)
ins=self.gui_inputs()
sizer.Add(ins)
self.panel.SetSizer(sizer)
def gui_inputs(self):
sizer=wx.BoxSizer(wx.HORIZONTAL)
simpleinputs=(("Page 1",(("Name",None),("Item","in"))),("sec page",tuple()))
simple=self.gui_inputs_make_simple(simpleinputs)
sizer.Add(simple)
return sizer
def gui_inputs_make_simple(self,simpleinputs):
sizer=wx.BoxSizer(wx.VERTICAL)
notebook=wx.Notebook(self.panel)
for tab in simpleinputs:
pan=wx.Panel(notebook,wx.ID_ANY)
siz=wx.BoxSizer(wx.VERTICAL)
for item in tab[1]:
it=self.gui_inputs_make_labeled_unitinput(pan,item[0],item[1])
siz.Add(it)
pan.SetSizer(siz)
notebook.AddPage(pan,tab[0])
sizer.Add(notebook)
return sizer
def gui_inputs_make_labeled_unitinput(self,par,label='',units='',validatenumber=False):
sizer=wx.BoxSizer(wx.HORIZONTAL)
lbl=wx.StaticText(par,label=label+':')
sizer.Add(lbl)
edit=wx.TextCtrl(par)
sizer.Add(edit)
if units!=None:
unit=wx.StaticText(par,label=units)
sizer.Add(unit)
return sizer
app = wx.App(False)
frame = MainWindow("GUI")
app.MainLoop()
and this is a screenshot of what I get:
The following are ways I was able to get the black rectangles to disappear (but none let me do what I need to do):
When I remove the code to put the units in, it works. When I remove the text from the units fields, it works. When I have only one tab, it works.
If anyone can tell me why this is happening, I would be greatly appreciative.
Thanks in advance!
This was an interesting one:
The black boxes in the TextCtrl instances disappear as soon the sizer cascades are set up properly. You can do this by updating the layout of your main sizer by:
sizer.Layout()
or
sizer.Fit(self)
at the end of your make_gui method.
This works for me but does of course not explain why the TextCtrl stays black in the first place without.
I have a label that I want right aligned and the text to be right aligned. But when my code runs through and the label updates it, the StaticText aligns to the left of a button object. My code is below
hbox14 = wx.BoxSizer(wx.HORIZONTAL)
self.buttonRemove = wx.Button(self.panel,label='Remove')
self.buttonRemove.Bind(wx.EVT_BUTTON,self.removeAccount) # Remove account from list
self.labelSecTic = wx.StaticText(self.panel,label='0.0',style=wx.TE_RIGHT|wx.EXPAND)
self.labelSecTic.SetForegroundColour('white')
self.labelSecTic.SetBackgroundColour('black')
hbox14.Add(self.buttonRemove,proportion=0)
hbox14.Add(self.labelSecTic,proportion=1,flag=wx.ALIGN_RIGHT|wx.TE_RIGHT|wx.EXPAND)
When the label is updated I call
self.gui.labelSecTic.SetLabel(str(self.diff))
Any suggestions on how to make the labelSecTic stay fixed to the right side of the panel? Thanks.
First a side note: the style wx.TE_RIGHT is for wx.TextCtrl, it probably does nothing with the static text. About your real issue, you should force layout of the hbox14 sizer. Not sure what is the sizer/panel structure of your window, you should call Layout on some ancestor of hbox14, it might be self.gui.panel or even self.gui (don't know what gui is), so for example:
self.gui.labelSecTic.SetLabel(str(self.diff))
self.gui.Layout()
or
self.gui.labelSecTic.SetLabel(str(self.diff))
self.gui.panel.Layout()