Python Forum
Place QT Window in the middle
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Place QT Window in the middle
#1
Hello,

I'm working on a Python Tool with Qt6 (I have created the UI with QT Designer) but I'm running into a few problems...
This is my code so far:

#!/usr/bin/env Python3

# Imports
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.uic import loadUi
from PyQt6.QtCore import Qt
import ctypes
import json
import sys

# Main Function
def main()
    window()

# Window Function
def window()
    # Load Config Information from JSON
    with open ('config/config.json', 'r') as fp
        data = json.load(fp)

    # Create Variables from JSON
    for i in data
        for j in data[i]
            for k, l in zip(j.keys(), j.values())
                globals()[k] = l

    # Create Application and Window
    app = QApplication(sys.argv)
    window = QMainWindow()
    loadUi(config/MainWindow.ui, window)

    # Get DPI Scale
    user32 = ctypes.windll.user32
    user32.SetProcessDPIAware()
    dpi = user32.GetDpiForSystem()
    scale_factor = dpi  96

    # Get Screen Size
    screen = app.primaryScreen()
    size = screen.size()
    screenWidth = round(size.width() * scale_factor)
    screenHeight = round(size.height() * scale_factor)

    # Set Static Size and Disbale Menu Bar
    window.setGeometry((screenWidth - window.width() // 2, (screenHeight - window.height() // 2, int(screenWidth // float(Size)), int(screenHeight // float(Size)))
    window.setWindowFlags(Qt.WindowType.FramelessWindowHint)
    window.show()

    # Start Close Button
    window.closeButton.clicked.connect(app.quit)
    window.resizeButton.clicked.connect(lambda window.resize(750, 100))

    # Start the Application Loop
    sys.exit(app.exec())

# Start Main Function
main()

#End
sys.exit()
I'm trying to place the Window in the middle of the screen I'm starting it (not on my primary monitor). For explanation, I used the scale_factor because the window.height and width does not give the right screen size (2560 instead of 3840)... Every time I start the tool the window is not in the middle of the monitor.
I tried to this in Lazarus once and it worked really fast but here I'm having problems... Can someone help me?
Reply
#2
That's not the way to use Qt or any other python code.
Colons are missing everywhere in the code.
Reply
#3
(Jul-16-2023, 12:49 PM)Axel_Erfurt Wrote: That's not the way to use Qt or any other python code.
Colons are missing everywhere in the code.

What do you mean exactly by "not the way to use Qt" ?
Reply
#4
with open ('config/config.json', 'r') as fp

should be

with open ('config/config.json', 'r') as fp:


for i in data

should be

for i in data:

...
Reply
#5
(Jul-16-2023, 01:13 PM)Axel_Erfurt Wrote: with open ('config/config.json', 'r') as fp

should be

with open ('config/config.json', 'r') as fp:


for i in data

should be

for i in data:

...

It seems that there has been an coding-error. In my code there are all the correct syntaxes.. Here is the correct core without the missiing characters:

#!/usr/bin/env Python3

# Imports
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.uic import loadUi
from PyQt6.QtCore import Qt
import ctypes
import json
import sys

# Main Function
def main():
    window()

# Window Function
def window():
    # Load Config Information from JSON
    with open ('config/config.json', 'r') as fp:
        data = json.load(fp)

    # Create Variables from JSON
    for i in data:
        for j in data[i]:
            for k, l in zip(j.keys(), j.values()):
                globals()[k] = l

    # Create Application and Window
    app = QApplication(sys.argv)
    window = QMainWindow()
    loadUi("config/MainWindow.ui", window)

    # Get DPI Scale
    user32 = ctypes.windll.user32
    user32.SetProcessDPIAware()
    dpi = user32.GetDpiForSystem()
    scale_factor = dpi / 96

    # Get Screen Size
    screen = app.primaryScreen()
    size = screen.size()
    screenWidth = round(size.width() * scale_factor)
    screenHeight = round(size.height() * scale_factor)

    # Set Static Size and Disbale Menu Bar
    window.setGeometry((screenWidth - window.width()) // 2, (screenHeight - window.height()) // 2, int(screenWidth // float(Size)), int(screenHeight // float(Size)))
    window.setWindowFlags(Qt.WindowType.FramelessWindowHint)
    window.show()

    # Start Close Button
    window.closeButton.clicked.connect(app.quit)
    window.resizeButton.clicked.connect(lambda: window.resize(750, 100))

    # Start the Application Loop
    sys.exit(app.exec())

# Start Main Function
main()

#End
sys.exit()
So is there another error in the way I use QT? Other than missing characters?
Reply
#6
Your last lines are:

main() 
sys.exit() 
First you create the window and then exit the program?

You'll learn more if you don't use the Qt Designer.

That's how I would create a simple window centered.

from PyQt6.QtWidgets import (QMainWindow, QApplication, 
                                                QVBoxLayout, QWidget)

class MainWindow(QMainWindow):
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)
        self.setupUI()
        
    def setupUI(self):
        self.setWindowTitle("Main Window")
        self.resize(800, 600)
        central_widget = QWidget()
        vbox = QVBoxLayout()
        central_widget.setLayout(vbox)
        self.setCentralWidget(central_widget)
        
        qt_rectangle = self.frameGeometry()
        center_point = QApplication.primaryScreen().geometry().center()
        print(center_point)
        qt_rectangle.moveCenter(center_point)
        self.move(qt_rectangle.topLeft())

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()

    sys.exit(app.exec())
Reply
#7
If you want to center it on the 2nd monitor

center_point = QApplication.screens()[1].geometry().center()
Reply
#8
Okay understood. Is there any possibility to set an initial position and size of my window and my Elements such as Buttons and Combobox which change proportionally when using a QVBoxLayout?
Reply
#9
Something like that?

from PyQt6.QtWidgets import (QMainWindow, QApplication, QPushButton, QMessageBox, 
                                                QVBoxLayout, QHBoxLayout, QWidget, QTextEdit)
 
class MainWindow(QMainWindow):
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)
        self.setupUI()
         
    def setupUI(self):
        self.setWindowTitle("Main Window")
        self.setGeometry(50, 50, 800, 600) # initial position and size (left, top, width, height)
        central_widget = QWidget()
        vbox = QVBoxLayout()
        
        button_box = QHBoxLayout()
        button_quit = QPushButton("Exit")
        button_quit.clicked.connect(self.handle_quit)
        
        button_resize = QPushButton("Resize")
        button_resize.clicked.connect(self.handle_resize)
        
        button_center = QPushButton("Center")
        button_center.clicked.connect(self.center_window)
        
        button_msg = QPushButton("Message")
        button_msg.clicked.connect(self.show_msg)
        
        button_box.addWidget(button_quit)
        button_box.addWidget(button_resize)
        button_box.addWidget(button_center)
        button_box.addWidget(button_msg)

        button_box.addStretch() # add stretch after the buttons to prevent the buttons from stretching.
                
        vbox.addLayout(button_box)

        editor = QTextEdit(plainText = "Hello World") 
        vbox.addWidget(editor)
        
        central_widget.setLayout(vbox)
        self.setCentralWidget(central_widget)
        self.statusBar().showMessage("Ready", 0)
        
    def show_msg(self):
        message = "This is a message"
        dlg = QMessageBox(self)
        dlg.setWindowTitle("Information")
        dlg.setText(message)
        button = dlg.exec()

        if button == QMessageBox.StandardButton.Ok:
            print("MessageBox closed")
            self.statusBar().showMessage("MessageBox closed", 0)
      

    def center_window(self):
        qt_rectangle = self.frameGeometry()
        center_point = QApplication.primaryScreen().geometry().center()
        qt_rectangle.moveCenter(center_point)
        self.move(qt_rectangle.topLeft())
        self.statusBar().showMessage("centered", 0)

    def handle_resize(self):
        self.resize(500, 300)
        self.statusBar().showMessage("resized", 0)
        
    def handle_quit(self):
        self.close()
 
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
 
    sys.exit(app.exec())
or use a toolbar for buttons

from PyQt6.QtWidgets import (QMainWindow, QApplication, QPushButton, QMessageBox, 
                                                QVBoxLayout, QHBoxLayout, QWidget, QTextEdit)
 
class MainWindow(QMainWindow):
    def __init__(self, parent = None):
        super(MainWindow, self).__init__(parent)
        self.setupUI()
         
    def setupUI(self):
        self.setWindowTitle("Main Window")
        self.setGeometry(50, 50, 800, 600) # initial position and size (left, top, width, height)
        central_widget = QWidget()
        vbox = QVBoxLayout()
        
        tbar = self.addToolBar("toolbar")
        tbar.layout().setSpacing(8)
        
        button_quit = QPushButton("Exit")
        button_quit.clicked.connect(self.handle_quit)
        
        button_resize = QPushButton("Resize")
        button_resize.clicked.connect(self.handle_resize)
        
        button_center = QPushButton("Center")
        button_center.clicked.connect(self.center_window)
        
        button_msg = QPushButton("Message")
        button_msg.clicked.connect(self.show_msg)
        
        tbar.addWidget(button_quit)
        tbar.addWidget(button_resize)
        tbar.addWidget(button_center)
        tbar.addWidget(button_msg)
                
        editor = QTextEdit(plainText = "Hello World") 
        vbox.addWidget(editor)
        
        central_widget.setLayout(vbox)
        self.setCentralWidget(central_widget)
        self.statusBar().showMessage("Ready", 0)
        
    def show_msg(self):
        message = "This is a message"
        dlg = QMessageBox(self)
        dlg.setWindowTitle("Information")
        dlg.setText(message)
        button = dlg.exec()

        if button == QMessageBox.StandardButton.Ok:
            print("MessageBox closed")
            self.statusBar().showMessage("MessageBox closed", 0)
      

    def center_window(self):
        qt_rectangle = self.frameGeometry()
        center_point = QApplication.primaryScreen().geometry().center()
        qt_rectangle.moveCenter(center_point)
        self.move(qt_rectangle.topLeft())
        self.statusBar().showMessage("centered", 0)

    def handle_resize(self):
        self.resize(500, 300)
        self.statusBar().showMessage("resized", 0)
        
    def handle_quit(self):
        self.close()
 
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
 
    sys.exit(app.exec())
Reply
#10
It seems like there are a few issues in your code that might be causing the window positioning problem.

DPI Scaling: Instead of manually calculating the DPI scaling, you can use Qt's QApplication method desktop().screenGeometry() to get the screen's geometry, including the DPI scaling factor.

Window Positioning: To center the window on the screen, you can use QDesktopWidget and move() methods.

Size Calculation: There seems to be a syntax error in calculating the window size. You can directly set the window size using resize().

Here i have done some updations in your code :-

#!/usr/bin/env python3

from PyQt6.QtWidgets import QApplication, QMainWindow, QDesktopWidget
from PyQt6.uic import loadUi
import json
import sys

def main():
    app = QApplication(sys.argv)
    window = QMainWindow()
    loadUi('config/MainWindow.ui', window)

    # Load Config Information from JSON
    with open('config/config.json', 'r') as fp:
        data = json.load(fp)

    # Create Variables from JSON (optional, only if needed in other parts of the code)
    for i in data:
        for j in data[i]:
            for k, l in zip(j.keys(), j.values()):
                globals()[k] = l

    # Get Screen Size
    desktop = QDesktopWidget()
    screen_rect = desktop.screenGeometry(window)
    screenWidth = screen_rect.width()
    screenHeight = screen_rect.height()

    # Set Window Size and Position
    window_width = 750
    window_height = 100
    window.setGeometry(
        (screenWidth - window_width) // 2,
        (screenHeight - window_height) // 2,
        window_width,
        window_height
    )

    # Hide Menu Bar
    window.setWindowFlag(Qt.WindowType.FramelessWindowHint)

    # Start Close Button
    window.closeButton.clicked.connect(app.quit)
    window.resizeButton.clicked.connect(lambda: window.resize(750, 100))  # Fixed a syntax error here

    # Show the Window
    window.show()

    # Start the Application Loop
    sys.exit(app.exec())

# Start Main Function
if __name__ == "__main__":
    main()
In this code, we use QDesktopWidget() to get the desktop widget, which helps in positioning the window on the center of the screen. The window's size and position are then set using the setGeometry() method. Also, make sure to use if __name__ == "__main__": to ensure that the main() function is only executed when the script is run directly, not when it is imported as a module.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Interaction between Matplotlib window, Python prompt and TKinter window NorbertMoussy 3 538 Mar-17-2024, 09:37 AM
Last Post: deanhystad
  Label.Place did not work? ATARI_LIVE 15 5,336 Sep-18-2020, 04:22 PM
Last Post: ATARI_LIVE
  [Tkinter] How to place scroll bar correctly scratchmyhead 1 3,967 May-18-2020, 04:17 PM
Last Post: scratchmyhead
  How to use place holders in tkinter sqlite scratchmyhead 1 1,837 May-12-2020, 06:13 PM
Last Post: Larz60+
  tkinter window and turtle window error 1885 3 6,750 Nov-02-2019, 12:18 PM
Last Post: 1885
  thinker button gui place next to each other jacklee26 9 4,795 Jul-04-2019, 07:48 AM
Last Post: wuf
  update a variable in parent window after closing its toplevel window gray 5 9,118 Mar-20-2017, 10:35 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020