PyQt Center on Screen

wxPython has been annoying me with the inconsistent behavior of its splitter window. Perhaps I’m doing something wrong, but the framework in general isn’t exactly fun to develop in. I’ve since discovered PyQt and while it’s not exactly Pythonic, it seems to make more sense. However, if you’re moving from wxPython to PyQt, you might be aware that there’s no obvious method of centering the main window on the screen. I’ve seen at least one method so far (to which I replied as my alter ego, Zancarius), but it doesn’t take into account something fairly minor but of some significance:

Windows have borders around them in most desktop environments!

Window borders can range from fairly minor (4 pixels around each side adding a total of 8 pixels horizontally and vertically) to imposing (16 pixels or more). Unfortunately, QWidget.geometry() and friends only return a QSize object describing the geometry of the contained window rather than the containing window. It seems insignificant, sure, but if you want pixel-perfect alignment, you have to use something else:

QWidget.frameSize()

frameSize() will return the size of the entire window, border included. Here’s a method you can include in your own classes as in this example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ExampleWindow (QtGui.QMainWindow):
    def __init__ (self, parent=None):
        '''constructor'''
        QtGui.QMainWindow.__init__(self, parent)
        self.setGeometry(0, 0, 650, 550)
        self.setWindowTitle("My Example Application")
        self.centerOnScreen()
 
    def centerOnScreen (self):
        '''centerOnScreen()
Centers the window on the screen.'''
        resolution = QtGui.QDesktopWidget().screenGeometry()
        self.move((resolution.width() / 2) - (self.frameSize().width() / 2),
                  (resolution.height() / 2) - (self.frameSize().height() / 2))

centerOnScreen() works by taking the desktop’s current resolution and dividing it by 2 to get half of the viewport. Next, it takes half of the window size (including the border) and subtracts that from the viewport half. This provides an origin for the upper-left corner of the window to be located such that the window itself is fully “centered.”

Simple, huh?

***

Leave a comment

Valid tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>