lang/pysideex/ ClickableGrid001


import sys
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from PySide6.QtNetwork import *

app = QApplication(sys.argv)

win = QMainWindow()

class G(QWidget):
  def __init__(self,*xs,**kw):
    super().__init__(*xs,**kw)
    self.rows = 8
    self.cols = 8
    self.states = [0 for i in range(self.rows*self.cols)]
    self.state_colors = [QColor.fromRgb(0,0,0),QColor.fromRgb(255,0,0),QColor.fromRgb(0,255,0),QColor.fromRgb(0,0,255)]
    for i in range(self.rows):
      for j in range(self.cols):
        self.setCellState(i,j,(i+j)%len(self.state_colors))
  def getCellState(self,i,j):
    return self.states[i*self.cols+j]
  def setCellState(self,i,j,s):
    self.states[i*self.cols+j] = s % len(self.state_colors)
    self.update()
  def cellForPos(self,x,y):
    rect = self.rect()
    w,h = rect.width(),rect.height()
    row = int(y*self.rows/h)
    if row >= self.rows:
      row = self.rows-1
    col = int(x*self.cols/w)
    if col >= self.cols:
      col = self.cols-1
    return (row,col)
  def clickedCell(self,i,j,delta=1):
    s = self.getCellState(i,j)
    self.setCellState(i,j,s+delta)
  def mousePressEvent(self,event):
    pos = event.position().toPoint()
    x,y = pos.x(), pos.y()
    i,j = self.cellForPos(x,y)
    self.clickedCell(i,j)
  def paintEvent(self,event):
    with QPainter(self) as p:
      rect = self.rect()
      w,h = rect.width(),rect.height()
      xdivs = [ int(i*w/self.cols) for i in range(self.cols) ] + [w]
      ydivs = [ int(i*w/self.rows) for i in range(self.rows) ] + [h]
      for i in range(self.rows):
        for j in range(self.cols):
          c = self.state_colors[self.getCellState(i,j)%len(self.state_colors)]
          x = xdivs[j]
          y = ydivs[i]
          x1 = xdivs[j+1]
          y1 = ydivs[i+1]
          p.fillRect(x,y,x1-x,y1-y,c)

g = G()
win.setCentralWidget(g)
win.setFixedSize(512,512)
win.show()
exit(app.exec())