# pyqt-frameless-window
PyQt(+PySide) Frameless Window
## Feature
* Frameless
* Using Windows API (for Windows OS effect - shadow, rounded, animation, etc.)
* Supports PyQt5, PySide2, PySide6
* User can make it enable/disable to move, resize
* Supports QWidget, QDialog, QMainWindow
* Support title bar. You can decide either show or hide it.
## Note
I have no macOS and Linux to test so i couldn't manage to support them as well.
Maybe i can use the virtual machine or something to do it.
I <b>strongly recommend</b> legacy version if your OS is not Windows and that's saying a lot.
## Requirements
* PyQt5 - Use QtWinExtras to use Windows API feature in Qt (Qt6 doesn't support QtWinExtras anymore, sadly)
* qtpy - To use PyQt5, PySide2(Qt version 5), PySide6(Qt version 6)
* pywin32 - For using Windows API feature
## Setup
### New version (using Windows API)
`python -m pip install pyqt-frameless-window`
<b>(For new version) Recommend to clone rather than installing with pip. Still working!</b>
### Legacy version
`python -m pip install pyqt-frameless-window==0.0.61`
## Class Overview
### Recommend to use `FramelessWidget`, the others have multiple inheritance, so it can cause unexpected problem (haven't found any so far, though)
* FramelessWidget(hint=None) - frameless QWidget
* FramelessDialog(hint=None) - frameless QDialog
* FramelessMainWindow(hint=None) - frameless QMainWindow
### About `hint`
You can give the list of buttons on the right top of the menu bar with `hint` like <b>['full_screen', 'min', 'max', 'close']</b>.
<b>['min', 'max', 'close']</b> will set by default if you don't give any arguments.
Available arguments (v0.0.78)
* full_screen (still buggy, for example you can resize the full-screen window if you put the cusror to the very edge of the window)
* min
* max
* close
You can set the list of them with `setTitleBarHint(hint: list)` as well. (v0.0.82)
## Method Overview
### == FramelessWidget, FramelessDialog, FramelessMainWindow ==
#### For Windows & The Others
* `setResizable(f: bool)` - Set resizable/none-resizable.
* `isResizable() -> bool` - Check if window is resizable or not
* `setPressToMove(f: bool)` - Set movable/non-movable
* `isPressToMove() -> bool` - Check if window is movable or not
* ##### New Version Only
* `setWindowIcon(filename: str)` - Set the icon to the title bar. This method is overriden.
* `setWindowTitle(title: str)` - Set the title to the title bar. This method is overriden.
* `setFixedSize(width, height)` - Set the fixed width and height. This method is overriden to call `setResizable(false)`.
* `setTitleBarVisible(f: bool)` - Set the title bar's visibility. If window is movable, window moving policy will also be decided by this.
* If you set this <b>true</b> and window is <b>movable</b>, you should click and drag only the title bar to move the window.
* If you set this <b>false</b> and window is <b>movable</b>, you can click and drag the part of the window which is not occupied by widget to move the window.
* `getTitleBar()` - Get the title bar.
* `setTitleBarHint(hint: list)` - Set the standard buttons(min, max, close...) of corner widget.
#### The Others
* `setMargin(margin: int)` - Set the margin which allows cursor to change its shape to resize form
* `setFrameColor(color)` - Set the background color. color argument type can be both QColor and str.
* `getFrameColor` -> QColor - Get the background color.
* `setVerticalExpandedEnabled(f: bool)` - Make it able to expand vertically when double-clicking the top or bottom edges of the window.
### == TitleBar (New Version Only) ==
* `getIcon() -> QLabel` - Get the icon.
* `getTitle() -> QLabel` - Get the title.
* `setTitleBarFont(font: QFont)` - Set the font of the title bar.
* `setIconSize(w, h)` - Set the size of icon on the title bar.
Note: Do not use any functions other than the above.
## Example
### Note: This example is for Windows only.
### PyQt5 Code Sample
#### FramelessDialog
```python
import sys
# IMPORTANT!!!!!!!!!
# to prevent the "QWidget: Must construct a QApplication before a QWidget" error, you should put the code below
from PyQt5.QtCore import Qt
from pyqt_frameless_window import FramelessDialog
from PyQt5.QtWidgets import QApplication, QTextEdit
class Window(FramelessDialog):
def __init__(self):
super().__init__()
self.__initUi()
def __initUi(self):
self.setWindowTitle('Winter Is Coming')
self.setWindowIcon('./Stark-icon.png')
# if you want to customize the title bar
# titleBar = self.getTitleBar()
# titleBar.setTitleBarFont(QFont('Arial', 24))
# titleBar.setIconSize(32, 32)
lay = self.layout()
lay.addWidget(QTextEdit())
self.setLayout(lay)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
```
#### FramelessWidget
FramelessWidget code sample will be identical with FramelessDialog except for its name.
#### FramelessMainWindow
```python
import sys
# IMPORTANT!!!!!!!!!
# to prevent the "QWidget: Must construct a QApplication before a QWidget" error, you should put the code below
from PyQt5.QtCore import Qt
from pyqt_frameless_window import FramelessMainWindow
from PyQt5.QtWidgets import QApplication, QTextEdit
class Window(FramelessMainWindow):
def __init__(self):
super().__init__()
self.__initUi()
def __initUi(self):
self.setWindowTitle('Winter Is Coming')
self.setWindowIcon('./Stark-icon.png')
# if you want to customize the title bar
# titleBar = self.getTitleBar()
# titleBar.setTitleBarFont(QFont('Arial', 24))
# titleBar.setIconSize(32, 32)
mainWidget = self.centralWidget()
lay = mainWidget.layout()
lay.addWidget(QTextEdit())
mainWidget.setLayout(lay)
self.setCentralWidget(mainWidget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
```
### PySide6 Code Sample
#### FramelessDialog
```python
import sys
# IMPORTANT!!!!!!!!!
# to prevent the "QWidget: Must construct a QApplication before a QWidget" error, you should put the code below
from PySide6.QtCore import Qt
from pyqt_frameless_window import FramelessDialog
from PySide6.QtWidgets import QApplication, QTextEdit
class Window(FramelessDialog):
def __init__(self):
super().__init__()
self.__initUi()
def __initUi(self):
self.setWindowTitle('Winter Is Coming')
self.setWindowIcon('./Stark-icon.png')
# if you want to customize the title bar
# titleBar = self.getTitleBar()
# titleBar.setTitleBarFont(QFont('Arial', 24))
# titleBar.setIconSize(32, 32)
lay = self.layout()
lay.addWidget(QTextEdit())
self.setLayout(lay)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
```
#### FramelessMainWindow
```python
import sys
# IMPORTANT!!!!!!!!!
# to prevent the "QWidget: Must construct a QApplication before a QWidget" error, you should put the code below
from PySide6.QtCore import Qt
from pyqt_frameless_window import FramelessMainWindow
from PySide6.QtWidgets import QApplication, QTextEdit
class Window(FramelessMainWindow):
def __init__(self):
super().__init__()
self.__initUi()
def __initUi(self):
self.setWindowTitle('Winter Is Coming')
self.setWindowIcon('./Stark-icon.png')
# if you want to customize the title bar
# titleBar = self.getTitleBar()
# titleBar.setTitleBarFont(QFont('Arial', 24))
# titleBar.setIconSize(32, 32)
mainWidget = self.centralWidget()
lay = mainWidget.layout()
lay.addWidget(QTextEdit())
mainWidget.setLayout(lay)
self.setCentralWidget(mainWidget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec())
```
### Result
#### Title bar

#### No title bar
If you make the title bar not visible with `setTitleBarVisible(False)`

Try to move and resize it.
Note: Result image was tested in Windows 11, PySide6.
## See Also
<a href="https://github.com/yjg30737/pyqt-frameless-window/tree/b84dd1ba421aa7f3f940229ce6379611380f5e35">Legacy version(0.0.61) README</a> - not using Windows API, qtpy, just good old PyQt5. Enable to resize and move as always. (clunky in Windows though) Only for PyQt5 by the way.
Don't use multiple inheritance!!
## TODO list
* Make QWebEngineView work in win32 app (Windows 10) - QDockWidget, QMdiSubWindow
* Switching the customized title bar's theme only
Raw data
{
"_id": null,
"home_page": "https://github.com/yjg30737/pyqt-frameless-window.git",
"name": "pyqt-frameless-window",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "",
"author": "Jung Gyu Yoon",
"author_email": "yjg30737@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/36/a4/3f09bd3d2e771d51ec906c8cd1e3c6befe43f2a1b26792d886c3efa7b032/pyqt-frameless-window-0.0.85.tar.gz",
"platform": null,
"description": "\r\n# pyqt-frameless-window\r\n\r\nPyQt(+PySide) Frameless Window\r\n\r\n\r\n\r\n## Feature\r\n\r\n* Frameless\r\n\r\n* Using Windows API (for Windows OS effect - shadow, rounded, animation, etc.) \r\n\r\n* Supports PyQt5, PySide2, PySide6\r\n\r\n* User can make it enable/disable to move, resize\r\n\r\n* Supports QWidget, QDialog, QMainWindow\r\n\r\n* Support title bar. You can decide either show or hide it.\r\n\r\n\r\n\r\n## Note\r\n\r\nI have no macOS and Linux to test so i couldn't manage to support them as well.\r\n\r\n\r\n\r\nMaybe i can use the virtual machine or something to do it.\r\n\r\n\r\n\r\nI <b>strongly recommend</b> legacy version if your OS is not Windows and that's saying a lot.\r\n\r\n\r\n\r\n## Requirements\r\n\r\n* PyQt5 - Use QtWinExtras to use Windows API feature in Qt (Qt6 doesn't support QtWinExtras anymore, sadly) \r\n\r\n* qtpy - To use PyQt5, PySide2(Qt version 5), PySide6(Qt version 6)\r\n\r\n* pywin32 - For using Windows API feature\r\n\r\n\r\n\r\n## Setup\r\n\r\n\r\n\r\n### New version (using Windows API)\r\n\r\n\r\n\r\n`python -m pip install pyqt-frameless-window`\r\n\r\n\r\n\r\n<b>(For new version) Recommend to clone rather than installing with pip. Still working!</b>\r\n\r\n\r\n\r\n### Legacy version\r\n\r\n\r\n\r\n`python -m pip install pyqt-frameless-window==0.0.61`\r\n\r\n\r\n\r\n## Class Overview\r\n\r\n### Recommend to use `FramelessWidget`, the others have multiple inheritance, so it can cause unexpected problem (haven't found any so far, though)\r\n\r\n* FramelessWidget(hint=None) - frameless QWidget\r\n\r\n* FramelessDialog(hint=None) - frameless QDialog\r\n\r\n* FramelessMainWindow(hint=None) - frameless QMainWindow\r\n\r\n\r\n\r\n### About `hint`\r\n\r\nYou can give the list of buttons on the right top of the menu bar with `hint` like <b>['full_screen', 'min', 'max', 'close']</b>. \r\n\r\n\r\n\r\n<b>['min', 'max', 'close']</b> will set by default if you don't give any arguments.\r\n\r\n\r\n\r\nAvailable arguments (v0.0.78)\r\n\r\n* full_screen (still buggy, for example you can resize the full-screen window if you put the cusror to the very edge of the window)\r\n\r\n* min\r\n\r\n* max\r\n\r\n* close\r\n\r\n\r\n\r\nYou can set the list of them with `setTitleBarHint(hint: list)` as well. (v0.0.82)\r\n\r\n\r\n\r\n## Method Overview\r\n\r\n### == FramelessWidget, FramelessDialog, FramelessMainWindow ==\r\n\r\n#### For Windows & The Others\r\n\r\n* `setResizable(f: bool)` - Set resizable/none-resizable.\r\n\r\n* `isResizable() -> bool` - Check if window is resizable or not\r\n\r\n* `setPressToMove(f: bool)` - Set movable/non-movable\r\n\r\n* `isPressToMove() -> bool` - Check if window is movable or not\r\n\r\n* ##### New Version Only\r\n\r\n * `setWindowIcon(filename: str)` - Set the icon to the title bar. This method is overriden.\r\n\r\n * `setWindowTitle(title: str)` - Set the title to the title bar. This method is overriden.\r\n\r\n * `setFixedSize(width, height)` - Set the fixed width and height. This method is overriden to call `setResizable(false)`.\r\n\r\n * `setTitleBarVisible(f: bool)` - Set the title bar's visibility. If window is movable, window moving policy will also be decided by this.\r\n\r\n * If you set this <b>true</b> and window is <b>movable</b>, you should click and drag only the title bar to move the window.\r\n\r\n * If you set this <b>false</b> and window is <b>movable</b>, you can click and drag the part of the window which is not occupied by widget to move the window.\r\n\r\n * `getTitleBar()` - Get the title bar.\r\n\r\n * `setTitleBarHint(hint: list)` - Set the standard buttons(min, max, close...) of corner widget.\r\n\r\n#### The Others\r\n\r\n* `setMargin(margin: int)` - Set the margin which allows cursor to change its shape to resize form\r\n\r\n* `setFrameColor(color)` - Set the background color. color argument type can be both QColor and str.\r\n\r\n* `getFrameColor` -> QColor - Get the background color.\r\n\r\n* `setVerticalExpandedEnabled(f: bool)` - Make it able to expand vertically when double-clicking the top or bottom edges of the window.\r\n\r\n### == TitleBar (New Version Only) ==\r\n\r\n* `getIcon() -> QLabel` - Get the icon.\r\n\r\n* `getTitle() -> QLabel` - Get the title.\r\n\r\n* `setTitleBarFont(font: QFont)` - Set the font of the title bar.\r\n\r\n* `setIconSize(w, h)` - Set the size of icon on the title bar.\r\n\r\n\r\n\r\nNote: Do not use any functions other than the above.\r\n\r\n\r\n\r\n## Example\r\n\r\n### Note: This example is for Windows only.\r\n\r\n### PyQt5 Code Sample\r\n\r\n#### FramelessDialog\r\n\r\n```python\r\n\r\nimport sys\r\n\r\n\r\n\r\n# IMPORTANT!!!!!!!!!\r\n\r\n# to prevent the \"QWidget: Must construct a QApplication before a QWidget\" error, you should put the code below\r\n\r\nfrom PyQt5.QtCore import Qt\r\n\r\n\r\n\r\nfrom pyqt_frameless_window import FramelessDialog\r\n\r\nfrom PyQt5.QtWidgets import QApplication, QTextEdit\r\n\r\n\r\n\r\n\r\n\r\nclass Window(FramelessDialog):\r\n\r\n def __init__(self):\r\n\r\n super().__init__()\r\n\r\n self.__initUi()\r\n\r\n\r\n\r\n def __initUi(self):\r\n\r\n self.setWindowTitle('Winter Is Coming')\r\n\r\n self.setWindowIcon('./Stark-icon.png')\r\n\r\n\r\n\r\n # if you want to customize the title bar\r\n\r\n # titleBar = self.getTitleBar()\r\n\r\n # titleBar.setTitleBarFont(QFont('Arial', 24))\r\n\r\n # titleBar.setIconSize(32, 32)\r\n\r\n\r\n\r\n lay = self.layout()\r\n\r\n lay.addWidget(QTextEdit())\r\n\r\n self.setLayout(lay)\r\n\r\n\r\n\r\n\r\n\r\nif __name__ == \"__main__\":\r\n\r\n app = QApplication(sys.argv)\r\n\r\n window = Window()\r\n\r\n window.show()\r\n\r\n sys.exit(app.exec())\r\n\r\n```\r\n\r\n\r\n\r\n#### FramelessWidget\r\n\r\nFramelessWidget code sample will be identical with FramelessDialog except for its name.\r\n\r\n\r\n\r\n#### FramelessMainWindow\r\n\r\n```python\r\n\r\nimport sys\r\n\r\n\r\n\r\n# IMPORTANT!!!!!!!!!\r\n\r\n# to prevent the \"QWidget: Must construct a QApplication before a QWidget\" error, you should put the code below\r\n\r\nfrom PyQt5.QtCore import Qt\r\n\r\n\r\n\r\nfrom pyqt_frameless_window import FramelessMainWindow\r\n\r\nfrom PyQt5.QtWidgets import QApplication, QTextEdit\r\n\r\n\r\n\r\n\r\n\r\nclass Window(FramelessMainWindow):\r\n\r\n def __init__(self):\r\n\r\n super().__init__()\r\n\r\n self.__initUi()\r\n\r\n\r\n\r\n def __initUi(self):\r\n\r\n self.setWindowTitle('Winter Is Coming')\r\n\r\n self.setWindowIcon('./Stark-icon.png')\r\n\r\n \r\n\r\n # if you want to customize the title bar\r\n\r\n # titleBar = self.getTitleBar()\r\n\r\n # titleBar.setTitleBarFont(QFont('Arial', 24))\r\n\r\n # titleBar.setIconSize(32, 32)\r\n\r\n \r\n\r\n mainWidget = self.centralWidget()\r\n\r\n lay = mainWidget.layout()\r\n\r\n lay.addWidget(QTextEdit())\r\n\r\n mainWidget.setLayout(lay)\r\n\r\n self.setCentralWidget(mainWidget)\r\n\r\n\r\n\r\n\r\n\r\nif __name__ == \"__main__\":\r\n\r\n app = QApplication(sys.argv)\r\n\r\n window = Window()\r\n\r\n window.show()\r\n\r\n sys.exit(app.exec())\r\n\r\n```\r\n\r\n\r\n\r\n### PySide6 Code Sample\r\n\r\n#### FramelessDialog\r\n\r\n```python\r\n\r\nimport sys\r\n\r\n\r\n\r\n# IMPORTANT!!!!!!!!!\r\n\r\n# to prevent the \"QWidget: Must construct a QApplication before a QWidget\" error, you should put the code below\r\n\r\nfrom PySide6.QtCore import Qt\r\n\r\n\r\n\r\nfrom pyqt_frameless_window import FramelessDialog\r\n\r\nfrom PySide6.QtWidgets import QApplication, QTextEdit\r\n\r\n\r\n\r\n\r\n\r\nclass Window(FramelessDialog):\r\n\r\n def __init__(self):\r\n\r\n super().__init__()\r\n\r\n self.__initUi()\r\n\r\n\r\n\r\n def __initUi(self):\r\n\r\n self.setWindowTitle('Winter Is Coming')\r\n\r\n self.setWindowIcon('./Stark-icon.png')\r\n\r\n \r\n\r\n # if you want to customize the title bar\r\n\r\n # titleBar = self.getTitleBar()\r\n\r\n # titleBar.setTitleBarFont(QFont('Arial', 24))\r\n\r\n # titleBar.setIconSize(32, 32)\r\n\r\n \r\n\r\n lay = self.layout()\r\n\r\n lay.addWidget(QTextEdit())\r\n\r\n self.setLayout(lay)\r\n\r\n\r\n\r\n\r\n\r\nif __name__ == \"__main__\":\r\n\r\n app = QApplication(sys.argv)\r\n\r\n window = Window()\r\n\r\n window.show()\r\n\r\n sys.exit(app.exec())\r\n\r\n```\r\n\r\n\r\n\r\n#### FramelessMainWindow\r\n\r\n```python\r\n\r\nimport sys\r\n\r\n\r\n\r\n# IMPORTANT!!!!!!!!!\r\n\r\n# to prevent the \"QWidget: Must construct a QApplication before a QWidget\" error, you should put the code below\r\n\r\nfrom PySide6.QtCore import Qt\r\n\r\n\r\n\r\nfrom pyqt_frameless_window import FramelessMainWindow\r\n\r\nfrom PySide6.QtWidgets import QApplication, QTextEdit\r\n\r\n\r\n\r\n\r\n\r\nclass Window(FramelessMainWindow):\r\n\r\n def __init__(self):\r\n\r\n super().__init__()\r\n\r\n self.__initUi()\r\n\r\n\r\n\r\n def __initUi(self):\r\n\r\n self.setWindowTitle('Winter Is Coming')\r\n\r\n self.setWindowIcon('./Stark-icon.png')\r\n\r\n \r\n\r\n # if you want to customize the title bar\r\n\r\n # titleBar = self.getTitleBar()\r\n\r\n # titleBar.setTitleBarFont(QFont('Arial', 24))\r\n\r\n # titleBar.setIconSize(32, 32)\r\n\r\n \r\n\r\n mainWidget = self.centralWidget()\r\n\r\n lay = mainWidget.layout()\r\n\r\n lay.addWidget(QTextEdit())\r\n\r\n mainWidget.setLayout(lay)\r\n\r\n self.setCentralWidget(mainWidget)\r\n\r\n\r\n\r\n\r\n\r\nif __name__ == \"__main__\":\r\n\r\n app = QApplication(sys.argv)\r\n\r\n window = Window()\r\n\r\n window.show()\r\n\r\n sys.exit(app.exec())\r\n\r\n```\r\n\r\n\r\n\r\n### Result\r\n\r\n\r\n\r\n#### Title bar\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n#### No title bar \r\n\r\n\r\n\r\nIf you make the title bar not visible with `setTitleBarVisible(False)`\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nTry to move and resize it.\r\n\r\n\r\n\r\nNote: Result image was tested in Windows 11, PySide6.\r\n\r\n\r\n\r\n## See Also\r\n\r\n\r\n\r\n<a href=\"https://github.com/yjg30737/pyqt-frameless-window/tree/b84dd1ba421aa7f3f940229ce6379611380f5e35\">Legacy version(0.0.61) README</a> - not using Windows API, qtpy, just good old PyQt5. Enable to resize and move as always. (clunky in Windows though) Only for PyQt5 by the way.\r\n\r\n\r\n\r\nDon't use multiple inheritance!!\r\n\r\n\r\n\r\n## TODO list\r\n\r\n* Make QWebEngineView work in win32 app (Windows 10) - QDockWidget, QMdiSubWindow\r\n\r\n* Switching the customized title bar's theme only \r\n\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "PyQt(+PySide) Frameless Window",
"version": "0.0.85",
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "f765c62f180f6b389b81bc954b0a0b2ad8875d657c669d736d0920ac6865d832",
"md5": "a1cf6b7d20b76290312501f3f6f1316a",
"sha256": "4bb23e222703dbc3f33816cc97704ea15dfb57c16bcf44812750e084fc939d23"
},
"downloads": -1,
"filename": "pyqt_frameless_window-0.0.85-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a1cf6b7d20b76290312501f3f6f1316a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 17318,
"upload_time": "2023-04-03T12:18:10",
"upload_time_iso_8601": "2023-04-03T12:18:10.788821Z",
"url": "https://files.pythonhosted.org/packages/f7/65/c62f180f6b389b81bc954b0a0b2ad8875d657c669d736d0920ac6865d832/pyqt_frameless_window-0.0.85-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "36a43f09bd3d2e771d51ec906c8cd1e3c6befe43f2a1b26792d886c3efa7b032",
"md5": "40a86e246fe9ef40de3d29d68903917b",
"sha256": "270101d7545acff02c448c37cdb72cdeb0492529f0c8422a8732ce3124315b57"
},
"downloads": -1,
"filename": "pyqt-frameless-window-0.0.85.tar.gz",
"has_sig": false,
"md5_digest": "40a86e246fe9ef40de3d29d68903917b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 16043,
"upload_time": "2023-04-03T12:18:12",
"upload_time_iso_8601": "2023-04-03T12:18:12.427938Z",
"url": "https://files.pythonhosted.org/packages/36/a4/3f09bd3d2e771d51ec906c8cd1e3c6befe43f2a1b26792d886c3efa7b032/pyqt-frameless-window-0.0.85.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-04-03 12:18:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "yjg30737",
"github_project": "pyqt-frameless-window.git",
"lcname": "pyqt-frameless-window"
}