128 lines
4.5 KiB
Python
128 lines
4.5 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""Created on 2018年8月2日
|
|
author: Irony
|
|
site: https://pyqt.site , https://github.com/PyQt5
|
|
email: 892768447@qq.com
|
|
file: win无边框调整大小
|
|
description:
|
|
"""
|
|
|
|
import ctypes.wintypes
|
|
from ctypes.wintypes import POINT
|
|
|
|
import win32api
|
|
import win32con
|
|
import win32gui
|
|
|
|
try:
|
|
from PyQt5.QtCore import Qt
|
|
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
|
|
from PyQt5.QtWinExtras import QtWin
|
|
except ImportError:
|
|
from PySide2.QtCore import Qt
|
|
from PySide2.QtWidgets import QWidget, QPushButton, QApplication
|
|
from PySide2.QtWinExtras import QtWin
|
|
|
|
|
|
class MINMAXINFO(ctypes.Structure):
|
|
_fields_ = [
|
|
("ptReserved", POINT),
|
|
("ptMaxSize", POINT),
|
|
("ptMaxPosition", POINT),
|
|
("ptMinTrackSize", POINT),
|
|
("ptMaxTrackSize", POINT),
|
|
]
|
|
|
|
|
|
class Window(QWidget):
|
|
BorderWidth = 5
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(Window, self).__init__(*args, **kwargs)
|
|
# 主屏幕的可用大小(去掉任务栏)
|
|
self._rect = QApplication.instance().desktop().availableGeometry(self)
|
|
self.resize(800, 600)
|
|
self.setWindowFlags(Qt.Window
|
|
| Qt.FramelessWindowHint
|
|
| Qt.WindowSystemMenuHint
|
|
| Qt.WindowMinimizeButtonHint
|
|
| Qt.WindowMaximizeButtonHint
|
|
| Qt.WindowCloseButtonHint)
|
|
# 增加薄边框
|
|
style = win32gui.GetWindowLong(int(self.winId()), win32con.GWL_STYLE)
|
|
win32gui.SetWindowLong(
|
|
int(self.winId()), win32con.GWL_STYLE, style | win32con.WS_THICKFRAME)
|
|
|
|
if QtWin.isCompositionEnabled():
|
|
# 加上 Aero 边框阴影
|
|
QtWin.extendFrameIntoClientArea(self, -1, -1, -1, -1)
|
|
else:
|
|
QtWin.resetExtendedFrame(self)
|
|
|
|
def nativeEvent(self, eventType, message):
|
|
retval, result = super(Window, self).nativeEvent(eventType, message)
|
|
if eventType == "windows_generic_MSG":
|
|
msg = ctypes.wintypes.MSG.from_address(message.__int__())
|
|
# 获取鼠标移动经过时的坐标
|
|
x = win32api.LOWORD(msg.lParam) - self.frameGeometry().x()
|
|
y = win32api.HIWORD(msg.lParam) - self.frameGeometry().y()
|
|
# 判断鼠标位置是否有其它控件
|
|
if self.childAt(x, y) != None:
|
|
return retval, result
|
|
if msg.message == win32con.WM_NCCALCSIZE:
|
|
# 拦截不显示顶部的系统自带的边框
|
|
return True, 0
|
|
if msg.message == win32con.WM_GETMINMAXINFO:
|
|
# 当窗口位置改变或者大小改变时会触发该消息
|
|
info = ctypes.cast(
|
|
msg.lParam, ctypes.POINTER(MINMAXINFO)).contents
|
|
# 修改最大化的窗口大小为主屏幕的可用大小
|
|
info.ptMaxSize.x = self._rect.width()
|
|
info.ptMaxSize.y = self._rect.height()
|
|
# 修改放置点的x,y坐标为0,0
|
|
info.ptMaxPosition.x, info.ptMaxPosition.y = 0, 0
|
|
if msg.message == win32con.WM_NCHITTEST:
|
|
w, h = self.width(), self.height()
|
|
lx = x < self.BorderWidth
|
|
rx = x > w - self.BorderWidth
|
|
ty = y < self.BorderWidth
|
|
by = y > h - self.BorderWidth
|
|
# 左上角
|
|
if (lx and ty):
|
|
return True, win32con.HTTOPLEFT
|
|
# 右下角
|
|
if (rx and by):
|
|
return True, win32con.HTBOTTOMRIGHT
|
|
# 右上角
|
|
if (rx and ty):
|
|
return True, win32con.HTTOPRIGHT
|
|
# 左下角
|
|
if (lx and by):
|
|
return True, win32con.HTBOTTOMLEFT
|
|
# 上
|
|
if ty:
|
|
return True, win32con.HTTOP
|
|
# 下
|
|
if by:
|
|
return True, win32con.HTBOTTOM
|
|
# 左
|
|
if lx:
|
|
return True, win32con.HTLEFT
|
|
# 右
|
|
if rx:
|
|
return True, win32con.HTRIGHT
|
|
# 标题
|
|
return True, win32con.HTCAPTION
|
|
return retval, result
|
|
|
|
|
|
if __name__ == '__main__':
|
|
import sys
|
|
|
|
app = QApplication(sys.argv)
|
|
w = Window()
|
|
btn = QPushButton('exit', w, clicked=app.quit)
|
|
btn.setGeometry(10, 10, 100, 40)
|
|
w.show()
|
|
sys.exit(app.exec_())
|