DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

wxPython: Set Which Display the Frame Is on

Looking to target specific displays with your wxPython app? Then this is the post for you!

Mike Driscoll user avatar by
Mike Driscoll
·
Jan. 10, 19 · Tutorial
Like (2)
Save
Tweet
Share
4.15K Views

Join the DZone community and get the full member experience.

Join For Free

The other day, I saw an interesting question in the wxPython IRC channel. They were asking if there was a way to set which display their application would appear on. Robin Dunn, the creator of wxPython, gave the questioner some pointers, but I decided to go ahead and write up a quick tutorial on the topic.

The wxPython toolkit actually has all the bits and pieces you need for this sort of thing. The first step is getting the combined screen size. What I mean by this is asking wxPython what it thinks is the total size of the screen. This would be the total width and height of all your displays combined. You can get this by calling  wx.DisplaySize() , which returns a tuple. If you would like to get individual display resolutions, then you have to call  wx.Display  and pass in the index of the display. So if you have two displays, then the first display’s resolution could be acquired like this:

index = 0
display = wx.Display(index)
geo = display.GetGeometry()


Let’s write up a quick little application that has a single button that will just switch which display the application is on.

import wx

class MyPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.frame = parent

        mainsizer = wx.BoxSizer(wx.VERTICAL)
        sizer = wx.BoxSizer(wx.HORIZONTAL)

        btn = wx.Button(self, label='Switch Display')
        btn.Bind(wx.EVT_BUTTON, self.switch_displays)

        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
        mainsizer.AddStretchSpacer(prop=1)
        mainsizer.Add(sizer, 0, wx.ALL|wx.CENTER, 5)
        mainsizer.AddStretchSpacer(prop=1)
        self.SetSizer(mainsizer)

    def switch_displays(self, event):
        combined_screen_size = wx.DisplaySize()
        for index in range(wx.Display.GetCount()):
            display = wx.Display(index)
            geo = display.GetGeometry()
            print(geo)

        current_w, current_h = self.frame.GetPosition()

        screen_one = wx.Display(0)
        _, _, screen_one_w, screen_one_h = screen_one.GetGeometry()
        screen_two = wx.Display(1)
        _, _, screen_two_w, screen_two_h = screen_two.GetGeometry()

        if current_w > combined_screen_size[0] / 2:
            # probably on second screen
            self.frame.SetPosition((int(screen_one_w / 2),
                                   int(screen_one_h / 2)))
        else:
            self.frame.SetPosition((int(screen_one_w + (screen_two_w / 2)),
                                   int(screen_two_h / 2)))

class MainFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title='Display Change')
        panel = MyPanel(self)
        self.Show()

if __name__ == '__main__':
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()


Here we create two classes. The first contains almost all the code and defines the button and its event handler. The other class is for creating the frame itself. The event handler is where all the fun is though, so let’s look at that. For context, I happen to have two monitors of the same make, model, and orientation.

def switch_displays(self, event):
    combined_screen_size = wx.DisplaySize()
    for index in range(wx.Display.GetCount()):
        display = wx.Display(index)
        geo = display.GetGeometry()
        print(geo)

    x, y = self.frame.GetPosition()

    screen_one = wx.Display(0)
    _, _, screen_one_w, screen_one_h = screen_one.GetGeometry()
    screen_two = wx.Display(1)
    _, _, screen_two_w, screen_two_h = screen_two.GetGeometry()

    if x > combined_screen_size[0] / 2:
        # probably on second screen
        self.frame.SetPosition((int(screen_one_w / 2),
                                    int(screen_one_h / 2)))
    else:
        self.frame.SetPosition((int(screen_one_w + (screen_two_w / 2)),
                                    int(screen_two_h / 2)))

Here we pull out the total resolution of both monitors. Then for demonstration purposes, we loop over the displays and print out their geometries. You can comment those lines out as they don’t do anything other than help with debugging.

Then we get the frame’s current position by calling its GetPosition  method. Next we extract the two display’s resolutions via a call to each of the display object’s GetGeometry  method. Next, we check to see if the X coordinate for the frame is greater than the combined width of the displays divided by two. Since I know both of my monitors are the same resolution and orientation, I know this will work. Anyway, if it is greater, then we attempt to move the application to the opposite monitor by calling SetPosition .

Wrapping Up

You should give this code a try and see if it works on your multiple display setup. If it doesn’t, you may need to adjust the math a bit or try to figure out where your OS thinks your monitors are so you can fix the code accordingly.

Additional Reading

  • wxPython documentation page on wx.Display
Frame (networking)

Published at DZone with permission of Mike Driscoll, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Java Development Trends 2023
  • An Introduction to Data Mesh
  • How To Create and Edit Excel XLSX Documents in Java
  • Why It Is Important To Have an Ownership as a DevOps Engineer

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: