Pulling excel rows to display as a grid in tkinter - python

I am imaging fluorescent cells from a 384-well plate and my software spits out a formatted excel analysis of the data (16 rowsx24 columns of images turns into a list of data, with 2 measurements from each well, ~800 data points). Because there is a lot of manual interaction with the data, I want to automate my work by taking the information that's indexed in the excel sheet and map it as a tkinter grid. I want to take my data, have it formatted from a list back to the original 16x24 display. I want to be able to interact with that data, among other things, but as a newbie in python, I'm having a difficult time mapping this data.
I used pandas to read my dataframe, but can't seem to display my list to the appropriate grid box. Ideally, I'd like the values in the excel list to display on the corresponding cell in the tkinter grid. For example, in my excel list, [1]:https://imgur.com/a/N8HAtYl, the two data points from each well are listed. I want to take the values from each cell and display them to the corresponding grid in tkinter, so the average of values of "A1" would be mapped onto column 1, row 1 of the grid, A2 would be col 2 row 1, A3 would be col 3 row 1, and so on and so forth.
Any help would be great, thank you.
from tkinter import *
import pandas as pd
from pandas import ExcelWriter
from pandas import ExcelFile
df = pd.read_excel('/Users/Zammam/PycharmProjects/Filipin_Analysis_Zammam/data.xlsx', sheet_name='Dataps')
print(()
class Cell():
FILLED_COLOR_BG = "green"
EMPTY_COLOR_BG = "white"
FILLED_COLOR_BORDER = "green"
EMPTY_COLOR_BORDER = "black"
def __init__(self, master, x, y, size):
self.master = master
self.abs = x
self.ord = y
self.size= size
self.fill= False
def _switch(self):
""" Switch if the cell is filled or not. """
self.fill= not self.fill
def draw(self):
if self.master != None :
fill = Cell.FILLED_COLOR_BG
outline = Cell.FILLED_COLOR_BORDER
if not self.fill:
fill = Cell.EMPTY_COLOR_BG
outline = Cell.EMPTY_COLOR_BORDER
xmin = self.abs * self.size
xmax = xmin + self.size
ymin = self.ord * self.size
ymax = ymin + self.size
self.master.create_rectangle(xmin, ymin, xmax, ymax, fill = fill, outline = outline)
class CellGrid(Canvas):
def __init__(self,master, rowNumber, columnNumber, cellSize, *args, **kwargs):
Canvas.__init__(self, master, width = cellSize * columnNumber , height = cellSize * rowNumber, *args, **kwargs)
self.cellSize = cellSize
self.grid = []
for row in range(rowNumber):
line = []
for column in range(columnNumber):
line.append(Cell(self, column, row, cellSize))
self.grid.append(line)
#memorize the cells that have been modified to avoid many switching of state during mouse motion.
self.switched = []
#bind click action
self.bind("<Button-1>", self.handleMouseClick)
#bind moving while clicking
self.bind("<B1-Motion>", self.handleMouseMotion)
#bind release button action - clear the memory of midified cells.
self.bind("<ButtonRelease-1>", lambda event: self.switched.clear())
self.draw()
def draw(self):
for row in self.grid:
for cell in row:
cell.draw()
def create_text(self):
for row in self.grid:
for cell in row:
for i in df:
cell.create_text(text = df)
def _eventCoords(self, event):
row = int(event.y / self.cellSize)
column = int(event.x / self.cellSize)
return row, column
def handleMouseClick(self, event):
row, column = self._eventCoords(event)
cell = self.grid[row][column]
cell._switch()
cell.draw()
#add the cell to the list of cell switched during the click
self.switched.append(cell)
def handleMouseMotion(self, event):
row, column = self._eventCoords(event)
cell = self.grid[row][column]
if cell not in self.switched:
cell._switch()
cell.draw()
self.switched.append(cell)
if __name__ == "__main__" :
app = Tk()
grid = CellGrid(app, 16, 24, 15)
grid.pack()
app.mainloop()

I'm not familiar with pandas so I will use openpyxl to demonstrate. It will probably be something similar with pandas or even simpler.
from openpyxl import load_workbook
import tkinter as tk
root = tk.Tk()
file = "your_excel_file.xlsx"
wb = load_workbook(file, data_only=True)
ws = wb.active
r = 0
for row in ws:
c = 0
for cell in row:
tk.Label(root,text=cell.value).grid(row=r,column=c)
c+=1
r+=1
root.mainloop()
A quick look at using pandas instead:
df = pd.read_excel('your_excel_file.xlsx',header=None)
for i, row in df.iterrows():
c = 0
for cell in row:
tk.Label(root, text=cell).grid(row=i, column=c)
c += 1

Related

How to make an interactive python grid with tkinter and excel

I want to know how to create a grid that connects to an excel or text file, and when run, it shows who is supposed to be in that grid space for the day and can be updated daily within the excel file.
This is the code that I have/found but I want to connect this GUI to an excel file.
Thanks in advance for your attention!
from tkinter import *
class Cell():
FILLED_COLOR_BG = "green"
EMPTY_COLOR_BG = "white"
FILLED_COLOR_BORDER = "green"
EMPTY_COLOR_BORDER = "black"
def __init__(self, master, x, y, size):
self.master = master
self.abs = x
self.ord = y
self.size= size
self.fill= False
def _switch(self):
self.fill= not self.fill
def draw(self):
if self.master != None :
fill = Cell.FILLED_COLOR_BG
outline = Cell.FILLED_COLOR_BORDER
if not self.fill:
fill = Cell.EMPTY_COLOR_BG
outline = Cell.EMPTY_COLOR_BORDER
xmin = self.abs * self.size
xmax = xmin + self.size
ymin = self.ord * self.size
ymax = ymin + self.size
self.master.create_rectangle(xmin, ymin, xmax, ymax, fill = fill, outline = outline)
class CellGrid(Canvas):
def __init__(self,master, rowNumber, columnNumber, cellSize, *args, **kwargs):
Canvas.__init__(self, master, width = cellSize * columnNumber , height = cellSize * rowNumber, *args, **kwargs)
self.cellSize = cellSize
self.grid = []
for row in range(rowNumber):
line = []
for column in range(columnNumber):
line.append(Cell(self, column, row, cellSize))
self.grid.append(line)
self.switched = []
self.bind("<ButtonRelease-1>", lambda event: self.switched.clear())
self.draw()
def draw(self):
for row in self.grid:
for cell in row:
cell.draw()
def _eventCoords(self, event):
row = int(event.y / self.cellSize)
column = int(event.x / self.cellSize)
return row, column
def handleMouseClick(self, event):
row, column = self._eventCoords(event)
cell = self.grid[row][column]
cell._switch()
cell.draw()
self.switched.append(cell)
def handleMouseMotion(self, event):
row, column = self._eventCoords(event)
cell = self.grid[row][column]
if cell not in self.switched:
cell._switch()
cell.draw()
self.switched.append(cell)
if __name__ == "__main__" :
app = Tk()
grid = CellGrid(app, 5, 2, 100)
grid.pack()
app.mainloop()
self.bind("<Button-1>", self.handleMouseClick)
self.bind("<B1-Motion>", self.handleMouseMotion)

insert dynamic data into QTableWidget

I want to populate a QTableWidgetwith incoming data from user input
this function should insert each incoming input row by row in "real time" , so far its inserts the input in all rows at the same time
what am I missing here ?
#qtc.pyqtSlot(str)
def add_dynamicdata(self, data):
row = 0
col = 0
for i in range(self.table_widget.rowCount()):
# insert inputdata in all cells at the same time !
cell = qtw.QTableWidgetItem(str(data))
self.table_widget.setItem(row, col, cell)
row += 1
full code
#!/usr/bin/env python
"""
"""
import sys
import threading
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
class LambdaTableWidget(qtw.QWidget):
# signals
core_signal = qtc.pyqtSignal(str)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# position
qtRectangle = self.frameGeometry()
centerPoint = qtw.QDesktopWidget().availableGeometry().center()
qtRectangle.moveCenter(centerPoint)
self.move(qtRectangle.topLeft())
# size
self.resize(1400, 710)
# frame title
self.setWindowTitle("QTableWidget Test")
# heading
heading_label = qtw.QLabel('better then excel')
heading_label.setAlignment(qtc.Qt.AlignHCenter | qtc.Qt.AlignTop)
# add Button
self.setdata_button = qtw.QPushButton("insert data")
self.test_button = qtw.QPushButton("test feature")
# table Widget
self.table_widget = qtw.QTableWidget(5, 1)
# name colums, rows
colum_label = ["Weight"]
row_label = ["row 1", "row 2", "row 3", "row 4", "row 5"]
self.table_widget.setHorizontalHeaderLabels(colum_label)
self.table_widget.setVerticalHeaderLabels(row_label)
# layout
self.main_layout = qtw.QGridLayout()
self.main_layout.addWidget(heading_label, 0, 0)
self.main_layout.addWidget(self.table_widget, 1, 0)
self.main_layout.addWidget(self.setdata_button, 2, 0)
self.setLayout(self.main_layout)
self.show()
# functionality
self.setdata_button.clicked.connect(self.start)
def start(self):
# starts thread
# Setting thread.daemon = True will allow the main program to exit before thread is killed.
threading.Thread(target=self._execute, daemon=True).start()
self.core_signal.connect(self.add_dynamicdata)
def _execute(self):
while True:
user_input = input("type in: ")
self.core_signal.emit(user_input) # transmit data
#qtc.pyqtSlot(str)
def add_dynamicdata(self, data):
row = 0
col = 0
for i in range(self.table_widget.rowCount()):
# todo fix the bug !!!
# insert inputdata in all cells at the same time !
cell = qtw.QTableWidgetItem(str(data))
self.table_widget.setItem(row, col, cell)
row += 1
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = LambdaTableWidget()
sys.exit(app.exec_())
def add_dynamicdata(self, data):
row = 0
col = 0
for i in range(self.table_widget.rowCount()):
# insert inputdata in all cells at the same time !
cell = qtw.QTableWidgetItem(str(data))
self.table_widget.setItem(row, col, cell)
row += 1
Data doesn't change in this contest
so cell = qtw.QTableWidgetItem(str(data)) would remain the same for all iterations

How to click through canvas tkinter

I am currently working on a chess program in python (Tkinter), I have got a board to generate with buttons so that I can click on pieces, I planned to use a canvas for each of the chess pieces and then move them around. Is there any way to make it so I can click through the canvas?
try:
from Tkinter import *
except:
from tkinter import *
class grid_piece():
def __init__(self, canvas, row, column, colour_boolean, size):
colour_1 = '#934904'
colour_2 = '#fce2c9'
self.row = row
self.column = column
grid_piece = Button(canvas, height = size // 100,
width = size // 50,
command=lambda: my_board.button_press([row, column]))
grid_piece.grid(row=row, column = column)
if colour_boolean:
grid_piece.configure(bg = colour_1, fg = colour_1)
else:
grid_piece.configure(bg = colour_2, fg = colour_2)
class pawn():
def __init__(self, size, canvas, position):
self.pawn_canvas = Canvas(canvas, width = size // 8, height = size // 8
)
self.pawn_canvas.grid(row = position[0], column = position[1])
class Board():
def __init__(self, master, size):
self.canvas = Canvas(master, width=size, height=size)
self.canvas.pack()
self.size = size
def generate_board(self):
colour_boolean = True
self.board_array = []
for column in range(8):
column_pieces = []
colour_boolean = not colour_boolean
for row in range(8):
colour_boolean = not colour_boolean
piece = grid_piece(self.canvas, row, column, colour_boolean, self.size)
column_pieces.append(piece)
self.board_array.append(column_pieces)
def display_pieces(self):
white_pieces = []
black_pieces = []
for x in range(8):
Pawn = pawn(self.size, self.canvas, [1, x])
white_pieces.append(Pawn)
def button_press(self, position):
print(position)
def onclick(*args):
print(*args)
root = Tk()
my_board = Board(root, 600)
my_board.generate_board()
my_board.display_pieces()
root.mainloop()
Here is an image of my board, the white squares are blank canvases that I will turn into objects once I create the pieces.

how to solve Name error in python2.7

When I run Python script in python3 it works well but in python 2.7 I get an error and I should run this code in Python 2.7 :
this is my code:I want to test some algorithms on path-finding and want to create a window consisting of grids where I can drag my mouse while clicked to create walls and delete them with right click and drag
import Tkinter
class Cell():
FILLED_COLOR_BG = "green"
EMPTY_COLOR_BG = "white"
FILLED_COLOR_BORDER = "green"
EMPTY_COLOR_BORDER = "black"
def __init__(self, master, x, y, size):
""" Constructor of the object called by Cell(...) """
self.master = master
self.abs = x
self.ord = y
self.size= size
self.fill= False
def _switch(self):
""" Switch if the cell is filled or not. """
self.fill= not self.fill
def draw(self):
""" order to the cell to draw its representation on the canvas """
if self.master != None :
fill = Cell.FILLED_COLOR_BG
outline = Cell.FILLED_COLOR_BORDER
if not self.fill:
fill = Cell.EMPTY_COLOR_BG
outline = Cell.EMPTY_COLOR_BORDER
xmin = self.abs * self.size
xmax = xmin + self.size
ymin = self.ord * self.size
ymax = ymin + self.size
self.master.create_rectangle(xmin, ymin, xmax, ymax, fill = fill, outline = outline)
class CellGrid(Canvas):
def __init__(self,master, rowNumber, columnNumber, cellSize, *args, **kwargs):
Canvas.__init__(self, master, width = cellSize * columnNumber , height = cellSize * rowNumber, *args, **kwargs)
self.cellSize = cellSize
self.grid = []
for row in range(rowNumber):
line = []
for column in range(columnNumber):
line.append(Cell(self, column, row, cellSize))
self.grid.append(line)
#memorize the cells that have been modified to avoid many switching of state during mouse motion.
self.switched = []
#bind click action
self.bind("<Button-1>", self.handleMouseClick)
#bind moving while clicking
self.bind("<B1-Motion>", self.handleMouseMotion)
#bind release button action - clear the memory of midified cells.
self.bind("<ButtonRelease-1>", lambda event: self.switched.clear())
self.draw()
def draw(self):
for row in self.grid:
for cell in row:
cell.draw()
def _eventCoords(self, event):
row = int(event.y / self.cellSize)
column = int(event.x / self.cellSize)
return row, column
def handleMouseClick(self, event):
row, column = self._eventCoords(event)
cell = self.grid[row][column]
cell._switch()
cell.draw()
#add the cell to the list of cell switched during the click
self.switched.append(cell)
def handleMouseMotion(self, event):
row, column = self._eventCoords(event)
cell = self.grid[row][column]
if cell not in self.switched:
cell._switch()
cell.draw()
self.switched.append(cell)
if __name__ == "__main__" :
app = Tk()
grid = CellGrid(app, 50, 50, 10)
grid.pack()
app.mainloop()
And error:
NameError: name 'Canvas' is not defined
How can I change my code in order to runnig this in Python 2.7?
Well, it's not defined all right, I wonder how could it run on Py3, unless Tkinter there dumped Canvas into your namespace somehow.
You probably wanted to do class CellGrid(Tkinter.Canvas), but I don't remember the exact structure of Tkinter offhand, so it might be in a subpackage or something.
You need to import elements of module you want to use, in your case:
from Tkinter import Canvas, Tk
You can also do:
from Tkinter import *
but it is not recomended way of doing. Your code may not work right, if you use many modules, and they two of them happend to have same name of method.
Last way is just
import Tkinker
but then every time you use element of this module, you need to add full path so if you wanna use Canvas, you need to useTkinker.Canvas.
Also remember that in Python 2.7 you import Tkinter and in 3.X import tkinter

How to make an interactive 2D grid in a window in python?

I want to test some algorithms on path-finding and want to create a window consisting of grids where I can drag my mouse while clicked to create walls and delete them with right click and drag. I just started with computer science and am fascinated with the algorithms however i don't know how to create the interactive window for it.
The example grid can be viewed here:
A* pathfindind visualisation
Here come a solution. You can use the list of list of cells objects contained in the CellGrid.grid object to apply your pathfinding algorithm on. Have fun.
from tkinter import *
class Cell():
FILLED_COLOR_BG = "green"
EMPTY_COLOR_BG = "white"
FILLED_COLOR_BORDER = "green"
EMPTY_COLOR_BORDER = "black"
def __init__(self, master, x, y, size):
""" Constructor of the object called by Cell(...) """
self.master = master
self.abs = x
self.ord = y
self.size= size
self.fill= False
def _switch(self):
""" Switch if the cell is filled or not. """
self.fill= not self.fill
def draw(self):
""" order to the cell to draw its representation on the canvas """
if self.master != None :
fill = Cell.FILLED_COLOR_BG
outline = Cell.FILLED_COLOR_BORDER
if not self.fill:
fill = Cell.EMPTY_COLOR_BG
outline = Cell.EMPTY_COLOR_BORDER
xmin = self.abs * self.size
xmax = xmin + self.size
ymin = self.ord * self.size
ymax = ymin + self.size
self.master.create_rectangle(xmin, ymin, xmax, ymax, fill = fill, outline = outline)
class CellGrid(Canvas):
def __init__(self,master, rowNumber, columnNumber, cellSize, *args, **kwargs):
Canvas.__init__(self, master, width = cellSize * columnNumber , height = cellSize * rowNumber, *args, **kwargs)
self.cellSize = cellSize
self.grid = []
for row in range(rowNumber):
line = []
for column in range(columnNumber):
line.append(Cell(self, column, row, cellSize))
self.grid.append(line)
#memorize the cells that have been modified to avoid many switching of state during mouse motion.
self.switched = []
#bind click action
self.bind("<Button-1>", self.handleMouseClick)
#bind moving while clicking
self.bind("<B1-Motion>", self.handleMouseMotion)
#bind release button action - clear the memory of midified cells.
self.bind("<ButtonRelease-1>", lambda event: self.switched.clear())
self.draw()
def draw(self):
for row in self.grid:
for cell in row:
cell.draw()
def _eventCoords(self, event):
row = int(event.y / self.cellSize)
column = int(event.x / self.cellSize)
return row, column
def handleMouseClick(self, event):
row, column = self._eventCoords(event)
cell = self.grid[row][column]
cell._switch()
cell.draw()
#add the cell to the list of cell switched during the click
self.switched.append(cell)
def handleMouseMotion(self, event):
row, column = self._eventCoords(event)
cell = self.grid[row][column]
if cell not in self.switched:
cell._switch()
cell.draw()
self.switched.append(cell)
if __name__ == "__main__" :
app = Tk()
grid = CellGrid(app, 50, 50, 10)
grid.pack()
app.mainloop()

Categories