wx.Frame positioning

Lubuntu-18.04, Python-3.6.7, wxWidgets-4.0.4, GTK3 .
I have been using wxPHP for a few years, but now I am writing my very first wxPython app.
I cannot position the frame at anythng other than (0, 0) with the constructor parameters, or with the SetPosition() method, or with the Centre() method.
GetPosition() returns the correct values, but the actual position on the screen is (0, 0), which I presume is wxDefaultPosition.
Size works OK.
It must be something totally obvious to everybody but me, but what is it?


#!/usr/bin/env python
# frame.py example
import wx
app = wx.App(False) # frame
frame_xpos = 100
frame_ypos = 200
frame_width = 640
frame_height = 480
frame_title = "Title"
frame_icon = "./python/icon.png"
frame = wx.Frame(None, -1)
frame.SetPosition(wx.Point(frame_xpos, frame_ypos))
frame.SetSize(wx.Size(frame_width, frame_height))
frame.SetIcon(wx.Icon(frame_icon))
frame.SetTitle(frame_title)
frame.Show(True) print frame.GetPosition()
# events
app.MainLoop()



The terminal outputs a warning (which I would like to suppress):

···

$ ./python/frame.py
(frame.py:7367): dbind-WARNING **: 12:08:46.199: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files
(100, 200)

Are you sure that the Python you are using is 3.6.7 and wxPython is 4.0.4? I would expect a syntax error on the old-style print statement if you were.

···

On Thursday, April 11, 2019 at 9:00:49 AM UTC-7, Dave Kimble wrote:

Lubuntu-18.04, Python-3.6.7, wxWidgets-4.0.4, GTK3 .
I have been using wxPHP for a few years, but now I am writing my very first wxPython app.
I cannot position the frame at anythng other than (0, 0) with the constructor parameters, or with the SetPosition() method, or with the Centre() method.
GetPosition() returns the correct values, but the actual position on the screen is (0, 0), which I presume is wxDefaultPosition.
Size works OK.
It must be something totally obvious to everybody but me, but what is it?

Robin

Using python 3.6.x
and wxPython 4.0.4 it works for me if I don’t use the print
statement.

Johnf

···

On 4/11/19 12:21 AM, Dave Kimble wrote:

Lubuntu-18.04, Python-3.6.7, wxWidgets-4.0.4, GTK3 .
I have been using wxPHP for a few years, but now I am
writing my very first wxPython app.
I cannot position the frame at anythng other than (0, 0)
with the constructor parameters, or with the SetPosition()
method, or with the Centre() method.
GetPosition() returns the correct values, but the actual
position on the screen is (0, 0), which I presume is
wxDefaultPosition.
Size works OK.
It must be something totally obvious to everybody but me,
but what is it?


#!/usr/bin/env python
# frame.py example
import wx
app = wx.App(False) # frame
frame_xpos = 100
frame_ypos = 200
frame_width = 640
frame_height = 480
frame_title = "Title"
frame_icon = "./python/icon.png"
frame = wx.Frame(None, -1)
frame.SetPosition(wx.Point(frame_xpos, frame_ypos))
frame.SetSize(wx.Size(frame_width, frame_height))
frame.SetIcon(wx.Icon(frame_icon))
frame.SetTitle(frame_title)
frame.Show(True) print frame.GetPosition()
# events
app.MainLoop()



        The terminal outputs a warning (which I would like to

suppress):


$ ./python/frame.py
(frame.py:7367): dbind-WARNING **: 12:08:46.199: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files
(100, 200)

  You received this message because you are subscribed to the Google

Groups “wxPython-users” group.

  To unsubscribe from this group and stop receiving emails from it,

send an email to wxpython-users+unsubscribe@googlegroups.com.

  For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).

Dave Kimble wrote:

Lubuntu-18.04, Python-3.6.7, wxWidgets-4.0.4, GTK3 .
I have been using wxPHP for a few years, but now I am writing my very first wxPython app.
I cannot position the frame at anythng other than (0, 0) with the constructor parameters, or with the SetPosition() method, or with the Centre() method.
GetPosition() returns the correct values, but the actual position on the screen is (0, 0), which I presume is wxDefaultPosition.

In X, the window positioning is not entirely under the application's control. The window manager gets involved. For what it's worth, your code works fine under Windows.

The terminal outputs a warning (which I would like to suppress):

GTK is the most annoyingly chatty whiner of a library I've ever encountered. I have a relatively complicated wxWidgets app with a notebook with 8 panels, each of which has a dialog, and I get two dozen ridiculous and pointless warnings from GTK every time I start.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Are you sure that the Python you are using is 3.6.7 and wxPython is 4.0.4? I would expect a syntax error on the old-style print statement if
you were.

Well, I am sure I HAVE Python 3.6.7 installed, but I don’t know if wxPython is using it. How do I tell?

After a LOT of difficulty with the setup, I finally used this from stackexchange:

sudo apt install make gcc libgtk-3-dev libwebkitgtk-dev libwebkitgtk-3.0-dev libgstreamer-gl1.0-0 freeglut3 freeglut3-dev python-gst-1.0 python3-gst-1.0 libglib2.0-dev ubuntu-restricted-extras libgstreamer-plugins-base1.0-dev python-wxgtk3.0

  In X, the window positioning is not entirely under the

application’s control. The window manager gets involved.

In Lubuntu the window manager is Openbox, which is a major difference from Ubuntu. It worked without problems in wxPHP.

···

On Friday, April 12, 2019 at 2:00:49 AM UTC+10, Dave Kimble wrote:

use the the command
line.

      If it's python2.x

you get

      johnf@linux-zu1d:~>

python

      Python 2.7.14 (default, Oct 12 2017, 15:50:02) [GCC] on linux2

      Type "help", "copyright", "credits" or "license" for more

information.

      >>>

for python 3.6.x

      johnf@linux-zu1d:~>

python3

      Python 3.6.5 (default, Mar 31 2018, 19:45:04) [GCC] on linux

      Type "help", "copyright", "credits" or "license" for more

information.

      >>>

      Please notice I used

“python3” to get python 3.6.5

Johnf

···

On 4/11/19 3:36 PM, Dave Kimble wrote:

    On Friday, April 12, 2019 at 2:00:49 AM UTC+10, Dave Kimble

wrote:

          Are you sure that the Python you are using is 3.6.7 and

wxPython is 4.0.4? I would expect a syntax error on the
old-style print statement if you were.

      Well, I am sure I HAVE Python 3.6.7 installed, but I don't

know if wxPython is using it. How do I tell?

      After a LOT of difficulty with the setup, I finally used

this from stackexchange:

        sudo apt install make

gcc libgtk-3-dev libwebkitgtk-dev libwebkitgtk-3.0-dev
libgstreamer-gl1.0-0 freeglut3 freeglut3-dev python-gst-1.0
python3-gst-1.0 libglib2.0-dev ubuntu-restricted-extras
libgstreamer-plugins-base1.0-dev python-wxgtk3.0

        In X, the window positioning is not entirely under the

application’s control. The window manager gets involved.

      In Lubuntu the window manager is Openbox, which is a major

difference from Ubuntu. It worked without problems in wxPHP.

  You received this message because you are subscribed to the Google

Groups “wxPython-users” group.

  To unsubscribe from this group and stop receiving emails from it,

send an email to wxpython-users+unsubscribe@googlegroups.com.

  For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).

Since you are using the #! spec due to running it as a shell command with ./python/frame.py then whatever python being executed by env python is the one that will be used to run your code. To force a specific instance of python to be used you can edit that line, or use a command line that runs a specific executable, like: /usr/bin/python3.6 ./python/frame.py

To double check, you can add code like this to the beginning of your script:

import sys

import wx

print(sys.version)

print(wx.version())

···

On Thursday, April 11, 2019 at 3:36:36 PM UTC-7, Dave Kimble wrote:

On Friday, April 12, 2019 at 2:00:49 AM UTC+10, Dave Kimble wrote:

Are you sure that the Python you are using is 3.6.7 and wxPython is 4.0.4? I would expect a syntax error on the old-style print statement if
you were.

Well, I am sure I HAVE Python 3.6.7 installed, but I don’t know if wxPython is using it. How do I tell?

Robin

$ python

Python 2.7.15rc1
$ python3

Python 3.6.7

$ ./python/frame.py(modified)
2.7.15rc1 (default, Nov 12 2018, 14:31:15)
[GCC 7.3.0]
3.0.2.0 gtk3 (classic)

I need someone to explain what that means.

It means you have both Python 2 and 3, but your default Python is 2.7 with wxWidgets 3.0.2.

If you would rather have Python 3 become your default, one easy way is to do:

cd /usr/local/bin

ln -s /usr/bin/python3 python

Now, when you type “python”, you’ll get Python 3.

···

On Apr 11, 2019, at 10:00 PM, Dave Kimble dave.kimble.2@gmail.com wrote:

$ python

Python 2.7.15rc1
$ python3

Python 3.6.7

$ ./python/frame.py(modified)
2.7.15rc1 (default, Nov 12 2018, 14:31:15)
[GCC 7.3.0]
3.0.2.0 gtk3 (classic)

I need someone to explain what that means.


Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

It means you have both Python 2 and 3, but your default Python is 2.7 with wxWidgets 3.0.2.

Thanks for that. Sorry about the misleading mistakes. Is there any good reason why i should care about versions? I now know that print x becomes print(x), which is more intuitive, I suppose. “print(filepicker.GetPath())” is returning “u’'” (that is 3 chars, a u and two single apostrophes) but printing nothing. What’s that all about?

https://www.google.com/search?q=python2+vs+python3

Python 2 is the legacy version. Python 3 is the current and future of the language. Unless there is a very good reason to stick with Python 2 (e.g. a large old project that can’t be ported) then the general consensus is to start with Python 3.

···

On Friday, April 12, 2019 at 1:22:38 AM UTC-7, Dave Kimble wrote:

It means you have both Python 2 and 3, but your default Python is 2.7 with wxWidgets 3.0.2.

Thanks for that. Sorry about the misleading mistakes. Is there any good reason why i should care about versions? I now know that print x becomes print(x), which is more intuitive, I suppose. “print(filepicker.GetPath())” is returning “u’'” (that is 3 chars, a u and two single apostrophes) but printing nothing. What’s that all about?

Robin

Oh, and u’’ is an empty unicode string.

···

On Friday, April 12, 2019 at 7:19:18 AM UTC-7, Robin Dunn wrote:

On Friday, April 12, 2019 at 1:22:38 AM UTC-7, Dave Kimble wrote:

It means you have both Python 2 and 3, but your default Python is 2.7 with wxWidgets 3.0.2.

Thanks for that. Sorry about the misleading mistakes. Is there any good reason why i should care about versions? I now know that print x becomes print(x), which is more intuitive, I suppose. “print(filepicker.GetPath())” is returning “u’'” (that is 3 chars, a u and two single apostrophes) but printing nothing. What’s that all about?

https://www.google.com/search?q=python2+vs+python3

Python 2 is the legacy version. Python 3 is the current and future of the language. Unless there is a very good reason to stick with Python 2 (e.g. a large old project that can’t be ported) then the general consensus is to start with Python 3.

Robin

Dave Kimble wrote:

I now know that print x becomes print(x), which is more intuitive, I suppose.

No, not more intuitive. The "print" statement in Python 1 and 2 was very intuitive and natural, but it was "impure". It's not a fundamental need of the language, it's just an I/O statement, and Guido felt that, as such, it should be a function in the library and not have special status as a language keyword. I don't particularly agree with the change, but I understand his motive. When they added the ability to print to different files, it required an ugly syntax hack:

 print >> other\_file, "This string"

and ugly syntax hacks have always bothered Guido.

"print(filepicker.GetPath())" is returning "u''" (that is 3 chars, a u and two single apostrophes) but printing nothing. What's that all about?

The print function doesn't return anything. Well, OK, it returns an empty string. You call it for its side effects -- writing something to a file. If you're in the interactive shell, just type
"filepicker.GetPath()" to see the value.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Another virtue of print() being a function is that you can replace it with your own (esp. useful for testing). After all, you can’t really replace a language statement.

“print(filepicker.GetPath())” is returning “u’'” (that is 3 chars, a u
and two single apostrophes) but printing nothing. What’s that all about?

The print function doesn’t return anything.

Yes, OK, I didn’t express that properly.

I have a wx.FilePickerCtrl() control named filepicker.

It calls picker_changed() on wx.EVT_FILEPICKER_CHANGED.

I click the control, select a filename, and I can see it shown in the filepicker control.

I pick it up with filepicker.GetPath() and open the file, and it fails “file not found”.

So I try and print it with print(filepicker.GetPath()), and it doesn’t print.

Why doesn’t filepicker.GetPath() return the path?

Why doesn’t print(filepicker.GetPath()) print anything?

Plus the original question: why does the frame always position itself at (0, 0) ?

In wxPHP I built up a template file with snippets of useful code, constructing controls, etc.,
now in wxPython, I am trying to rebuild that template file (attached).

When I run the file, virtually every control has something that doesn’t work about it.

  1. the frame only positions at (0, 0), despite the constuctor parameters, or .SetPosition(), or .Centre()

  2. the text control (multiline) and/or the 2 boxsizers don’t expand the control properly.
    The width is set to minimum width, despite having been expanded in the horizontal

  3. the file picker control seems to fire straight away instead of when the “picked file has changed” event happens. It thus returns an empty string for GetPath()

  4. the tray icon displays OK, but when clicked the event handler doesn’t do anything, it should frame.Raise() .

  5. the panel for holding an image isn’t displayed at all

See screenshot

template.py (2.73 KB)

Screenshot from 2019-04-13 14-06-45.png

Your coding style here is not the style used in wxPython. Check the samples; people use an object-based scheme, rather than just linearly creating windows, frames, and controls at the global level. You are going to find it difficult to map the many available examples to your non-class coding style.

Two of your biggest problems are related to your calls to Bind, and I don't believe this would have worked in wxPHP either. When you do this:

    trayicon.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, trayicon_clicked(frame))

it does not do what you think. You are thinking that this will cause the LEFT_DOWN event to call trayicon_clicked(frame). Instead, what this does is call trayicon_clicked(frame) immediately, then pass the return value to trayicon.Bind. That's wrong, and it happens every time you call Bind. That's why you see the immediate calls.

Even more than that, you are calling Bind incorrectly. You can't pass arbitrary parameters to a bound event handler. Your event handler will be passed an event object derived from wx.Event, and that's it. That's why people use classes; they can pass a method bound to a class instance, and they can store state in that class instance. In your case, you have to do:

    frame.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, trayicon_clicked)
and
    frame.Bind(wx.EVT_FILEPICKER_CHANGED, picker_changed, filepicker)
and
    top_panel.Bind(wx.EVT_BUTTON, button_clicked, button )
and
    frame.Bind(wx.EVT_TIMER, every_second)

Next, since your event handlers are not going to receive the parameters you're trying to pass, you should change their definitions to
    def button_clicked(evt):
    def picker_changed(evt):
    def trayicon_clicked(evt):
    def every_second(evt):

Fortunately, since you have your windows and controls stored in globals, you can access them by name, just like you have it in the code.

Next, you create both an hbox and vbox, and you try to call frame.SetSizer with both. A frame can only have one sizer at a time. The hbox is useless, so just delete it.

Next, you have this:
    photo_frame = wx.Panel(top_panel, -1)
    photo_frame.SetSize(wx.Size(photo_frame_width, photo_frame_height))
    photo_frame.SetBackgroundColour("#000000")
    photo_frame = wx.StaticBitmap(photo_frame, -1, photo)
    vbox.Add(photo_frame, 0, wx.ALL, 10)

You create a Panel. Then, you create a StaticBitmap owned by that Panel, but you store that bitmap into the same variable as the panel, so you've lost the panel. What you are adding to the vbox is the static bitmap, not the panel. The panel is not really necessary, so I changed this to:
    #photo_frame = wx.Panel(top_panel, -1)
    #photo_frame.SetSize(wx.Size(photo_frame_width, photo_frame_height))
    #photo_frame.SetBackgroundColour("#000000")
    photo_frame = wx.StaticBitmap(photo_frame, -1, photo)
    photo_frame.SetSize(wx.Size(photo_frame_width, photo_frame_height))
    vbox.Add(photo_frame, 0, wx.ALL, 10)

Next, you add all of the controls to the top_panel, but you attach the vbox to the frame. You need to set the sizer on the panel that actually owns the controls to be managed. So, instead of this:
    frame.SetSizer(hbox)
    frame.SetSizer(vbox)
    frame.Layout()
    frame.SetAutoLayout(True)
    frame.Show(True)

Do this:
    #frame.SetSizer(hbox)
    top_panel.SetSizer(vbox)
    top_panel.Layout()
    top_panel.SetAutoLayout(True)
    frame.Show(True)

With all of those changes, your code seems to work for me, but you should really think about learning how to use wxPython with classes.

···

On Apr 12, 2019, at 9:13 PM, Dave Kimble <dave.kimble.2@gmail.com> wrote:

In wxPHP I built up a template file with snippets of useful code, constructing controls, etc.,
now in wxPython, I am trying to rebuild that template file (attached).

When I run the file, virtually every control has something that doesn't work about it.


Tijm Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Tim, Many thanks for taking the time and effort to go thru all my newbie problems. I have followed all your fixes and everything now works, apart from the frame positioning.

Yes, I am trying to avoid using classes. This goes back to PHP’s horrible syntax for defining classes. It also gets rid of “self” all over the place, which I think is A Good Thing.

It’s a bit disappointing that Python cannot seem to cope with the event handler lines coming after app.Mainloop() line (button_clicked not defined), which is the logical place for them… Is there a way round this?

In wxPHP I would ident the lines for controls to emphasis their hierachies, but in wxPython the rules for idents don’t allow this.

My first impressions of Python are very favourable, especially no dollar-signs and no semicolons.

And thanks to all who helped.

Tim, Many thanks for taking the time and effort to go thru all my newbie problems. I have followed all your fixes and everything now works, apart from the frame positioning.
Yes, I am trying to avoid using classes. This goes back to PHP's horrible syntax for defining classes. It also gets rid of "self" all over the place, which I think is A Good Thing.

It is absolutely NOT a good thing, in either Python or PHP. Using classes and "self" gives you an automatic way to compartmentalize your data and hold state. It is a proven way to reduce bugs. Your scheme puts everything into global variables, which is terrible coding practice.

PHP's syntax for defining classes is not all that different from other languages. It is quite possible to write good, object-oriented code in PHP, it's just that almost no one does so. Essentially all of the PHP examples on the web suck.

It's a bit disappointing that Python cannot seem to cope with the event handler lines coming after app.Mainloop() line (button_clicked not defined), which is the logical place for them.. Is there a way round this?

What on earth makes you think that's logical? Python, like PHP and C, requires that a name be defined before it is used. If you were using classes, that organization would come automatically, because the class would all be defined before any of the class's code was executed. Where you are making everything a global, it dictates a very specific ordering for your code, because the code is interpreted linearly from top to bottom. app.Mainloop() does not return until the program exits. Thus, when your windows all come up, none of the code after that call will have been seen yet.

And if I can be frank, I don't think you are really in a position yet to say what is the "logical place" for things. You are trying to write Python as if it were PHP. That is always going to lead to tears, heartache, and bad designs. Seriously, you need to learn the Pythonic way of doing things. The standard practices are there because history has shown us what works.

In wxPHP I would ident the lines for controls to emphasis their hierachies, but in wxPython the rules for idents don't allow this.

Right. In Python, indentation is syntax. It is one of its most endearing features.

···

On Apr 13, 2019, at 10:14 PM, Dave Kimble <dave.kimble.2@gmail.com> wrote:

Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

I have discovered another aspect of the frame positioning problem.

When
the frame has the “style=~wx.CAPTION” option, and frame_pos = wx.Point(200,200) it does position correctly, but with the default style (with my setup) it doesn’t, it positions at wx.Point(x, 0) where x is the width of the taskbar , which is on the left margin).

test1.py (253 Bytes)

···

====

While it may true I am trying to write Python as if it were PHP, that is explained by me knowing PHP and not knowing Python. I started coding in 1967 and have experience of Fortran 4, Algol 68, COBOL, Pascal, Basic, PLAN, asm and others. You have decided Python does things the “right way” and won’t have it any other way. History has shown that new coding languages can go backwards in terms of neatness and intuitiveness. Indentation as syntax looks right, EXCEPT when you want to use indentation for other purposes, then it is impossible without using { }.

It is NOT true that PHP has to have its functions defined before use. Python could do it simply by doing a dual pass over the code.

Event handling occurs after “app.MainLoop()” is executed, so the logical place to put the code lines is after the “app.MainLoop()” line.

OOP imposes a nonsensical structure and line ordering on things which are logically top to bottom.

I am not going to get confused by this approach, although I can see that a room full of programmers all working on the same project might have a problem.

On Sunday, April 14, 2019 at 5:16:08 PM UTC+10, Tim Roberts wrote:

On Apr 13, 2019, at 10:14 PM, Dave Kimble dave....@gmail.com wrote:

Tim, Many thanks for taking the time and effort to go thru all my newbie problems. I have followed all your fixes and everything now works, apart from the frame positioning.

Yes, I am trying to avoid using classes. This goes back to PHP’s horrible syntax for defining classes. It also gets rid of “self” all over the place, which I think is A Good Thing.

It is absolutely NOT a good thing, in either Python or PHP. Using classes and “self” gives you an automatic way to compartmentalize your data and hold state. It is a proven way to reduce bugs. Your scheme puts everything into global variables, which is terrible coding practice.

PHP’s syntax for defining classes is not all that different from other languages. It is quite possible to write good, object-oriented code in PHP, it’s just that almost no one does so. Essentially all of the PHP examples on the web suck.

It’s a bit disappointing that Python cannot seem to cope with the event handler lines coming after app.Mainloop() line (button_clicked not defined), which is the logical place for them… Is there a way round this?

What on earth makes you think that’s logical? Python, like PHP and C, requires that a name be defined before it is used. If you were using classes, that organization would come automatically, because the class would all be defined before any of the class’s code was executed. Where you are making everything a global, it dictates a very specific ordering for your code, because the code is interpreted linearly from top to bottom. app.Mainloop() does not return until the program exits. Thus, when your windows all come up, none of the code after that call will have been seen yet.

And if I can be frank, I don’t think you are really in a position yet to say what is the “logical place” for things. You are trying to write Python as if it were PHP. That is always going to lead to tears, heartache, and bad designs. Seriously, you need to learn the Pythonic way of doing things. The standard practices are there because history has shown us what works.

In wxPHP I would ident the lines for controls to emphasis their hierachies, but in wxPython the rules for idents don’t allow this.

Right. In Python, indentation is syntax. It is one of its most endearing features.


Tim Roberts, ti...@probo.com

Providenza & Boekelheide, Inc.