|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
|
|
|
|
from PyQt5.QtCore import Qt
|
|
|
|
|
from PyQt5.Qt import *
|
|
|
|
|
from PyQt5.QtGui import QPixmap
|
|
|
|
|
from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QApplication, QLabel, QLineEdit, QVBoxLayout, QMessageBox, QPushButton
|
|
|
|
|
from PyQt5.QtWidgets import QWidget
|
|
|
|
|
|
|
|
|
|
from ctypes import POINTER, cast
|
|
|
|
|
from ctypes.wintypes import MSG
|
|
|
|
|
from utils import Globals
|
|
|
|
|
from win32 import win32api, win32gui
|
|
|
|
|
from win32.lib import win32con
|
|
|
|
|
from windoweffect import WindowEffect, MINMAXINFO, NCCALCSIZE_PARAMS
|
|
|
|
|
from model.UserModel.UserManage import UserManage
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LoginWidget(QWidget):
|
|
|
|
|
BORDER_WIDTH = 5 #设圆角
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super(LoginWidget, self).__init__()
|
|
|
|
|
self.setupUi()
|
|
|
|
|
self.setObjectName('LoginWidget')
|
|
|
|
|
|
|
|
|
|
def setupUi(self):
|
|
|
|
|
self.resize(306, 451)
|
|
|
|
|
|
|
|
|
|
self.picLabel = QLabel()
|
|
|
|
|
self.picLabel.setPixmap(QPixmap('./Static/userPic.png'))
|
|
|
|
|
self.picLabel.setScaledContents(True)
|
|
|
|
|
|
|
|
|
|
self.userEdit = QLineEdit()
|
|
|
|
|
self.userEdit.setPlaceholderText("请输入用户名")
|
|
|
|
|
self.userEdit.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
|
|
|
|
self.userEdit.setObjectName('userEdit')
|
|
|
|
|
|
|
|
|
|
self.pwdEdit = QLineEdit()
|
|
|
|
|
self.pwdEdit.setPlaceholderText("请输入密码")
|
|
|
|
|
self.pwdEdit.setEchoMode(QLineEdit.Password)
|
|
|
|
|
self.pwdEdit.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
|
|
|
|
self.pwdEdit.setObjectName('pwdEdit')
|
|
|
|
|
|
|
|
|
|
self.loginButton = QPushButton('登录')
|
|
|
|
|
self.loginButton.setObjectName('loginButton')
|
|
|
|
|
self.loginButton.clicked.connect(self.login)
|
|
|
|
|
enter_shortcut = QtWidgets.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Return), self)
|
|
|
|
|
enter_shortcut.activated.connect(self.loginButton.click)
|
|
|
|
|
|
|
|
|
|
self.exitButton = QPushButton('退出')
|
|
|
|
|
self.exitButton.clicked.connect(self.close)
|
|
|
|
|
self.exitButton.setObjectName('exitButton')
|
|
|
|
|
|
|
|
|
|
self.horizontalLayout = QHBoxLayout()
|
|
|
|
|
self.horizontalLayout.addWidget(self.loginButton)
|
|
|
|
|
self.horizontalLayout.addWidget(self.exitButton)
|
|
|
|
|
self.horizontalLayout.setSpacing(10)
|
|
|
|
|
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
self.verticalLayout = QVBoxLayout(self)
|
|
|
|
|
|
|
|
|
|
self.conVerLayout = QVBoxLayout()
|
|
|
|
|
self.conVerLayout.addWidget(self.userEdit)
|
|
|
|
|
self.conVerLayout.addWidget(self.pwdEdit)
|
|
|
|
|
self.conVerLayout.addLayout(self.horizontalLayout)
|
|
|
|
|
self.conVerLayout.setSpacing(32)
|
|
|
|
|
self.conVerLayout.setContentsMargins(34, 26, 34, 65)
|
|
|
|
|
|
|
|
|
|
self.verticalLayout.addWidget(self.picLabel)
|
|
|
|
|
self.verticalLayout.addLayout(self.conVerLayout)
|
|
|
|
|
self.verticalLayout.setStretch(0, 4)
|
|
|
|
|
self.verticalLayout.setStretch(1, 6)
|
|
|
|
|
self.verticalLayout.setSpacing(0)
|
|
|
|
|
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
self.setLayout(self.verticalLayout)
|
|
|
|
|
|
|
|
|
|
# 设置模态窗口
|
|
|
|
|
self.setWindowFlags(self.windowFlags() | Qt.Window)
|
|
|
|
|
self.setWindowModality(Qt.ApplicationModal)
|
|
|
|
|
|
|
|
|
|
self.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowSystemMenuHint)
|
|
|
|
|
self.SHADOW_WIDTH = 0 #边框距离
|
|
|
|
|
self.isLeftPressDown = False #鼠标左键是否按下
|
|
|
|
|
self.dragPosition = 0 #拖动时坐标
|
|
|
|
|
self.padding = 4
|
|
|
|
|
self.Numbers = self.enum(UP=0, DOWN=1, LEFT=2, RIGHT=3, LEFTTOP=4, LEFTBOTTOM=5, RIGHTBOTTOM=6, RIGHTTOP=7, NONE=8) #枚举参数
|
|
|
|
|
self.setMinimumHeight(451) #窗体最小高度
|
|
|
|
|
self.setMinimumWidth(306) #窗体最小宽度
|
|
|
|
|
self.dir = self.Numbers.NONE #初始鼠标状态
|
|
|
|
|
|
|
|
|
|
#开启鼠标追踪
|
|
|
|
|
self.setMouseTracking(True)
|
|
|
|
|
|
|
|
|
|
#初始化接口
|
|
|
|
|
self.windowEffect = WindowEffect()
|
|
|
|
|
|
|
|
|
|
# 添加DWM阴影效果
|
|
|
|
|
self.windowEffect.addWindowAnimation(self.winId())
|
|
|
|
|
self.windowEffect.addShadowEffect(self.winId())
|
|
|
|
|
|
|
|
|
|
# 解决报错
|
|
|
|
|
self.windowHandle().screenChanged.connect(self.__onScreenChanged)
|
|
|
|
|
self.setWindowOpacity(0.995) # 设置窗口透明度
|
|
|
|
|
self.setWindowFlag(Qt.FramelessWindowHint)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def login(self):
|
|
|
|
|
returnVar = UserManage.authentication(self.userEdit.text(), self.pwdEdit.text())
|
|
|
|
|
if returnVar == 2:
|
|
|
|
|
QMessageBox.information(self, "提示", "账号不存在")
|
|
|
|
|
if returnVar == 1:
|
|
|
|
|
QMessageBox.information(self, "提示", "密码错误")
|
|
|
|
|
if returnVar == 0:
|
|
|
|
|
# Globals.setValue('username', self.userEdit.text())
|
|
|
|
|
# username = Globals.getValue('username')
|
|
|
|
|
username = self.userEdit.text()
|
|
|
|
|
userauthority = UserManage.getByName(username)
|
|
|
|
|
proType = Globals.getValue('currentProType')
|
|
|
|
|
mainwindow = Globals.getValue('MainWindow')
|
|
|
|
|
|
|
|
|
|
if userauthority[5] == '2':
|
|
|
|
|
mainwindow.projectWidget.importBtn.setEnabled(False)
|
|
|
|
|
mainwindow.projectWidget.exportBtn.setEnabled(False)
|
|
|
|
|
else:
|
|
|
|
|
mainwindow.projectWidget.importBtn.setEnabled(True)
|
|
|
|
|
mainwindow.projectWidget.exportBtn.setEnabled(True)
|
|
|
|
|
|
|
|
|
|
if userauthority[6] == '2':
|
|
|
|
|
if proType in ['0', '1', '2', '3']:
|
|
|
|
|
mainwindow.leftWidget.protocolMag.setEnabled(False)
|
|
|
|
|
else:
|
|
|
|
|
if proType in ['0', '1', '2', '3']:
|
|
|
|
|
mainwindow.leftWidget.protocolMag.setEnabled(True)
|
|
|
|
|
|
|
|
|
|
if userauthority[7] == '2':
|
|
|
|
|
mainwindow.leftWidget.userMag.setEnabled(False)
|
|
|
|
|
else:
|
|
|
|
|
mainwindow.leftWidget.userMag.setEnabled(True)
|
|
|
|
|
|
|
|
|
|
if userauthority[8] == '2':
|
|
|
|
|
mainwindow.leftWidget.trendMag.setEnabled(False)
|
|
|
|
|
else:
|
|
|
|
|
mainwindow.leftWidget.trendMag.setEnabled(True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.close()
|
|
|
|
|
#QMessageBox.information(self, "提示", "登录成功")
|
|
|
|
|
def enum(self,**enums):
|
|
|
|
|
return type('Enum', (), enums)
|
|
|
|
|
|
|
|
|
|
def region(self,cursorGlobalPoint):
|
|
|
|
|
#获取窗体在屏幕上的位置区域,tl为topleft点,rb为rightbottom点
|
|
|
|
|
rect = self.rect()
|
|
|
|
|
tl = self.mapToGlobal(rect.topLeft())
|
|
|
|
|
rb = self.mapToGlobal(rect.bottomRight())
|
|
|
|
|
|
|
|
|
|
x = cursorGlobalPoint.x()
|
|
|
|
|
y = cursorGlobalPoint.y()
|
|
|
|
|
|
|
|
|
|
if(tl.x() + self.padding >= x and tl.x() <= x and tl.y() + self.padding >= y and tl.y() <= y):
|
|
|
|
|
#左上角
|
|
|
|
|
self.dir = self.Numbers.LEFTTOP
|
|
|
|
|
self.setCursor(QCursor(Qt.SizeFDiagCursor)) #设置鼠标形状
|
|
|
|
|
elif(x >= rb.x() - self.padding and x <= rb.x() and y >= rb.y() - self.padding and y <= rb.y()):
|
|
|
|
|
#右下角
|
|
|
|
|
self.dir = self.Numbers.RIGHTBOTTOM
|
|
|
|
|
self.setCursor(QCursor(Qt.SizeFDiagCursor))
|
|
|
|
|
elif(x <= tl.x() + self.padding and x >= tl.x() and y >= rb.y() - self.padding and y <= rb.y()):
|
|
|
|
|
#左下角
|
|
|
|
|
self.dir = self.Numbers.LEFTBOTTOM
|
|
|
|
|
self.setCursor(QCursor(Qt.SizeBDiagCursor))
|
|
|
|
|
elif(x <= rb.x() and x >= rb.x() - self.padding and y >= tl.y() and y <= tl.y() + self.padding):
|
|
|
|
|
#右上角
|
|
|
|
|
self.dir = self.Numbers.RIGHTTOP
|
|
|
|
|
self.setCursor(QCursor(Qt.SizeBDiagCursor))
|
|
|
|
|
elif(x <= tl.x() + self.padding and x >= tl.x()):
|
|
|
|
|
#左边
|
|
|
|
|
self.dir = self.Numbers.LEFT
|
|
|
|
|
self.setCursor(QCursor(Qt.SizeHorCursor))
|
|
|
|
|
elif( x <= rb.x() and x >= rb.x() - self.padding):
|
|
|
|
|
#右边
|
|
|
|
|
|
|
|
|
|
self.dir = self.Numbers.RIGHT
|
|
|
|
|
self.setCursor(QCursor(Qt.SizeHorCursor))
|
|
|
|
|
elif(y >= tl.y() and y <= tl.y() + self.padding):
|
|
|
|
|
#上边
|
|
|
|
|
self.dir = self.Numbers.UP
|
|
|
|
|
self.setCursor(QCursor(Qt.SizeVerCursor))
|
|
|
|
|
elif(y <= rb.y() and y >= rb.y() - self.padding):
|
|
|
|
|
#下边
|
|
|
|
|
self.dir = self.Numbers.DOWN
|
|
|
|
|
self.setCursor(QCursor(Qt.SizeVerCursor))
|
|
|
|
|
else:
|
|
|
|
|
#默认
|
|
|
|
|
self.dir = self.Numbers.NONE
|
|
|
|
|
self.setCursor(QCursor(Qt.ArrowCursor))
|
|
|
|
|
|
|
|
|
|
def mouseReleaseEvent(self,event):
|
|
|
|
|
if(event.button() == Qt.LeftButton):
|
|
|
|
|
self.isLeftPressDown = False
|
|
|
|
|
if(self.dir != self.Numbers.NONE):
|
|
|
|
|
self.releaseMouse()
|
|
|
|
|
self.setCursor(QCursor(Qt.ArrowCursor))
|
|
|
|
|
|
|
|
|
|
def mousePressEvent(self,event):
|
|
|
|
|
if(event.button()==Qt.LeftButton):
|
|
|
|
|
self.isLeftPressDown=True
|
|
|
|
|
if(self.dir != self.Numbers.NONE):
|
|
|
|
|
self.mouseGrabber()
|
|
|
|
|
else:
|
|
|
|
|
self.dragPosition = event.globalPos() - self.frameGeometry().topLeft()
|
|
|
|
|
|
|
|
|
|
def mouseMoveEvent(self,event):
|
|
|
|
|
gloPoint = event.globalPos()
|
|
|
|
|
rect = self.rect()
|
|
|
|
|
tl = self.mapToGlobal(rect.topLeft())
|
|
|
|
|
rb = self.mapToGlobal(rect.bottomRight())
|
|
|
|
|
|
|
|
|
|
if(not self.isLeftPressDown):
|
|
|
|
|
self.region(gloPoint)
|
|
|
|
|
else:
|
|
|
|
|
if(self.dir != self.Numbers.NONE):
|
|
|
|
|
rmove=QRect(tl, rb)
|
|
|
|
|
if(self.dir==self.Numbers.LEFT):
|
|
|
|
|
if(rb.x() - gloPoint.x() <= self.minimumWidth()):
|
|
|
|
|
rmove.setX(tl.x())
|
|
|
|
|
else:
|
|
|
|
|
rmove.setX(gloPoint.x())
|
|
|
|
|
elif(self.dir==self.Numbers.RIGHT):
|
|
|
|
|
rmove.setWidth(gloPoint.x() - tl.x())
|
|
|
|
|
elif(self.dir==self.Numbers.UP):
|
|
|
|
|
if(rb.y() - gloPoint.y() <= self.minimumHeight()):
|
|
|
|
|
rmove.setY(tl.y())
|
|
|
|
|
else:
|
|
|
|
|
rmove.setY(gloPoint.y())
|
|
|
|
|
elif(self.dir==self.Numbers.DOWN):
|
|
|
|
|
rmove.setHeight(gloPoint.y() - tl.y())
|
|
|
|
|
elif(self.dir==self.Numbers.LEFTTOP):
|
|
|
|
|
if(rb.x() - gloPoint.x() <= self.minimumWidth()):
|
|
|
|
|
rmove.setX(tl.x())
|
|
|
|
|
else:
|
|
|
|
|
rmove.setX(gloPoint.x())
|
|
|
|
|
if(rb.y() - gloPoint.y() <= self.minimumHeight()):
|
|
|
|
|
rmove.setY(tl.y())
|
|
|
|
|
else:
|
|
|
|
|
rmove.setY(gloPoint.y())
|
|
|
|
|
elif(self.dir==self.Numbers.RIGHTTOP):
|
|
|
|
|
rmove.setWidth(gloPoint.x() - tl.x())
|
|
|
|
|
rmove.setY(gloPoint.y())
|
|
|
|
|
elif(self.dir==self.Numbers.LEFTBOTTOM):
|
|
|
|
|
rmove.setX(gloPoint.x())
|
|
|
|
|
rmove.setHeight(gloPoint.y() - tl.y())
|
|
|
|
|
elif(self.dir==self.Numbers.RIGHTBOTTOM):
|
|
|
|
|
rmove.setWidth(gloPoint.x() - tl.x())
|
|
|
|
|
rmove.setHeight(gloPoint.y() - tl.y())
|
|
|
|
|
else:
|
|
|
|
|
pass
|
|
|
|
|
self.setGeometry(rmove)
|
|
|
|
|
else:
|
|
|
|
|
self.move(event.globalPos() - self.dragPosition)
|
|
|
|
|
event.accept()
|
|
|
|
|
|
|
|
|
|
def nativeEvent(self, eventType, message):
|
|
|
|
|
""" 接受windows发送的信息 """
|
|
|
|
|
msg = MSG.from_address(message.__int__())
|
|
|
|
|
if msg.message == win32con.WM_NCHITTEST:
|
|
|
|
|
# 解决 issue #2 and issue #7
|
|
|
|
|
r = self.devicePixelRatioF()
|
|
|
|
|
xPos = (win32api.LOWORD(msg.lParam) -
|
|
|
|
|
self.frameGeometry().x()*r) % 65536
|
|
|
|
|
yPos = win32api.HIWORD(msg.lParam) - self.frameGeometry().y()*r
|
|
|
|
|
w, h = self.width()*r, self.height()*r
|
|
|
|
|
lx = xPos < self.BORDER_WIDTH
|
|
|
|
|
rx = xPos + 9 > w - self.BORDER_WIDTH
|
|
|
|
|
ty = yPos < self.BORDER_WIDTH
|
|
|
|
|
by = yPos > h - self.BORDER_WIDTH
|
|
|
|
|
if lx and ty:
|
|
|
|
|
return True, win32con.HTTOPLEFT
|
|
|
|
|
elif rx and by:
|
|
|
|
|
return True, win32con.HTBOTTOMRIGHT
|
|
|
|
|
elif rx and ty:
|
|
|
|
|
return True, win32con.HTTOPRIGHT
|
|
|
|
|
elif lx and by:
|
|
|
|
|
return True, win32con.HTBOTTOMLEFT
|
|
|
|
|
elif ty:
|
|
|
|
|
return True, win32con.HTTOP
|
|
|
|
|
elif by:
|
|
|
|
|
return True, win32con.HTBOTTOM
|
|
|
|
|
elif lx:
|
|
|
|
|
return True, win32con.HTLEFT
|
|
|
|
|
elif rx:
|
|
|
|
|
return True, win32con.HTRIGHT
|
|
|
|
|
elif msg.message == win32con.WM_NCCALCSIZE:
|
|
|
|
|
if self.__isWindowMaximized(msg.hWnd):
|
|
|
|
|
self.__monitorNCCALCSIZE(msg)
|
|
|
|
|
return True, 0
|
|
|
|
|
elif msg.message == win32con.WM_GETMINMAXINFO:
|
|
|
|
|
if self.__isWindowMaximized(msg.hWnd):
|
|
|
|
|
window_rect = win32gui.GetWindowRect(msg.hWnd)
|
|
|
|
|
if not window_rect:
|
|
|
|
|
return False, 0
|
|
|
|
|
|
|
|
|
|
# get the monitor handle
|
|
|
|
|
monitor = win32api.MonitorFromRect(window_rect)
|
|
|
|
|
if not monitor:
|
|
|
|
|
return False, 0
|
|
|
|
|
|
|
|
|
|
# get the monitor info
|
|
|
|
|
__monitorInfo = win32api.GetMonitorInfo(monitor)
|
|
|
|
|
monitor_rect = __monitorInfo['Monitor']
|
|
|
|
|
work_area = __monitorInfo['Work']
|
|
|
|
|
|
|
|
|
|
# convert lParam to MINMAXINFO pointer
|
|
|
|
|
info = cast(msg.lParam, POINTER(MINMAXINFO)).contents
|
|
|
|
|
|
|
|
|
|
# adjust the size of window
|
|
|
|
|
info.ptMaxSize.x = work_area[2] - work_area[0]
|
|
|
|
|
info.ptMaxSize.y = work_area[3] - work_area[1]
|
|
|
|
|
info.ptMaxTrackSize.x = info.ptMaxSize.x
|
|
|
|
|
info.ptMaxTrackSize.y = info.ptMaxSize.y
|
|
|
|
|
|
|
|
|
|
# modify the upper left coordinate
|
|
|
|
|
info.ptMaxPosition.x = abs(window_rect[0] - monitor_rect[0])
|
|
|
|
|
info.ptMaxPosition.y = abs(window_rect[1] - monitor_rect[1])
|
|
|
|
|
return True, 1
|
|
|
|
|
|
|
|
|
|
return QWidget.nativeEvent(self, eventType, message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __isWindowMaximized(self, hWnd) -> bool:
|
|
|
|
|
""" Determine whether the window is maximized """
|
|
|
|
|
# GetWindowPlacement() returns the display state of the window and the restored,
|
|
|
|
|
# maximized and minimized window position. The return value is tuple
|
|
|
|
|
windowPlacement = win32gui.GetWindowPlacement(hWnd)
|
|
|
|
|
if not windowPlacement:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
return windowPlacement[1] == win32con.SW_MAXIMIZE
|
|
|
|
|
|
|
|
|
|
def __monitorNCCALCSIZE(self, msg: MSG):
|
|
|
|
|
""" 调整窗口大小 """
|
|
|
|
|
monitor = win32api.MonitorFromWindow(msg.hWnd)
|
|
|
|
|
|
|
|
|
|
# If the display information is not saved, return directly
|
|
|
|
|
if monitor is None and not self.__monitorInfo:
|
|
|
|
|
return
|
|
|
|
|
elif monitor is not None:
|
|
|
|
|
self.__monitorInfo = win32api.GetMonitorInfo(monitor)
|
|
|
|
|
|
|
|
|
|
# adjust the size of window
|
|
|
|
|
params = cast(msg.lParam, POINTER(NCCALCSIZE_PARAMS)).contents
|
|
|
|
|
params.rgrc[0].left = self.__monitorInfo['Work'][0]
|
|
|
|
|
params.rgrc[0].top = self.__monitorInfo['Work'][1]
|
|
|
|
|
params.rgrc[0].right = self.__monitorInfo['Work'][2]
|
|
|
|
|
params.rgrc[0].bottom = self.__monitorInfo['Work'][3]
|
|
|
|
|
|
|
|
|
|
def __onScreenChanged(self):
|
|
|
|
|
hWnd = int(self.windowHandle().winId())
|
|
|
|
|
win32gui.SetWindowPos(hWnd, None, 0, 0, 0, 0, win32con.SWP_NOMOVE |
|
|
|
|
|
win32con.SWP_NOSIZE | win32con.SWP_FRAMECHANGED)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
|
app.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
|
|
|
|
|
# print(QtWidgets.QStyleFactory.keys())
|
|
|
|
|
ex = LoginWidget()
|
|
|
|
|
ex.show()
|
|
|
|
|
sys.exit(app.exec_())
|