from PySide6.QtWidgets import QWidget, QLabel, QApplication from PySide6.QtGui import QPainter, QPen, QColor from PySide6.QtCore import QRectF, Qt, QSize import sys class KeyWidget(QWidget): def __init__(self, key_label: str, debug: bool = False, parent=None): super().__init__(parent) self.key_label = key_label self.debug = debug self.label = QLabel(key_label, self) self.label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.hitbox_rect = QRectF(0, 0, 50, 50) self.resize(60, 60) def resizeEvent(self, event): self.label.setGeometry(0, 0, self.width(), self.height()) def paintEvent(self, event): painter = QPainter(self) # Always draw the base border (true key bounds) base_pen = QPen(QColor(100, 100, 100), 1, Qt.SolidLine) painter.setPen(base_pen) painter.drawRect(0, 0, self.width() - 1, self.height() - 1) if self.debug: # Draw hitbox as red dashed line hitbox_pen = QPen(QColor(255, 0, 0), 2, Qt.DashLine) painter.setPen(hitbox_pen) painter.drawRect(self.hitbox_rect) def set_hitbox_size(self, width: float, height: float): x = (self.width() - width) / 2 y = (self.height() - height) / 2 self.hitbox_rect = QRectF(x, y, width, height) self.update() def sizeHint(self) -> QSize: return QSize(60, 60) def mousePressEvent(self, event): if self.hitbox_rect.contains(event.position()): print(f"Key '{self.key_label}' pressed inside hitbox.") else: print(f"Key '{self.key_label}' clicked outside hitbox.") if __name__ == "__main__": app = QApplication(sys.argv) from PySide6.QtWidgets import QGridLayout, QWidget main_window = QWidget() layout = QGridLayout(main_window) keys = "ASDF" for i, char in enumerate(keys): key = KeyWidget(char, debug=True) key.set_hitbox_size(30 + i * 10, 30 + i * 5) # Varying hitbox sizes layout.addWidget(key, 0, i) main_window.show() sys.exit(app.exec())