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.
- [PyQt5] Hide the title bar and use mouse to move the interface
- [PyQt5] How to allow users to right-click to open a menu option
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: