Использую python 3.5 + pyQT5
Создаю окно, внутри него лейблы.
Как мне на лейблы повесить события ховер( и клик заодно)
Например на InfoSover
Если прописываю просто внутри класса
def enterEvent(self, QEvent):
то он срабатывает на все окно, а мне надо конкретно к определенному лейлу/баттону/любому элементу применить
from PyQt5.QtWidgets import * from PyQt5 import QtCore from functions.main_funcs import getScreen import configparser class ProfileForm(QWidget): # Объявляем позицию окна для последущей записи PF_wx = 0 PF_wy = 0 def __init__(self): super().__init__() self.initUI() def initUI(self): self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool) # окно без рамок и заголовка, не отображается на панели задач self.setAttribute(QtCore.Qt.WA_TranslucentBackground) # прозрачный бек окна self.setFixedSize(330, 220) # InfoS BG info_s = QLabel(self) info_s.setStyleSheet("background-repeat: none; background-image: url(.data/img/infoS.png); background-position:0 0;") info_s.setFixedSize(303, 220) info_s.move(0, 0) # user avatar avatar = QLabel(self) avatar.setStyleSheet("background-repeat: none; background-image: url(.data/img/avatarDemo.png); background-position:center center; border-radius:50px; border: 1px solid transparent;") avatar.setFixedSize(103, 103) avatar.move(67, 50) # gate6 BG gate6 = QLabel(self) gate6.setStyleSheet("background-repeat: none; background-image: url(.data/img/gate6.png); background-position:0 0;") gate6.setFixedSize(180, 90) gate6.move(145, 42) # InfoSover infosover = QLabel(self) infosover.setStyleSheet("cursor:pointer; background: transparent; background-repeat: none; background-image: url(.data/img/over.png); background-position:0 0;") infosover.setFixedSize(112, 112) infosover.move(62, 47) # Получаем данные о расположении окна и зписываем в конфиг положение окна если его нет config = configparser.ConfigParser() config.read('config.ini') profile_xy_x = 0 profile_xy_y = 0 try: profile_xy_x = int(config.get('profileXY','x')) profile_xy_y = int(config.get('profileXY', 'y')) except configparser.NoSectionError: config.add_section('profileXY') config.set('profileXY', 'x', '0') config.set('profileXY', 'y', '0') with open('config.ini', 'w') as configfile: config.write(configfile) finally: self.move(profile_xy_x, profile_xy_y) # показываем окно self.show() # Возможность перемещения окна def mousePressEvent(self, event): self.offset = event.pos() def mouseMoveEvent(self, event): global PF_wx, PF_wy x = event.globalX() y = event.globalY() x_w = self.offset.x() y_w = self.offset.y() w_x = x - x_w w_y = y - y_w # Вычисляем размеры экрана и не даем окну выходить за его пределы if (w_x < 0): w_x = 0 if (w_y < 0): w_y = 0 screen = getScreen() screen_w = screen[0] screen_h = screen[1] win_w = self.width() win_h = self.height() if (w_x > (screen_w - win_w)): w_x = screen_w - win_w if (w_y > (screen_h - win_h)): w_y = screen_h - win_h PF_wx = w_x PF_wy = w_y # двигаем окно по позиции self.move(w_x, w_y) def mouseReleaseEvent(self, event): global PF_wx, PF_wy # Записываем в конфиг положение окна после перетаскивания config = configparser.ConfigParser() config.read('config.ini') config.set('profileXY', 'x', str(PF_wx)) config.set('profileXY', 'y', str(PF_wy)) with open('config.ini', 'w') as configfile: config.write(configfile) def close(self): self.hide() qApp.quit()
Сделала такой вариант через баттон:
from PyQt5.QtWidgets import * from PyQt5 import QtCore from PyQt5.QtCore import pyqtSignal from functions.main_funcs import getScreen import configparser class HoverButton(QPushButton): mouseHover = pyqtSignal(bool) def __init__(self, parent=None): QPushButton.__init__(self, parent) self.setMouseTracking(True) def enterEvent(self, event): self.mouseHover.emit(True) global infosover infosover.setStyleSheet("cursor:pointer; background: transparent; background-repeat: none; background-image: url(.data/img/over.png); background-position:0 0;") def leaveEvent(self, event): self.mouseHover.emit(False) infosover.setStyleSheet("cursor:pointer; background: transparent;") class ProfileForm(QWidget): # Объявляем позицию окна для последущей записи PF_wx = 0 PF_wy = 0 infosover = 0 def __init__(self): super().__init__() self.initUI() def initUI(self): self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool) # окно без рамок и заголовка, не отображается на панели задач self.setAttribute(QtCore.Qt.WA_TranslucentBackground) # прозрачный бек окна self.setFixedSize(330, 220) # InfoS BG info_s = QLabel(self) info_s.setStyleSheet("background-repeat: none; background-image: url(.data/img/infoS.png); background-position:0 0;") info_s.setFixedSize(303, 220) info_s.move(0, 0) # user avatar avatar = QLabel(self) avatar.setStyleSheet("background-repeat: none; background-image: url(.data/img/avatarDemo.png); background-position:center center; border-radius:50px; border: 1px solid transparent;") avatar.setFixedSize(103, 103) avatar.move(67, 50) # gate6 BG gate6 = QLabel(self) gate6.setStyleSheet("background-repeat: none; background-image: url(.data/img/gate6.png); background-position:0 0;") gate6.setFixedSize(180, 90) gate6.move(145, 42) # InfoSover global infosover infosover = HoverButton(self) infosover.clicked.connect(self.close) infosover.mouseHover.connect(self.hover) infosover.setStyleSheet("background: transparent;") infosover.setFixedSize(112, 112) infosover.move(63, 45) # Получаем данные о расположении окна и зписываем в конфиг положение окна если его нет config = configparser.ConfigParser() config.read('config.ini') profile_xy_x = 0 profile_xy_y = 0 try: profile_xy_x = int(config.get('profileXY','x')) profile_xy_y = int(config.get('profileXY', 'y')) except configparser.NoSectionError: config.add_section('profileXY') config.set('profileXY', 'x', '0') config.set('profileXY', 'y', '0') with open('config.ini', 'w') as configfile: config.write(configfile) finally: self.move(profile_xy_x, profile_xy_y) # показываем окно self.show() def hover(self): pass # Возможность перемещения окна def mousePressEvent(self, event): self.offset = event.pos() def mouseMoveEvent(self, event): global PF_wx, PF_wy x = event.globalX() y = event.globalY() x_w = self.offset.x() y_w = self.offset.y() w_x = x - x_w w_y = y - y_w # Вычисляем размеры экрана и не даем окну выходить за его пределы if (w_x < 0): w_x = 0 if (w_y < 0): w_y = 0 screen = getScreen() screen_w = screen[0] screen_h = screen[1] win_w = self.width() win_h = self.height() if (w_x > (screen_w - win_w)): w_x = screen_w - win_w if (w_y > (screen_h - win_h)): w_y = screen_h - win_h PF_wx = w_x PF_wy = w_y # двигаем окно по позиции self.move(w_x, w_y) def mouseReleaseEvent(self, event): global PF_wx, PF_wy # Записываем в конфиг положение окна после перетаскивания config = configparser.ConfigParser() config.read('config.ini') config.set('profileXY', 'x', str(PF_wx)) config.set('profileXY', 'y', str(PF_wy)) with open('config.ini', 'w') as configfile: config.write(configfile) def close(self): self.hide() qApp.quit()
Работает, но по мне это какой-то костыль на глобалсах, и по идее должно делаться куда проще. Ибо если вешать ховер на другие элементы
мне придется класс class HoverButton постоянно дублировать чтобы задавать события для разных элементов окна.
2) Как можно сменить курсор у лейбла/баттона? в css cursor:hand; не пашет. через setCursor тоже что-то не пойму как сделать)