Skip to content

[PyQt5] Realize The Interface Of Rounded Border Window

I wonder if you are tired of the unchanging right-angle border window? At least, I'm sure I don't feel so interesting about the right-angled border interface. Look at the Android App icon and iOS borders. Are there any nice rounded borders?

In the framework of PyQt5, of course, we can also make the same nice rounded border. Let's look at a simple example code.


Use setStyleSheet() to adjust border

First at all, I have to clarify that I am not sure if there is a better way to implement it, so this method is just for reference.

# coding: utf-8
import sys
from PyQt5.Qt import Qt
from PyQt5.QtWidgets import *


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        # Window size
        self.WIDTH = 300
        self.HEIGHT = 300
        self.resize(self.WIDTH, self.HEIGHT)

        # Widget
        self.centralwidget = QWidget(self)
        self.centralwidget.resize(self.WIDTH, self.HEIGHT)

        # Initial
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setWindowOpacity(0.6)

        radius = 30
        self.centralwidget.setStyleSheet(
            """
            background:rgb(255, 255, 255);
            border-top-left-radius:{0}px;
            border-bottom-left-radius:{0}px;
            border-top-right-radius:{0}px;
            border-bottom-right-radius:{0}px;
            """.format(radius)
        )


if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())



Output:

The principle is very easy to know: I don't know how to change the real MainWindow element beautifully, so I created a Widget element that covers the MainWindow, and then hides the MainWindow, leaving only a simple Widget.

Then I use setStyleSheet() to add QSS, it can change radius parameter to adjust Widget style.

Why can not we change the MainWindow component directly? Let's run directly to change the status of MainWindow.

# coding: utf-8
import sys
from PyQt5.Qt import Qt
from PyQt5.QtWidgets import *


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        # Window size
        self.WIDTH = 300
        self.HEIGHT = 300
        self.resize(self.WIDTH, self.HEIGHT)

        # Initial
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setWindowOpacity(0.6)

        radius = 30
        self.setStyleSheet(
            """
            background:rgb(255, 255, 255);
            
            border-top:1px solid black;
            border-bottom:1px solid black;
            border-left:1px solid black;
            border-right:1px solid black;
             
            border-top-left-radius:{0}px;
            border-bottom-left-radius:{0}px;
            border-top-right-radius:{0}px;
            border-bottom-right-radius:{0}px;
            """.format(radius)
        )


if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())



Output:

It's not that it hasn't been changed (in order to better present the effect, I set the rounded corners to black), but we can find that the border still exists, but it looks a little ugly. As a last resort, I had to use the Widget component as an interface.

By the way, if you want a complete circle, you can set radius parameter to 150.

This is because my size is 300 x 300. For example, if your size is 600 x 600, you must adjust the radius parameter to 300 if you want to be round.


Drag interface

Presumably everyone who is used to writing PyQt5 should have noticed that for the sake of beauty, I have hidden the title field.

So, don't we have no way to drag the interface and close the program now?

May be you can refer two articles I wrote before.

The first article recorded how to drag the interface after hiding the title field.

The second article introduces how to set the right-click to open the menu. So that you can set the exit button

The complete code is as follows:

# coding: utf-8
import sys
from PyQt5.Qt import Qt
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QCursor


class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        # Window size
        self.WIDTH = 300
        self.HEIGHT = 300
        self.resize(self.WIDTH, self.HEIGHT)

        # Widget
        self.centralwidget = QWidget(self)
        self.centralwidget.resize(self.WIDTH, self.HEIGHT)

        # Menu
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.right_menu)

        # Initial
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setWindowOpacity(0.6)

        radius = 150
        self.centralwidget.setStyleSheet(
            """
            background:rgb(255, 255, 255);
            border-top-left-radius:{0}px;
            border-bottom-left-radius:{0}px;
            border-top-right-radius:{0}px;
            border-bottom-right-radius:{0}px;
            """.format(radius)
        )

    def right_menu(self, pos):
        menu = QMenu()

        # Add menu options
        exit_option = menu.addAction('Exit')

        # Menu option events
        exit_option.triggered.connect(lambda: exit())

        # Position
        menu.exec_(self.mapToGlobal(pos))

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.moveFlag = True
            self.movePosition = event.globalPos() - self.pos()
            self.setCursor(QCursor(Qt.OpenHandCursor))
            event.accept()

    def mouseMoveEvent(self, event):
        if Qt.LeftButton and self.moveFlag:
            self.move(event.globalPos() - self.movePosition)
            event.accept()

    def mouseReleaseEvent(self, QMouseEvent):
        self.moveFlag = False
        self.setCursor(Qt.CrossCursor)


if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())



Output:


References

Leave a Reply