Skip to content
Snippets Groups Projects
Commit 7442a757 authored by Lucas Philippe's avatar Lucas Philippe
Browse files

erreur adding

parent 11e922ad
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 1182 deletions
from PyQt5.QtGui import QColor
class BubbleCursor:
defaultCol=QColor("blue")
def __init__(self, targets):
self.x = 0
self.y = 0
self.size = 50
self.targets = targets
self.closest = None
def paint(self, painter):
painter.setBrush(self.defaultCol)
painter.drawEllipse(int(self.x - self.size), int(self.y - self.size), int(self.size * 2), int(self.size * 2))
def move(self, x, y):
self.x = x
self.y = y
min_distance = float("inf")
previous_closest = self.closest
for target in self.targets:
distance = ((self.x - target.x) ** 2 + (self.y - target.y) ** 2) ** 0.5 # cf. Theoreme de Pythagore
distance = distance - target.size/2 # Prendre la distance avec le contour du cercle et pas le centre
if distance < min_distance:
min_distance = distance
self.closest = target
self.size = min_distance
if previous_closest != self.closest:
if previous_closest:
previous_closest.highlighted = False
self.closest.highlighted = True
\ No newline at end of file
import csv
import random
import time
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QWidget
from BubbleCursor import BubbleCursor
from Target import Target
class BubbleWidget(QWidget):
def __init__(self, file_name, exp_setup, number_of_targets, technique_name):
super().__init__()
self.exp_setup = exp_setup
self.targets = []
self.setMouseTracking(True)
self.start_time = None
self.errors = 0
self.technique_name = technique_name
# Chargement du fichier csv
with open(file_name) as csvfile:
reader = csv.reader(csvfile)
for row in reader:
x = int(row[0])
y = int(row[1])
size = int(row[2])
target = Target(x, y, size)
self.targets.append(target)
self.target_to_select = self.targets[:number_of_targets]
self.cursor = BubbleCursor(self.targets)
self.selectRandomTarget()
def paintEvent(self, event):
painter = QPainter(self)
self.cursor.paint(painter)
for target in self.targets:
target.paint(painter)
painter.setPen(QColor("black"))
status_text = f"Technique: {self.technique_name}, Cible: {self.target_number}/15, Configuration: {self.config_number}/9, Répétition: {self.repeat_number}/{self.total_repeats}"
painter.drawText(10, 20, status_text)
def mouseMoveEvent(self, event):
self.cursor.move(event.x(), event.y())
self.update()
def selectRandomTarget(self):
if self.start_time == None:
self.start_time = time.time()
target = self.target_to_select.pop()
target.toSelect = True
self.update()
def printLog(self):
current_time = (time.time() - self.start_time)*1000
self.exp_setup.add_line_to_response(current_time, self.errors)
self.errors = 0
self.start_time = None
def set_status(self, target_number, config_number, repeat_number, total_repeats):
self.target_number = target_number
self.config_number = config_number
self.repeat_number = repeat_number
self.total_repeats = total_repeats
def mousePressEvent(self, event):
if self.cursor.closest is not None:
if self.cursor.closest.click_cible():
self.errors = 0
self.target_number += 1
self.printLog()
if len(self.target_to_select) > 0:
self.selectRandomTarget()
else:
self.exp_setup.next_experience()
else:
self.errors += 1
self.set_status(self.target_number, self.config_number, self.repeat_number,
self.total_repeats)
self.update()
import os
import sys
from PyQt5.QtGui import QIntValidator
from PyQt5.QtWidgets import QDialog, QLabel, QLineEdit, QComboBox, QGridLayout, QPushButton, QHBoxLayout, QVBoxLayout
from Experience import Experience
from FileDisplayWidget import FileDisplayWidget
DIR_PATH = "generated_exp/"
TARGETS_PER_EXPERIENCE = 15
class ExpSetup(QDialog):
def __init__(self, window):
super().__init__()
self.file_name = 'data/response.csv'
self.current_ordonnance = None
self.ordonnance = None
self.window = window
self.user_number = None
self.technique = None
self.repeats = None
self.current_repeat_series = 0
self.current_target_number = 1
user_label = QLabel("Numéro d'utilisateur :")
self.user_edit = QLineEdit()
self.user_edit.setValidator(QIntValidator())
tech_label = QLabel("Technique :")
self.tech_combo = QComboBox()
self.tech_combo.addItems(["Bubble", "Rope", "Normal"])
repeats_label = QLabel("Nombre de répétitions :")
self.repeats_edit = QLineEdit()
self.repeats_edit.setValidator(QIntValidator())
layout = QGridLayout()
layout.addWidget(user_label, 0, 0)
layout.addWidget(self.user_edit, 0, 1)
layout.addWidget(tech_label, 1, 0)
layout.addWidget(self.tech_combo, 1, 1)
layout.addWidget(repeats_label, 4, 0)
layout.addWidget(self.repeats_edit, 4, 1)
self.validate_button = QPushButton("Valider")
self.validate_button.clicked.connect(self.verify_entry)
h_layout = QHBoxLayout()
h_layout.addStretch()
h_layout.addWidget(self.validate_button)
h_layout.addStretch()
v_layout = QVBoxLayout()
v_layout.addLayout(layout)
v_layout.addLayout(h_layout)
self.setLayout(v_layout)
def verify_entry(self):
self.user_number = self.user_edit.text()
self.technique = self.tech_combo.currentIndex()
self.repeats = int(self.repeats_edit.text())
if self.repeats <= 1:
print('Répétition doit être strictement supérieur à 1')
else:
self.init_ordonnance()
self.next_experience()
def create_experience(self, experience, density, target_size, technique_name):
if experience not in Experience:
print('Aucune expérience selectionné')
return None
density = str(density)
target_size = str(target_size)
file_name = "src_d_" + density + "_s_" + target_size + ".csv"
file_path = DIR_PATH + file_name
return experience.create_widget(file_path, self, TARGETS_PER_EXPERIENCE, technique_name)
def start_experience(self, widget):
if widget is not None:
self.window.resize(1024, 800)
self.window.setCentralWidget(widget)
self.window.show()
def init_ordonnance(self):
self.ordonnance = []
self.current_ordonnance = -1
experience_list = [Experience.BUBBLE, Experience.ROPE, Experience.NORMAL]
experience_ordered = experience_list[self.technique:] + experience_list[:self.technique]
density_list = [30, 60, 90]
size_list = [9, 12, 18]
for _ in range(self.repeats):
for experience in experience_ordered:
for density in density_list:
for size in size_list:
widget = self.create_experience(experience, density, size, experience.name)
self.ordonnance.append((widget, experience, density, size))
def next_experience(self):
self.current_target_number = 1
self.current_ordonnance += 1
total_experiences_per_repeat = len(Experience) * len([30, 60, 90]) * len([9, 12, 18])
if self.current_ordonnance >= len(self.ordonnance):
self.display_data()
return
if self.current_ordonnance % total_experiences_per_repeat == 0 and self.current_ordonnance != 0:
self.current_repeat_series += 1
self.current_configuration_number = (self.current_ordonnance % 9) + 1
self.current_repeat_number = (self.current_ordonnance // total_experiences_per_repeat) + 1
widget, experience, density, size = self.ordonnance[self.current_ordonnance]
widget.set_status(self.current_repeat_series, self.current_configuration_number, self.current_repeat_number,
self.repeats)
self.start_experience(widget)
def add_line_to_response(self, time, error):
line = f"{self.user_number}, {self.current_repeat_series}, {self.current_target_number}, {self.ordonnance[self.current_ordonnance][2]}, {self.ordonnance[self.current_ordonnance][3]}, {self.ordonnance[self.current_ordonnance][1].name}, {time}, {error}"
with open(self.file_name, "a") as file:
file.write(line + '\n')
self.current_target_number += 1
def display_data(self):
widget = FileDisplayWidget(self.file_name)
self.start_experience(widget)
from enum import Enum
from BubbleWidget import BubbleWidget
from RopeWidget import RopeWidget
from NormalWidget import NormalWidget
class Experience(Enum):
BUBBLE = 1
ROPE = 2
NORMAL = 3
def create_widget(self, file_path, exp_setup, number_of_targets, technique_name):
if self.value == Experience.BUBBLE.value:
widget = BubbleWidget(file_path, exp_setup, number_of_targets, technique_name)
elif self.value == Experience.ROPE.value:
widget = RopeWidget(file_path, exp_setup, number_of_targets, technique_name)
elif self.value == Experience.NORMAL.value:
widget = NormalWidget(file_path, exp_setup, number_of_targets, technique_name)
else:
print('Aucune expérience selectionnée')
widget = None
return widget
\ No newline at end of file
from PyQt5.QtWidgets import QTextEdit, QWidget, QApplication, QMainWindow
class FileDisplayWidget(QWidget):
def __init__(self, filename):
super().__init__()
self.filename = filename
self.textEdit = QTextEdit(self)
self.textEdit.setReadOnly(True)
with open(self.filename, 'r') as f:
self.textEdit.setPlainText(f.read())
def resizeEvent(self, event):
self.textEdit.setGeometry(0, 0, self.width(), self.height())
import random
import csv
SIZE_X_MAX = 1000
SIZE_Y_MAX = 800
DIR_NAME = 'generated_exp/'
SPACING = 5
all_density = (30, 60, 90)
all_size = (9, 12, 18)
max_density = max(all_density)
max_size = max(all_size)
def generate_targets(num_targets, max_target_size, min_spacing):
all_targets = []
for _ in range(num_targets):
x = random.randint(0, SIZE_X_MAX)
y = random.randint(0, SIZE_Y_MAX)
target = (x, y, max_target_size)
if not all_targets:
all_targets.append(target)
else:
min_distance = min([(((x - t[0]) ** 2 + (y - t[1]) ** 2) ** 0.5) - max_target_size/2 for t in all_targets])
if min_distance >= min_spacing:
all_targets.append(target)
return all_targets
def save_to_csv(filename, all_targets, density, change_size):
with open(filename, "w", newline='\n') as f:
writer = csv.writer(f)
for target in all_targets[:density]:
as_list = list(target)
as_list[2] = change_size
writer.writerow(as_list)
def create_csv(filename, all_targets, density, change_size):
save_to_csv(filename, all_targets, density, change_size)
def create_all_files(min_spacing):
all_targets = generate_targets(max_density, max_size, min_spacing)
for density in all_density:
for size in all_size:
filename = "src_d_" + str(density) + '_s_' + str(size) + '.csv'
create_csv(DIR_NAME + filename, all_targets, density, size)
if __name__ == '__main__':
create_all_files(SPACING)
import sys
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import QApplication, QMainWindow
from BubbleWidget import BubbleWidget
file_name = "data/src_tp_bubble.csv"
def main():
app = QApplication(sys.argv)
main_window = QMainWindow()
main_window.resize(1024, 800)
bubble_widget = BubbleWidget(file_name)
main_window.setCentralWidget(bubble_widget)
main_window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
if len(sys.argv) == 2:
file_name = sys.argv[1]
main()
from PyQt5.QtWidgets import QApplication, QMainWindow
from ExpSetup import ExpSetup
def main():
app = QApplication([])
window = QMainWindow()
exp_widget = ExpSetup(window)
window.setCentralWidget(exp_widget)
window.show()
app.exec_()
if __name__ == "__main__":
main()
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from NormalWidget import NormalWidget
file_name = "data/src_tp_bubble.csv"
def main():
app = QApplication([])
window = QMainWindow()
window.resize(1024, 800)
normalWidget = NormalWidget(file_name)
window.setCentralWidget(normalWidget)
window.show()
app.exec_()
if __name__ == "__main__":
if len(sys.argv) == 2:
file_name = sys.argv[1]
main()
from PyQt5.QtWidgets import QApplication, QMainWindow
from RopeWidget import RopeWidget
file_name = "data/src_tp_bubble.csv"
def main():
app = QApplication([])
window = QMainWindow()
window.resize(1024, 800)
bubble_widget = RopeWidget(file_name)
window.setCentralWidget(bubble_widget)
window.show()
app.exec_()
if __name__ == "__main__":
main()
from PyQt5.QtGui import QColor
class NormalCursor:
defaultCol=QColor("blue")
def __init__(self, targets):
self.x = 0
self.y = 0
self.targets = targets
self.closest = None
def move(self, x, y):
self.x = x
self.y = y
closest_target = None
min_distance = float('inf')
for target in self.targets:
distance = ((self.x - target.x) ** 2 + (self.y - target.y) ** 2) ** 0.5
if distance < min_distance:
min_distance = distance
closest_target = target
if closest_target and min_distance < closest_target.size / 2:
closest_target.highlighted = True
else:
if self.closest and self.closest != closest_target:
self.closest.highlighted = False
self.closest = closest_target
\ No newline at end of file
import csv
import random
import time
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QWidget
from NormalCursor import NormalCursor
from Target import Target
class NormalWidget(QWidget):
def __init__(self, file_name, exp_setup, number_of_targets, technique_name):
super().__init__()
self.targets = []
self.setMouseTracking(True)
self.start_time = None
self.exp_setup = exp_setup
self.errors = 0
self.technique_name = technique_name
# Chargement du fichier csv
with open(file_name) as csvfile:
reader = csv.reader(csvfile)
for row in reader:
x = int(row[0])
y = int(row[1])
size = int(row[2])
target = Target(x, y, size)
self.targets.append(target)
self.target_to_select = self.targets[:number_of_targets]
self.cursor = NormalCursor(self.targets)
self.selectRandomTarget()
def paintEvent(self, event):
painter = QPainter(self)
for target in self.targets:
target.paint(painter)
painter.setPen(QColor("black"))
status_text = f"Technique: {self.technique_name}, Cible: {self.target_number}/15, Configuration: {self.config_number}/9, Répétition: {self.repeat_number}/{self.total_repeats}"
painter.drawText(10, 20, status_text)
def set_status(self, target_number, config_number, repeat_number, total_repeats):
self.target_number = target_number
self.config_number = config_number
self.repeat_number = repeat_number
self.total_repeats = total_repeats
def mouseMoveEvent(self, event):
self.cursor.move(event.x(), event.y())
self.update()
def selectRandomTarget(self):
if self.start_time is None:
self.start_time = time.time()
target = self.target_to_select.pop()
target.toSelect = True
self.update()
def printLog(self):
current_time = (time.time() - self.start_time)*1000
self.exp_setup.add_line_to_response(current_time, self.errors)
self.errors = 0
self.start_time = None
def mousePressEvent(self, event):
if self.cursor.closest is not None and self.cursor.closest.toSelect:
distance = ((event.x() - self.cursor.closest.x) ** 2 + (event.y() - self.cursor.closest.y) ** 2) ** 0.5
if distance <= self.cursor.closest.size / 2:
self.target_number += 1
self.printLog()
self.cursor.closest.toSelect = False
self.cursor.closest = None
if len(self.target_to_select) > 0:
self.selectRandomTarget()
else:
self.exp_setup.next_experience()
else:
self.errors += 1
self.set_status(self.target_number, self.config_number, self.repeat_number, self.total_repeats)
self.update()
# Programmation d'une technique d'interaction : le Bubble Cursor
from BubbleCursor import BubbleCursor
class RopeCursor(BubbleCursor):
def paint(self, painter):
if self.closest is not None:
painter.setBrush(self.defaultCol)
painter.drawLine(self.x, self.y, self.closest.x, self.closest.y)
import csv, random, time
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QWidget
from Target import Target
from RopeCursor import RopeCursor
class RopeWidget(QWidget):
def __init__(self, file_name, exp_setup, number_of_targets, technique_name):
super().__init__()
self.exp_setup = exp_setup
self.targets = []
self.setMouseTracking(True)
self.start_time = None
self.errors = 0
self.technique_name = technique_name
# Chargement du fichier csv
with open(file_name) as csvfile:
reader = csv.reader(csvfile)
for row in reader:
x = int(row[0])
y = int(row[1])
size = int(row[2])
target = Target(x, y, size)
self.targets.append(target)
self.target_to_select = self.targets[:number_of_targets]
self.cursor = RopeCursor(self.targets)
self.selectRandomTarget()
def paintEvent(self, event):
painter = QPainter(self)
self.cursor.paint(painter)
for target in self.targets:
target.paint(painter)
painter.setPen(QColor("black"))
status_text = f"Technique: {self.technique_name}, Cible: {self.target_number}/15, Configuration: {self.config_number}/9, Répétition: {self.repeat_number}/{self.total_repeats}"
painter.drawText(10, 20, status_text)
def set_status(self, target_number, config_number, repeat_number, total_repeats):
self.target_number = target_number
self.config_number = config_number
self.repeat_number = repeat_number
self.total_repeats = total_repeats
def mouseMoveEvent(self, event):
self.cursor.move(event.x(), event.y())
self.update()
def selectRandomTarget(self):
if self.start_time == None:
self.start_time = time.time()
target = self.target_to_select.pop()
target.toSelect = True
self.update()
def printLog(self):
current_time = (time.time() - self.start_time)*1000
self.exp_setup.add_line_to_response(current_time, self.errors)
self.errors = 0
self.start_time = None
def mousePressEvent(self, event):
if self.cursor.closest is not None:
if self.cursor.closest.click_cible():
self.errors = 0
self.target_number += 1
self.printLog()
if len(self.target_to_select) > 0:
self.selectRandomTarget()
else:
self.exp_setup.next_experience()
else:
self.errors += 1
self.set_status(self.target_number, self.config_number, self.repeat_number,
self.total_repeats)
self.update()
from PyQt5.QtGui import QColor, QBrush, QPen
class Target:
defaultCol = QColor("green")
highlightCol = QColor("red")
toSelectCol = QColor("blue")
def __init__(self, x, y, size):
self.x = x
self.y = y
self.size = size
self.toSelect = False
self.highlighted = False
def paint(self, painter):
color = self.defaultCol
if self.toSelect:
color = self.toSelectCol
elif self.highlighted:
color = self.highlightCol
painter.setBrush(QBrush(color))
painter.setPen(QPen(color))
painter.drawEllipse(int(self.x - self.size / 2), int(self.y - self.size / 2), int(self.size), int(self.size))
def click_cible(self):
if self.toSelect:
self.toSelect = False
return True
return False
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment