Sizers don't support doing that. Scrolled windows have the ability to
be made to work that way, sort of. Basically you would need to use some
extra child windows of the scrolled window. One for the first column,
one for the first row, and one for the scrollable area. You would then
need to call SetTargetWindow to make the scrolled window use the child
for the scrollable area as the one to actually do the scrolling.
(wx.grid.Grid is implemented this way.)
--
Robin Dunn
Software Craftsman
http://wxPython.org
Based on your description of what you are wanting to create, doing it
yourself might be a lot better than trying to pound it into
wx.grid.Grid. You may also want to think about using something like
FloatCanvas as it will handle all of the low-level drawing (and
buffering, scaling, zooming, etc.) for you and let you deal with the
higher level shape objects representing the labels, grid lines,
appointment blocks, etc.
There is a version of it distributed with wxPython. See
wx.lib.floatcanvas and the samples in the demo.
[...]
>
> What do you think of this approach? Am I doing something very klutzy?
Not the ideal approach, but if it works for you then go for it.
Not sure if I am doing something wrong with the search, but it looks like search in Google Group seems to be limited to recent months, so a search for the original discussion topic (prior to this re-post) doesn't find it.
I originally posted this in www.nabble.com, but shortly after,
realised that the forum had moved over to Google Groups, so I re-
posted the message in Google Group's wxPython. I then deleted the
posting in www.nabble.com. Subsequent replies and postings were all
done in Google Groups.
we'll see!
> I also re-attach a copy of the requirements implemented using
> GridBagSizer, lots of wx.Panels and lots and lots of coding to implement
> what appears to be fairly simple requirements.
Actually, I don't think these requirements are simple at all.
> (a) Have a spreadsheet-like view of rows and columns. Scrollbars should
> appear when contents exceed available window space. Row titles and
> column titles should never scroll out of view during scrolling but
> should scroll itself accordingly e.g. like the row and column titles in
> wx.Grid
>
> (b) Contents may span rows or parts of rows.
hmmm - I guess what you really want is a wxGrid they allows spanning of
rows. I haven't really used wx.Grid, but I take it doesn't support that.
> Rows are time periods of
> half an each: e.g. 2pm to 2:30pm, 2:30pm to 3pm etc, but appointments
> (the contents) may be from 2:15 pm to 3:45pm.
>
> I have implemented these requirements as per the attached code. I only
> managed to get it working after a lot of difficulties, but this is also
> in part due to the fact that this was my first wx.Python attempt
Well, you have jumped into the deep end!
> This code now 'seems' to be working and with 'reasonable' performance
Is there something that the Chandler project developed that you could
use? I imagine they had a Calendar control that might be able to be used
like this.
> but is probably not a good way to do it, and I suspect will require a
> lot more coding or hit some limitations as I try to finish up other
> requirements.
>
> This is how the code was implemented using GridBagSizer and wx.Panels:
Well, there may be tweaks you can do to this, but the other option is
really to draw the whole thing yourself, with wxDC or wxGraphicsContext.
If you want to be able to zoom it , then FloatCanvas could help.
Otherwise, I'd probably just do it from scratch, which would give you
full control, but it would be a fair bit of of work. If this approach is
working for you, I'd probably just stick with it. If you do go that
route, I've been experimenting with using wxHtml to layout an render
text to an off-screen bitmap, which can then be drawn with a DC -- that
might be a way to do your text boxes.
> (b) Scrolling is achieved by shuffling windows that have scrolled
> out of view to the far side, out of view (e.g. for row titles, they are
> shuffled to far bottom and for column titles they are shuffled to far
> right (out of view).
It seems you should be able to use a wxScrolledWindow to do this for
you, I know I've seen examples of putting lots of widgets on a
ScrolledPanel around somewhere. That would require that the row an
column labels be on different Panels, so I'm not sure how you'd keep
them scrolled correctly, but I'll bet its possible.
> (c) Ability to span partial rows is achieved by creating a column of
> cells that represent 5-minute intervals. Each visible 'period label' row
> of half an hour spans 6 of the 5-minute interval cells; and appointments
> are placed by referencing the y-position of the 5-minute interval cells
> and not the 30-minute period labels. i.e. appointments can be displayed
> with 5-minute resolution.
nice trick!
> The sample code also demonstrates one of the functions that the schedule
> should implement: change appointment. Click on an appointment, and it
> will be highlighted, and at the top, an option to shift the appointment
> is shown.
Hmm -- FloatCanvas could help with this too. It supports binding to objects.
You also could pop up a "editor" window right on top of the selected
app. instead.
As I think about it, you are doing a fair bit of work keeping track of
layout and all yourself, so it may not be that much more work to draw
stuff yourself, too.
I don't know it this helped any,
-Chris
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Date: 2009/8/18 Subject: [wxPython-users] Re: Scrolling while freezing first column and first row To: wxPytho...@googlegroups.com
Actually, I don't think these requirements are simple at all.
hmmm - I guess what you really want is a wxGrid they allows spanning of rows. I haven't really used wx.Grid, but I take it doesn't support that.
Rows are time periods of half an each: e.g. 2pm to 2:30pm, 2:30pm to 3pm etc, but appointments (the contents) may be from 2:15 pm to 3:45pm. I have implemented these requirements as per the attached code. I only managed to get it working after a lot of difficulties, but this is also in part due to the fact that this was my first wx.Python attemptWell, you have jumped into the deep end!
Is there something that the Chandler project developed that you could use? I imagine they had a Calendar control that might be able to be used like this.
Well, there may be tweaks you can do to this, but the other option is really to draw the whole thing yourself, with wxDC or wxGraphicsContext.
If you want to be able to zoom it , then FloatCanvas could help.
Otherwise, I'd probably just do it from scratch, which would give you full control, but it would be a fair bit of of work. If this approach is working for you, I'd probably just stick with it.
It seems you should be able to use a wxScrolledWindow to do this for you, I know I've seen examples of putting lots of widgets on a ScrolledPanel around somewhere. That would require that the row an column labels be on different Panels, so I'm not sure how you'd keep them scrolled correctly, but I'll bet its possible.
(c) Ability to span partial rows is achieved by creating a column of cells that represent 5-minute intervals.
Initially, I thought it was good enough to have a display resolution of 30 minutes. When I realised that it wasn't, I was stumped for quite a while. I had already done quite a lot of code based on scrolling with resolution of 30 minutes. Luckily I figured out this way around it.nice trick!
The sample code also demonstrates one of the functions that the schedule should implement: change appointment. Click on an appointment, and it will be highlighted, and at the top, an option to shift the appointment is shown.Hmm -- FloatCanvas could help with this too. It supports binding to objects. You also could pop up a "editor" window right on top of the selected app. instead.
As I think about it, you are doing a fair bit of work keeping track of layout and all yourself, so it may not be that much more work to draw stuff yourself, too.
I don't know it this helped any,
Well, you get it for free, so why not?
> increase to 500 wx.Panels. Am I reaching any sorts of limits in
> wx.Python with these numbers?
I'm not sure, but that does seem like a lot.
> boxes). The 5-minute interval windows (almost 200) are even simpler,
> just background colour with no contents and no events.
maybe you don't need windows for that -- StaticBitmaps are not real
Windows on all platforms. Or is that what you are using anyway?
> Currently, the performance seems to be acceptable; nothing takes longer
> than a second,
a second is a pretty long time, actually.
> some testing and it looks like I can repaint just part of the window
> with (a).
yes, you only need to paint what has changed.
> As an example, when the user clicks on the time slot, it is highlighted
> with a yellow border. With the current many wx.Panels approach, I only
> need to redraw the selected wx.Panel. With the single large wx.Panel
> approach would I need to repaint the entire window?
nope, only what's been damaged, though you need to figure out what that is.
> It looks like I can
> specify which part of the screen to repaint. (using BufferedDC? and
> specifying where to paint?)
Buffering is a good idea too -- you can buffer the Calendar, then draw
the highlighted event over the buffer. You only need to re-blit the
buffer to restore it. FloatCanvas does something like this with the
"foreground".
> Actually, it will probably be less work than what I am doing currently.
maybe, but it adds up.
The more I think about it, the more I think FloatCanvas may help. I'm
going to see if I can whip up a bit of a demo...
Phil Mayes wrote the following on 8/18/2009 11:14 PM:
> I would try this approach, using a ScrolledWindow and a buffered DC.
> +: no risk of slow-down due to many wx components
>
Yes, nice.
> +: complete control of look and feel
>
Yes, very nice.
> -: have to write code to mimic the decorations supplied by wx, eg
> borders, buttons, ...
>
Not too bad. Only the Calendar window is self-drawn. Other parts of the
frame can have panels using wx Buttons, Menu, status bar, etc. The
calendar is a table with text and some simple graphic objects (coloured
boxes), so it probaly won't look too out of place.
> -: needs a data structure to describe location on screen that can
> be used by a) drawing code b) mouse handling code
>
Yes, this will be the bulk of the work.
> I would have separate windows for the 1st row and column and update
> them in response to the Draw events caused by scrolling.
>
I think there may be some advantages with not using ScrolledWindow i.e.
draw everything using buffered DC only. If I use ScrolledWindow, I will
need to coordinate the scrolling events of the ScrolledWindow with that
of the row and column titles. This means that I am handling scrolling
using 2 different ways (one via ScrolledWindow and another via manual
redrawing). I am not sure I know how to do this; have to try. Thing is,
since I am going to have to 'scroll' the row and column labels, I might
as well handle the 'scroll' of the contents - i.e. only 1 set of logic
to code for; and no worries about scrolling becoming un-cordinated.
>> increase to 500 wx.Panels. Am I reaching any sorts of limits in
>> wx.Python with these numbers?
>
> I'm not sure, but that does seem like a lot.
There is no explicit limit, other than resources that the OS provides.
But consider the difference between 500 paint events vs 1 paint event.
What would you recommend I should use to give explanations of grid column headings ?
I have grids where the headings aren't obvious, and I need to explain what possible values the column cells could display.
In a similar situation, which wxPython widget would you use ?
Thanks,
Ron.