1

I am trying to display a 2d list as CSV like structure in a new tkinter window

here is my code

import tkinter as tk
import requests
import pandas as pd
import numpy as np
from tkinter import messagebox
from finta import TA
from math import exp
import xlsxwriter
from tkinter import *
from tkinter.ttk import *
import yfinance as yf
import csv
from operator import itemgetter

def Createtable(root,rows):
        # code for creating table
        newWindow = Toplevel(root)
        newWindow.title("New Window")
     
        # sets the geometry of toplevel
        newWindow.geometry("600x600")

        for i in range(len(rows)):
            for j in range(3):
                  
                self.e = Entry(root, width=20, fg='blue',
                               font=('Arial',16,'bold'))
                  
                self.e.grid(row=i, column=j)
                self.e.insert(END, rows[i][j])

        Label(newWindow, text ="Results").pack()

This is my code for display the 2d list in a new window, here rows is the 2d list

This is how I am calling the function

def clicked():
    selected_stocks=[]
    converted_tickers=[]
    selected = box.curselection()
    for idx in selected:
        selected_stocks.append(box.get(idx))
    for i in selected_stocks:
        converted_tickers.append(name_to_ticker[i])
    rows=compute(converted_tickers)
    Createtable(app,rows)


btn = Button(app, text = 'Submit',command = clicked)
btn.pack(side = 'bottom')

rows works, I printed it out seperately and confirmed.

When I execute the program this is the error I receive

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
    return self.func(*args)
  File "pair.py", line 144, in clicked
    Createtable(app,rows)
  File "pair.py", line 31, in Createtable
    self.e = Entry(root, width=20, fg='blue',
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/tkinter/ttk.py", line 669, in __init__
    Widget.__init__(self, master, widget or "ttk::entry", kw)
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/tkinter/ttk.py", line 557, in __init__
    tkinter.Widget.__init__(self, master, widgetname, kw=kw)
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/tkinter/__init__.py", line 2567, in __init__
    self.tk.call(
_tkinter.TclError: unknown option "-fg"

I looked up the error and it says that this happens when you are using both old and new version of tkinter. I am not able to understand this as I am not using tk and ttk seperately anywhere in the Createtable function.

How can I solve this issue to display the 2d list on the new window?

For a reference I am attaching a screenshot here

enter image description here

UPDATE: Updated code as per comment

1)I commented out from tkinter.ttk import * 2)I also changed the Createtable function into a class like this

class Table:
      
    def __init__(self,root,rows):
        # code for creating table
        newWindow = Toplevel(root)
        newWindow.title("New Window")
     
        # sets the geometry of toplevel
        newWindow.geometry("600x600")

        for i in range(len(rows)):
            for j in range(3):
                  
                self.e=Entry(root, width=20, fg='blue',
                               font=('Arial',16,'bold'))
                  
                self.e.grid(row=i, column=j)
                self.e.insert(END, rows[i][j])

        Label(newWindow, text ="Results").pack()

Now, two errors are happening

1.The 2d list is showing on top of the main window instead of the new window.

2.After removing ttk the words on top of the button have become white for some reason. You can see in the picture attached below ( compare with the old picture, you will see "Submit" has become white)

How do I solve these?

Attaching picture for reference enter image description here

UPDATE 2: minimum reproducible code

import tkinter as tk
import requests
import pandas as pd
import numpy as np
from tkinter import messagebox
from finta import TA
from math import exp
import xlsxwriter
from tkinter import *
import tkinter.ttk as ttk
import yfinance as yf
import csv
from operator import itemgetter



class Table:
      
    def __init__(self,root,rows):
        # code for creating table
        newWindow = Toplevel(root)
        newWindow.title("New Window")
        # sets the geometry of toplevel
        newWindow.geometry("600x600")

        for i in range(len(rows)):
            for j in range(3):
                self.e=Entry(newWindow)
                  
                self.e.grid(row=i, column=j)
                self.e.insert(END, rows[i][j])

        Label(newWindow, text ="Results").pack()

#######################LIST TO DISPLAY##############

final_sorted_list=['Allahabad Bank', 'Andhra Bank', 'Axis Bank Limited','Bank of Baroda','Bank of India Limited']




########TKINTER##############################

app = Tk()
app.title('Test')
app.geometry("500x800")



def clicked():
    
    rows=[['Stock 1', 'Stock 2', 'Value'], ['AXISBANK.NS', 'MAHABANK.NS', 81.10000000000001], ['AXISBANK.NS', 'BANKINDIA.NS', 82.3], ['BANKBARODA.NS', 'MAHABANK.NS', 84.8], ['MAHABANK.NS', 'CANBK.NS', 85.5], ['BANKBARODA.NS', 'BANKINDIA.NS', 90.4], ['BANKINDIA.NS', 'CANBK.NS', 90.9], ['AXISBANK.NS', 'CANBK.NS', 91.5], ['AXISBANK.NS', 'BANKBARODA.NS', 93.30000000000001], ['BANKINDIA.NS', 'MAHABANK.NS', 95.8], ['BANKBARODA.NS', 'CANBK.NS', 97.6]]
    Table(app,rows)
    print("Finished")


box = Listbox(app, selectmode=MULTIPLE, height=4)
for val in final_sorted_list:
    box.insert(tk.END, val)
box.pack(padx=5,pady=8,side=LEFT,fill=BOTH,expand=True)

scrollbar = Scrollbar(app)
scrollbar.pack(side = RIGHT, fill = BOTH)

box.config(yscrollcommand = scrollbar.set)
# scrollbar.config(command = box.yview)

btn = ttk.Button(app, text = 'Submit',command = clicked)
btn.pack(side = 'bottom')

exit_button = ttk.Button(app, text='Close', command=app.destroy)
exit_button.pack(side='top')

clear_button = ttk.Button(app, text='Clear Selection',command=lambda: box.selection_clear(0, 'end'))
clear_button.pack(side='top')



app.mainloop()


If you run this, you get a frontend like in the picture above. You don't need to select anything as a sample result already has been hard coded in rows. The data in rows needs to be displayed in another window as a table. To recreate the error (new window not popping up) - you can just click on the "Submit" button, you don't need to select anything from the list.

alex deralu
  • 569
  • 1
  • 3
  • 18
  • The error is caused by importing everything from both tkinter and ttk. They both have a class called Label and it looks like ttk took priority and ttk Labels don't have the fg property, hence the error. To fix this, remove your global import for ttk. – Henry Jul 15 '21 at 20:50
  • @Henry I changed code according to your comment but got two new errors, can you please help me with those. Thank you. – alex deralu Jul 15 '21 at 21:13
  • To fix issue 1, change `self.e = Entry(root` to `self.e = Entry(newWindow`. – Henry Jul 15 '21 at 21:20
  • I'm not really sure what causes issue 2, but if you add `from tkinter import ttk` at the start and change `btn = Button` to `btn = ttk.Button` then that might fix it. – Henry Jul 15 '21 at 21:23
  • ok, this is a prime example of why You want to never import anything using wildcard, obviously some stuff You have made Yourself, in other words, You know the library well (made it or just know it), You can import using wildcard, otherwise You should avoid it for reasons like this: name clashes (maybe other reasons too, but nothing comes to mind now), so... import only what You need or import the module as a whole (basically don't use `from`) – Matiiss Jul 15 '21 at 21:35
  • @Henry Thanks a lot, issue 2 was solved. issue 1 I changed it to ``` new window``` but now it does not throw any error, but the mouse cursor changes to processing and the new window doesn't even open up. Is it because I am using ```grid``` and ```pack``` together? Do you know of a better approach I can take to this problem? – alex deralu Jul 15 '21 at 22:00
  • @alexderalu You should get an error for using grid and pack together, but it sounds like the program doesn't even get to that part. Are you getting any errors when you run it? – Henry Jul 16 '21 at 10:10
  • @Henry I have added a minimum reproducible code in the question. And also I added ```print()``` in various places in the ```Table``` class to see if the code was reaching there and they were all being printed. – alex deralu Jul 16 '21 at 12:08

2 Answers2

1

The problem update 2 is that you are using pack and grid in the same window. When I click submit the new window comes up (I couldn't reproduce that problem) but the word "results" is missing. This is because you are trying to use pack and grid on the same window. To fix this, show "results" using grid like this:

class Table:
      
    def __init__(self,root,rows):
        # code for creating table
        newWindow = Toplevel(root)
        newWindow.title("New Window")
        # sets the geometry of toplevel
        newWindow.geometry("600x600")
        Label(newWindow, text ="Results").grid(row = 0, column = 0, columnspan = 3)
        for i in range(len(rows)):
            for j in range(3):
                self.e=Entry(newWindow)
                  
                self.e.grid(row=i+1, column=j)
                self.e.insert(END, rows[i][j])

Because the "results" label is now in column 1 I've had to change self.e.grid to use row=i+1 so it displays properly. I also set the columnspan of the "results" label to 3 so it will be centered.

Henry
  • 3,472
  • 2
  • 12
  • 36
  • Do you know how can I include a vertical scrollbar in the new window? Since scrollbar is done with a ```pack``` like this ```v = Scrollbar(root) v.pack(side = RIGHT, fill = Y)``` – alex deralu Jul 16 '21 at 12:48
  • 1
    Scrollbars are a little more complicated than that. You have to make a canvas, then put the table in the canvas and the scrollbar next to the canvas. See [this answer](https://stackoverflow.com/a/3092341) for more information. – Henry Jul 16 '21 at 12:52
0

I've organized your imports. This should remove naming conflicts.

Note: You will have to declare tkinter objects with tk. and ttk objects with ttk. This should also help to remove naming conflicts.


import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

import requests
import csv
import pandas as pd
import numpy as np
import xlsxwriter
import yfinance as yf

from finta import TA
from math import exp
from operator import itemgetter

Derek
  • 1,916
  • 2
  • 5
  • 15