class PopupWindow(QWidget): def __init__(self, state, device): super().__init__() self.state = state self.close_requested = False self.score_manager = None self.device = device self.network = QNetworkAccessManager() self.minimize = False self.mouse_hover = False self.top = Detector() self.mid = Detector() self.bottom = Detector() self.top.enter.connect(self.leave) self.mid.enter.connect(self.leave) self.bottom.enter.connect(self.leave) self.last_score = None self.counter = 0 # Setup UI self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool | Qt.FramelessWindowHint | Qt.WindowDoesNotAcceptFocus | Qt.X11BypassWindowManagerHint) self.setAttribute(Qt.WA_TranslucentBackground) self.label = QLabel("...") self.graph_view = GraphView() self.layout = QVBoxLayout() # layout.addWidget(self.label) self.layout.addWidget(self.graph_view) self.update_size() self.frame = QWidget() self.frame.setLayout(self.layout) self.frame.setProperty("class", "overlay") main_layout = QVBoxLayout() main_layout.addWidget(self.frame) main_layout.setContentsMargins(0, 0, 0, 0) self.setLayout(main_layout) self.setProperty("class", "root") self.setContentsMargins(0, 0, 0, 0) self.opacity = QGraphicsOpacityEffect() self.opacity.setOpacity(0.8) self.setGraphicsEffect(self.opacity) self.device.connectedChanged.connect(self.graph_view.connected_changed) self.device.updateNumber.connect(self.sensor_update) self.timer = QTimer() self.timer.setInterval(1000 / 30) self.timer.timeout.connect(self.graph_view.update_screen) self.timer.start() def update_size(self): if self.minimize: width, height = 150, 80 self.layout.setContentsMargins(10, 10, 10, 10) else: width, height = 450, 300 self.layout.setContentsMargins(20, 20, 20, 20) desktop: QDesktopWidget = QApplication.instance().desktop() desktop_rect = desktop.availableGeometry() popup_size = QSize(width, height) rect = QStyle.alignedRect(Qt.RightToLeft, Qt.AlignVCenter, popup_size, desktop_rect) self.setGeometry(rect) return desktop_rect, rect def start(self): self.score_manager = ScoreManager(self.state.score, self.state.sensor_values) self.graph_view.start(self.state.score) self.last_score = self.state.score self.counter = 0 # Connect self.device.updateNumber.connect(self.score_manager.score_update) self.score_manager.updateScore.connect(self.score_update) self.show() def set_minimized(self, minimize): self.minimize = minimize self.update_size() self.graph_view.size_changed(minimize) if minimize: self.frame.setStyleSheet("border-radius: 10px;") else: self.frame.setStyleSheet("border-radius: 30px;") def score_update(self, score, msg, sitting_time): if not self.state.is_logged_in(): return if msg == "바른 자세" and not self.mouse_hover: self.set_minimized(True) else: self.set_minimized(False) self.graph_view.update_score(score, msg, sitting_time, self.minimize) self.counter += 1 if self.counter == 50: self.send_data(self.counter / 10, score - self.last_score) self.last_score = score self.counter = 0 def sensor_update(self, score): self.label.setText(str(score)) def send_data(self, duration, dscore): print("send data") data = { "email": self.state.user_email, "duration": duration, "dscore": dscore } req = QNetworkRequest( QUrl(SERVER_BASE_ADDR + "/api/device/update_score")) req.setRawHeader("Content-Type".encode('utf-8'), "application/json".encode('utf-8')) self.network.post(req, json.dumps(data).encode('utf-8')) def closeEvent(self, event: QCloseEvent): if not self.close_requested: event.ignore() self.close_requested = False def enterEvent(self, event: QEvent): if self.minimize: self.set_minimized(False) else: self.opacity.setOpacity(0.1) self.mouse_hover = True self.setWindowFlag(Qt.WindowTransparentForInput, True) self.show() desktop, rect = self.update_size() self.top.setGeometry(QRect(0, 0, desktop.width(), rect.top())) self.mid.setGeometry(QRect(0, rect.top(), rect.left(), rect.height())) self.bottom.setGeometry( QRect(0, rect.bottom(), desktop.width(), desktop.height() - rect.bottom())) self.top.show() self.mid.show() self.bottom.show() def leave(self): self.mouse_hover = False self.top.hide() self.mid.hide() self.bottom.hide() self.opacity.setOpacity(0.8) self.setWindowFlag(Qt.WindowTransparentForInput, False) self.show() def mousePressEvent(self, event: QMouseEvent): event.setAccepted(False) def logout(self): self.close_requested = True self.close()