PyQt GridLayout combining widgets - pyqt

so for example, I have a GUI that has a label1+line_edit1, label2+line_edit2, button1, button2, button3. In a normal sense the code would look somewhat like this:
class gridlayout_example(QtGui.QWidget):
def __init__(self):
self.grid_layout = QtGui.QGridLayout()
self.label1 = QtGui.QLabel("label1")
self.grid_layout.addWidget(self.label1,0,0,1,3)
self.line_edit1 = QtGui.QLineEdit()
self.grid_layout.addWidget(self.line_edit1,1,0,1,3)
self.label2 = QtGui.QLabel("label2")
self.grid_layout.addWidget(self.label1,2,0,1,3)
self.line_edit2 = QtGui.QLineEdit()
self.grid_layout.addWidget(self.line_edit2,3,0,1,3)
self.button1 = QtGui.QPushButton("button1")
self.button2 = QtGui.QPushButton("button2")
self.button3 = QtGui.QPushButton("button3")
self.grid_layout.addWidget(self.button1, 4,0,1,1)
self.grid_layout.addWidget(self.button2, 4,1,1,1)
self.grid_layout.addWidget(self.button3, 4,2,1,1)
self.setLayout(self.grid_layout)
But is there a way to combine label1+line_edit1 and label2 + line_edit2 so it becomes something like:
[label1
line edit1 ] -> (0,0,1,3)
[label2
line edit2 ] -> (1,0,1,3)
[button1][button2][button3] -> (2,x,1,1)
so basically label1+line edit1 would occupy row 0 of the grid layout, label2 + line edit2 occupy row1 and so on...

Create a second layout to use as a sublayout, add your widgets to it, and use addLayout() in place of addWidget()
class gridlayout_example(QtGui.QWidget):
def __init__(self, parent=None):
super(gridlayout_example, self).__init__(parent)
label1 = QtGui.QLabel('label 1')
line_edit1 = QtGui.QLineEdit()
sublayout1 = QtGui.QVBoxLayout()
sublayout1.addWidget(label1)
sublayout1.addWidget(line_edit1)
label2 = QtGui.QLabel('label 2')
line_edit2 = QtGui.QLineEdit()
sublayout2 = QtGui.QVBoxLayout()
sublayout2.addWidget(label2)
sublayout2.addWidget(line_edit2)
button1 = QtGui.QPushButton("button1")
button2 = QtGui.QPushButton("button2")
button3 = QtGui.QPushButton("button3")
grid_layout = QtGui.QGridLayout(self)
grid_layout.addLayout(sublayout1, 0, 0, 1, 3)
grid_layout.addLayout(sublayout2, 1, 0, 1, 3)
grid_layout.addWidget(button1, 2, 0, 1, 1)
grid_layout.addWidget(button2, 2, 1, 1, 1)
grid_layout.addWidget(button3, 2, 2, 1, 1)

Related

Second window opened from button click on MainWindow shows but buttons are not clickable pyqt5

I'm developing a desktop application with pyqt5 and I'm trying to open a new window when a button in the MainWindow's application is clicked. The second window (a QWidget object) appears, but nothing in it is clickable (buttons, comboBoxes etc.). If I close the MainWindow the second window is still open and becomes clickable. Below the second window's code and the way I call it from the MainWindow (MainWindow's code is huge!).
Every help is more than welcome, thanks!
Second window:
from PyQt5 import QtCore, QtGui, QtWidgets
class Interaction:
def __init__(self):
self.wanted = False
self.interaction_type = None
self.chain = None
self.res_type = None
self.res_number = None
self.atom_name = None
def set_interaction_type(self, interaction_type):
self.interaction_type = interaction_type
def set_chain(self, chain):
self.chain = chain
def set_res_type(self, res_type):
self.res_type = res_type
def set_res_number(self, res_number):
self.res_number = res_number
def set_atom_name(self, atom_name):
self.atom_name = atom_name
def set_wanted(self, wanted):
if isinstance(wanted, bool):
self.wanted = wanted
class Ui_Form(QtWidgets.QWidget):
def __init__(self, list_of_available_items, parent):
super().__init__()
self.interactions_type = ['R', 'H', 'vdW']
self.items = list_of_available_items
self.filter = Interaction()
self.setupUi()
self.setFocusPolicy(QtCore.Qt.StrongFocus)
# self.show()
def setupUi(self):
self.setObjectName("Form")
self.resize(542, 128)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
self.setSizePolicy(sizePolicy)
self.gridLayout = QtWidgets.QGridLayout(self)
self.gridLayout.setObjectName("gridLayout")
self.interactionTypeLabel = QtWidgets.QLabel(self)
self.interactionTypeLabel.setFocusPolicy(QtCore.Qt.NoFocus)
self.interactionTypeLabel.setObjectName("interactionTypeLabel")
self.gridLayout.addWidget(self.interactionTypeLabel, 0, 0, 1, 2)
self.interactionTypeComboBox = QtWidgets.QComboBox(self)
self.interactionTypeComboBox.setObjectName("interactionTypeComboBox")
self.gridLayout.addWidget(self.interactionTypeComboBox, 0, 2, 1, 2)
self.wantedRadioButton = QtWidgets.QRadioButton(self)
self.wantedRadioButton.setObjectName("wantedRadioButton")
self.gridLayout.addWidget(self.wantedRadioButton, 0, 4, 1, 1)
self.unwantedRadioButton = QtWidgets.QRadioButton(self)
self.unwantedRadioButton.setObjectName("unwantedRadioButton")
self.gridLayout.addWidget(self.unwantedRadioButton, 0, 5, 1, 1)
self.interactionChainLabel = QtWidgets.QLabel(self)
self.interactionChainLabel.setObjectName("interactionChainLabel")
self.gridLayout.addWidget(self.interactionChainLabel, 1, 0, 1, 1)
self.interactionResTypeLabel = QtWidgets.QLabel(self)
self.interactionResTypeLabel.setObjectName("interactionResTypeLabel")
self.gridLayout.addWidget(self.interactionResTypeLabel, 1, 1, 1, 2)
self.interactionResNLabel = QtWidgets.QLabel(self)
self.interactionResNLabel.setObjectName("interactionResNLabel")
self.gridLayout.addWidget(self.interactionResNLabel, 1, 3, 1, 1)
self.interactionAtomNameLabel = QtWidgets.QLabel(self)
self.interactionAtomNameLabel.setObjectName("interactionAtomNameLabel")
self.gridLayout.addWidget(self.interactionAtomNameLabel, 1, 4, 1, 2)
self.interactionChainComboBox = QtWidgets.QComboBox(self)
self.interactionChainComboBox.setObjectName("interactionChainComboBox")
self.gridLayout.addWidget(self.interactionChainComboBox, 2, 0, 1, 1)
self.interactionResTypeComboBox = QtWidgets.QComboBox(self)
self.interactionResTypeComboBox.setObjectName("interactionResTypeComboBox")
self.gridLayout.addWidget(self.interactionResTypeComboBox, 2, 1, 1, 2)
self.interactionResNComboBox = QtWidgets.QComboBox(self)
self.interactionResNComboBox.setObjectName("interactionResNComboBox")
self.gridLayout.addWidget(self.interactionResNComboBox, 2, 3, 1, 1)
self.interactionAtomNameComboBox = QtWidgets.QComboBox(self)
self.interactionAtomNameComboBox.setObjectName("interactionAtomNameComboBox")
self.gridLayout.addWidget(self.interactionAtomNameComboBox, 2, 4, 1, 2)
self.interactionDialogButtonBox = QtWidgets.QDialogButtonBox(self)
self.interactionDialogButtonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.interactionDialogButtonBox.setObjectName("interactionDialogButtonBox")
self.gridLayout.addWidget(self.interactionDialogButtonBox, 3, 4, 1, 2)
self.retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self)
self.interactionTypeComboBox.currentIndexChanged.connect(self.set_interaction_type)
self.wantedRadioButton.clicked.connect(self.set_filter_wanted)
self.unwantedRadioButton.clicked.connect(self.set_filter_unwanted)
# DEFAULTS
self.populate_interactions_type()
self.wantedRadioButton.click()
# CLASS METHODS
def populate_interactions_type(self):
for interaction in self.interactions_type:
self.interactionTypeComboBox.addItem(interaction)
def set_interaction_type(self):
self.filter.set_interaction_type(self.interactionTypeComboBox.currentText())
def set_filter_wanted(self):
if self.wantedRadioButton.isChecked():
self.filter.set_wanted(True)
else:
self.filter.set_wanted(False)
def set_filter_unwanted(self):
if self.unwantedRadioButton.isChecked():
self.filter.set_wanted(False)
else:
self.filter.set_wanted(True)
def get_interaction_obj(self):
return self.filter
def retranslateUi(self):
self.interactionTypeLabel.setText("Select interaction type:")
self.wantedRadioButton.setText("Enable")
self.unwantedRadioButton.setText("Disable")
self.interactionChainLabel.setText("Chain:")
self.interactionResTypeLabel.setText("Res Type:")
self.interactionResNLabel.setText("Res #:")
self.interactionAtomNameLabel.setText("Atom Name:")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ui = Ui_Form(list(), QtWidgets.QMainWindow)
ui.show()
sys.exit(app.exec_())
Second window's call from MainWindow:
def add_interaction(self):
self.interaction_ui = Ui_Form(list(), self)
self.interaction_ui.show()
All right, after two days I found the bug thanks to #musicamante 's comment. I tried to create a new MainWindow with just a button to open the second window and everything worked so I tried to traceback the problem comparing the two MainWindow's code and it turned out that in the original one I set the MainWindow.setWindowModality(QtCore.Qt.ApplicationModal), this apparently blocked the focus to go on the second window.

How can I scroll multiple frames in canvas?

I want to create a list of frames with further features like a button, label e.g.. but my issues are the size of the LabelFrame. If I put the LabelFrame in container it fits like I want to but it isn't scrollable any more. Any ideas?
from tkinter import ttk
import tkinter as tk
root = tk.Tk()
container = ttk.Frame(root)
canvas = tk.Canvas(container)
scrollbar = ttk.Scrollbar(container, orient="vertical", command=canvas.yview)
scrollable_frame = ttk.Frame(canvas)
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(
scrollregion=canvas.bbox("all")
)
)
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
for i in range(50):
lf = ttk.Frame(scrollable_frame, text=i).grid(column=1, row=i)
frame_ip = tk.LabelFrame(lf, bg="white", text=i)
frame_ip.place(relwidth=0.95, relheight=0.2, relx=0.025, rely=0)
button_scroll1 = tk.Button(frame_ip, text="Start", bg="grey")
button_scroll1.place(relwidth=0.15, relx=0.025, relheight=0.15, rely=0.1)
container.pack()
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
root.mainloop()
Here is your updated code with a Button, Canvas and Scrollbar inserted into each LabelFrame with grid manager.
I've also made the container resizable with row|column configure.
Seems to work fine.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.rowconfigure(0, weight = 1)
root.columnconfigure(0, weight = 1)
root.geometry("341x448")
container = ttk.Frame(root)
container.rowconfigure(0, weight = 1)
container.columnconfigure(0, weight = 1)
canvas = tk.Canvas(container)
scrollbar = ttk.Scrollbar(container, orient = tk.VERTICAL, command = canvas.yview)
scrollable_frame = ttk.Frame(canvas)
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(
scrollregion=canvas.bbox("all")))
canvas.create_window((0, 0), window = scrollable_frame, anchor = tk.NW)
canvas.configure(yscrollcommand = scrollbar.set)
for i in range(15):
L = ttk.LabelFrame(scrollable_frame, text = "Sample scrolling label")
L.grid(row = i, column = 0, sticky = tk.NSEW)
B = ttk.Button( L, text = f"Button {i}")
B.grid(row = 0, column = 0, sticky = tk.NW)
K = tk.Canvas(
L, width = 300, height = 100,
scrollregion = "0 0 400 400", background = "#ffffff")
K.grid(row = 1, column = 0, sticky = tk.NSEW)
S = ttk.Scrollbar( L, command = K.yview)
S.grid(column = 1, row = 1, sticky = tk.NSEW)
K["yscrollcommand"] = S.set
container.grid(row = 0, column = 0, sticky = tk.NSEW)
canvas.grid(row = 0, column = 0, sticky = tk.NSEW)
scrollbar.grid(row = 0, column = 1, sticky = tk.NS)
root.mainloop()

tkinter scrollbar with grid, it doesn't get linked

I'm studying GUI, so please understand my poor codes below.
I was trying to make a program which gets game-character's information. So if you press the 'search' button, the list would be shown below. But... it only shows about 11 names due to the window size. So i wanted to put a scrollbar for that area, but I just don't know how to link the scroll bar to control the area. I meant, the scroll bar itself has created, and it does scroll itself, but it doesn't scroll the window I wanted. I must have linked it wrong but... not sure.
Below is the minimized example code, but it's still quite long and crude. Sorry for that again.
If anyone can enlighten me, it would be really great help for this and my future works as well.
import tkinter as tk
import requests
from bs4 import BeautifulSoup
import webbrowser
import time
global var_dict, input_id, output
var_dict = {}
def enter_call_back(event=None):
output.grid(column = 0, row = 2, columnspan = 5 , sticky='w')
output.insert(tk.END,"Text_Something")
output.update()
search_chr()
def open_browse(url_list):
for url in url_list:
time.sleep(0.3)
webbrowser.open(url)
def search_inven(ch_id):
if ch_id == "ch1" or ch_id == "ch13" or ch_id == "ch15" :
num = 5
url_list = ["something.url","something2.url"]
self_count = 1
else:
num = 0
url_list = []
self_count = 0
masterset = []
masterset.append(num)
masterset.append(url_list)
masterset.append(self_count)
return masterset
def search_chr():
global var_dict, output
for things in var_dict.keys():
var_dict[things].destroy()
chr_list = ["ch1","ch2","ch3","ch4","ch5","ch6","ch7","ch8","ch9","ch9","ch10","ch11","ch12","ch13","ch14","ch15"]
output.insert(tk.END," Done! \n\n")
var_dict = {}
num = -1
for ch in chr_list:
num += 1
var_dict["output%s" %num] = tk.Entry(frame_buttons, width = 125)
result = search_inven(ch)
if result[0] == 0:
var_dict["output"+str(num)].insert(0, "Clean "+ch+"\n")
var_dict["output"+str(num)].grid(column = 0, row = num, sticky='w', padx=5, pady=5)
else:
url_list = result[1]
var_dict["o-button%s" %num] = tk.Button(frame_buttons, command=lambda url_list = url_list : open_browse(url_list))
var_dict["o-button"+str(num)].grid(column = 1, row = num, sticky='e')
var_dict["o-button"+str(num)].config(text="URL")
var_dict["output"+str(num)].insert(0, "Not Clean "+str(result[0])+" Self : "+str(result[2])+" Ch_id : "+ch+")\n")
var_dict["output"+str(num)].grid(column = 0, row = num, sticky='w', padx=5, pady=5)
vsb = tk.Scrollbar(frame_canvas, orient="vertical")
vsb.grid(row=0, column=1, sticky='ns')
vsb.config(command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
frame_canvas.config(height = 300)
canvas.config(scrollregion=canvas.bbox("all"))
root = tk.Tk()
root.geometry("760x710")
root.resizable(width=False, height=False)
root.title("Minimum v.1.2")
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frame_main = tk.Frame(root, bg="gray")
frame_main.grid(sticky='news')
intro = tk.Text(frame_main, height = 17, bg="#E3D5F3")
intro.option_add("*Font", "명조 10")
intro.insert(tk.CURRENT,"Text_something")
intro.config(state='disabled')
intro.grid(row=0, column=0, pady=(5, 0), columnspan = 5, sticky='nw')
input_id = tk.Entry(frame_main, width = 35)
input_id.option_add("*Font","명조 10")
input_id.insert(0,"Ch_name")
input_id.grid(row=1, column=0, pady=(5, 0), sticky='w')
search_btn = tk.Button(frame_main)
search_btn.config(text="Search")
search_btn.option_add("*Font","명조 10")
search_btn.config(width=5,height=1)
search_btn.grid(row = 1, column = 0, pady=(5, 0), sticky='e')
output = tk.Text(frame_main, height = 10)
output.option_add("*Font","명조 10")
output.grid(row = 2, column = 0,pady=(5,0),sticky='nw')
frame_canvas = tk.Frame(frame_main, width = 565)
frame_canvas.grid(row=3, column=0, pady=(5, 0), columnspan = 3 ,sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
frame_canvas.grid_propagate(False)
canvas = tk.Canvas(frame_canvas, bg="gray", height=500,scrollregion=(0,0,500,1800))
canvas.grid(row=0, column=0, sticky="news")
frame_buttons = tk.Frame(canvas, bg="gray")
frame_buttons.grid(row = 0, column = 0,sticky='e')
root.bind('<Return>',enter_call_back)
search_btn.config(command = enter_call_back)
root.mainloop()
First, using grid() to put frame_buttons into the canvas will not affect the scrollregion of the canvas. Use canvas.create_window() instead.
Second, it is better to bind <Configure> event on frame_buttons and update canvas' scrollregion inside the bind callback. Then adding widgets to frame_buttons will automatically update the scrollregion.
Also note that you have created new scrollbar and put it at same position whenever search_chr() is executed. Better create the scrollbar only once outside the function.

Python 3 tkinter insert file contents into a text box

Okay so I have done about 10 days of searching and I caved in so I'm turning to the community for help.
I am using python 3.6 and tkinter as a user interface.
The basic's of what I'm trying to accomplish is that I have a file that I open and search for a word within the file and insert all the lines that word falls on.
My issue is that its only inserting the first line it finds and I need it to insert all the lines it finds. Sorry for wet coding I'll dry it up once I have functionality later
here's a sample of my code (it's not the full thing but it should give you more than enough info about what I'm trying to accomplish):
import tkinter as tk
from tkinter import ttk
# i added all my imports that this class use's in case you guys think they could pose a problem but they shouldn't be a issue
class EXAMPLEapp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.iconbitmap(self, default = "dlm64.ico")
tk.Tk.wm_title(self, "Example.")
self.FILE_MENU_BAR()
self.minsize(width = 360, height = 200)
container = tk.Frame(self)
container.grid(row=0,column=0, sticky="nsew")
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
self.frames = {}
for FRAME in (SearchPage):
frame = FRAME(container, self)
self.frames[FRAME] = frame
frame.grid(row = 0, column = 0, sticky = "nsew")
self.show_frame(SearchPage)
def FILE_MENU_BAR(self):
#File
self.menubar = tk.Menu()
self.configure(menu = self.menubar)
File_Menu = tk.Menu(self.menubar, tearoff = False)
self.menubar.add_cascade(label = "File", menu = File_Menu)
File_Menu.add_command(label = "EXIT" , command = self.File_EXIT)
# Edit Menu
Edit_Menu = tk.Menu(self.menubar, tearoff = False)
self.menubar.add_cascade(label = "Edit", menu = Edit_Menu)
Edit_Menu.add_command(label = "cut", underline = 2, command = self.Edit_Cut)
Edit_Menu.add_command(label = "copy", underline = 0, command = self.Edit_Copy)
def File_EXIT(self):
sys.exit(0)
def Edit_Cut(self):
print("CUT")
def Edit_Copy(self):
print("COPY")
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class SearchPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text = "Search Inventory", font = ("Helvetica", 20, 'bold', 'underline'))
label.grid(row = 0, column = 1, sticky = "nsew", pady = (0,0), padx = (0,0))
button0 = ttk.Button(self, text = "Inventory Search")
button0.grid(row = 0, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
button1 = ttk.Button(self, text = "New Inventory", command = lambda: controller.show_frame(CreatePage))
button1.grid(row = 1, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
button2 = ttk.Button(self, text = "Edit Invetory", command = lambda: controller.show_frame(EditPage))
button2.grid(row = 2, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
button3 = ttk.Button(self, text = "Ship", command = lambda: controller.show_frame(ShipPage))
button3.grid(row = 3, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
button4 = ttk.Button(self, text = "Graph", command = lambda: controller.show_frame(PlotPage))
button4.grid(row = 4, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
DATE_VAR = tk.StringVar()
def DATE_SEARCH():
USER_TEXT = DATE_VAR.get()
with open('SAMPLE.txt', 'r') as searchfile:
for line in searchfile:
if USER_TEXT == '':
LABEL = tk.Text(self, width = 30, height = 2, wrap = tk.WORD, foreground = 'red')
LABEL.grid(row = 6, column = 3, sticky = "nsew", pady = (0,0), padx = (20,0))
LABEL.insert(1.0, "PLEASE ENTER A VALUE")
LABEL.configure(state = 'disabled')
break
elif USER_TEXT in line:
LABEL = tk.Text(self, width = 100, height = 4, wrap = tk.WORD)
LABEL.grid(row = 6, column = 3, sticky = "e", pady = (0,0), padx = (20,0))
LABEL.insert(1.0, line)
LABEL.configure(state = 'disabled')
ScrollBar = tk.Scrollbar(self)
ScrollBar.config(command = LABEL.yview)
LABEL.config(yscrollcommand = ScrollBar.set)
ScrollBar.grid(row = 6, column = 4, sticky = "e")
break
else:
LABEL = tk.Text(self, width = 30, height = 2, wrap = tk.WORD, foreground = 'red')
LABEL.grid(row = 6, column = 3, sticky = "nsew", pady = (0,0), padx = (20,0))
LABEL.insert(1.0, "INVENTORY DOES NOT EXIST")
LABEL.configure(state = 'disabled')
DATE_Search_label = tk.Label(self, text = "Search by DATE", font = ("Helvetica", 9))
DATE_Search_label.grid(row = 5, column = 1, sticky = "nsew")
DATE_Search_Entry = tk.Entry(self, textvariable = DATE_VAR)
DATE_Search_Entry.grid(row = 6, column = 1, sticky = "nsew", pady = 0, padx = 2)
DATE_SEARCH_BUTTON = ttk.Button(self, text = "Search", command = DATE_SEARCH)
DATE_SEARCH_BUTTON.grid(row = 6, column = 2, sticky = "nsew")
app = EXAMPLEapp()
app.mainloop()
EDIT:
I have made several changes to your code.
There were way too many emblems with the way you had it set up.
As I am not 100% sure how what you are trying to accomplish I have made progress with your code.
Below is the edited version of your code.
I also created a text file on my end to test with and it seams to have worked so let me know if this is getting close to what you are attempting to do.
A few notes:
1st I moved everything into one class. The way you had it set up was just not going to work without some major changes.
2nd I needed to add self. to many of your variables because they are variables that we need to interact with in the class.
3rd I changed they way you get the data from the entry box. The way you were doing it was just not working so I simplified it by adding .get() function to the entry variable.
4th but probably should have been the 1st thing I mentions. The way you had your main Tk() window starting was odd. I changed how root was created and how we pass it into the class. This seams to make more sense to me.
This is much better to use IMO.
Let me know what parts you still need explanation on and I will make updates to my answer as needed.
Update:
change the while open statement a bit. You do not need to recreate the text box and reconfigure it ever for loop this is not good and will prevent you from seeing multiple items. Also I do not believe you can have a multi line label thought I have never tried. Lets change this to a text box this should do what we need.
import tkinter as tk
from tkinter import ttk
class EXAMPLEapp(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.root = parent
self.root.wm_title("TM Duch\'e Nut CO.")
self.FILE_MENU_BAR()
self.root.minsize(width = 360, height = 200)
self.container = tk.Frame(self.root)
self.container.grid(row=0,column=0, sticky="nsew")
self.container.grid_rowconfigure(0, weight = 1)
self.container.grid_rowconfigure(6, weight = 0)
self.container.grid_columnconfigure(0, weight = 1)
self.container.grid_columnconfigure(3, weight = 0)
self.label = tk.Label(self.root, text = "Search Inventory", font = ("Helvetica", 20, 'bold', 'underline'))
self.label.grid(row = 0, column = 1, sticky = "nsew", pady = (0,0), padx = (0,0))
self.button0 = ttk.Button(self.root, text = "Inventory Search")
self.button0.grid(row = 0, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
self.button1 = ttk.Button(self.root, text = "New Inventory", command = lambda: controller.show_frame(CreatePage))
self.button1.grid(row = 1, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
self.button2 = ttk.Button(self.root, text = "Edit Invetory", command = lambda: controller.show_frame(EditPage))
self.button2.grid(row = 2, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
self.button3 = ttk.Button(self.root, text = "Ship", command = lambda: controller.show_frame(ShipPage))
self.button3.grid(row = 3, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
self.button4 = ttk.Button(self.root, text = "Graph", command = lambda: controller.show_frame(PlotPage))
self.button4.grid(row = 4, column = 0, sticky = "nsew", pady = 0, padx = (0,10))
self.DATE_Search_label = tk.Label(self.root, text = "Search by DATE", font = ("Helvetica", 9))
self.DATE_Search_label.grid(row = 5, column = 1, sticky = "nsew")
self.DATE_Search_Entry = tk.Entry(self.root)
self.DATE_Search_Entry.grid(row = 6, column = 1, sticky = "nsew", pady = 0, padx = 2)
self.DATE_SEARCH_BUTTON = ttk.Button(self.root, text = "Search", command = lambda: self.DATE_SEARCH())
self.DATE_SEARCH_BUTTON.grid(row = 6, column = 2, sticky = "nsew")
def DATE_SEARCH(self):
with open('SAMPLE.txt', 'r') as f:
search_f = f.readlines()
self.text = tk.Text(self.root, width = 30, height = 2)
self.text.grid(row = 6, column = 3, sticky = "ew", pady = (0,0), padx = (20,0))
self.ScrollBar = tk.Scrollbar(self.root)
self.ScrollBar.config(command = self.text.yview)
self.text.config(yscrollcommand = self.ScrollBar.set)
self.ScrollBar.grid(row = 6, column = 4, sticky = "ns")
self.text.delete(1.0, "end-1c")
USER_TEXT = self.DATE_Search_Entry.get()
if USER_TEXT == '':
self.text.config(foreground = 'red')
self.text.insert(tk.END, "PLEASE ENTER A VALUE")
else:
match_in_file = False
for line in search_f:
if USER_TEXT in line:
self.text.config(foreground = 'black')
self.text.insert(tk.END, "{}".format(line))
match_in_file = True
if match_in_file == False:
self.text.config(foreground = 'red')
self.text.insert(tk.END, "INVENTORY DOES NOT EXIST")
def FILE_MENU_BAR(self):
#File
self.menu = tk.Menu(self.root)
self.root.config(menu = self.menu)
self.fileMenu = tk.Menu(self.menu, tearoff = 0)
self.menu.add_cascade(label = "File", menu = self.fileMenu)
self.fileMenu.add_separator()
self.fileMenu.add_command(label = "Exit", command = lambda: self.root.destroy())
# Edit Menu
self.Edit_Menu = tk.Menu(self.menu)
self.menu.add_cascade(label = "Edit", menu = self.Edit_Menu)
self.Edit_Menu.add_command(label = "cut", underline = 2, command = self.Edit_Cut)
self.Edit_Menu.add_command(label = "copy", underline = 0, command = self.Edit_Copy)
def File_EXIT(self):
sys.exit(0)
def Edit_Cut(self):
print("CUT")
def Edit_Copy(self):
print("COPY")
root = tk.Tk()
app = EXAMPLEapp(root)
app.mainloop()

tkinter report frame as well as mouse coordinates

def mouse_click(event):
#'reports' to both terminal and results text box
parent_name = Frame.winfo_parent(root)
parent = Frame._nametowidget(parent_name)
result = ("{0}: {1},{2}\n ".format('Clicked at', event.x, event.y))
print('clicked at',parent, event.x, event.y)
from tkinter import *
root = Tk()
root.title("Change Text")
root.geometry('700x500')
top=root.winfo_toplevel()
for rn in range(0,9): # rn = row number
top.rowconfigure(rn, weight=1)
top.rowconfigure(rn, weight=0)
for cn in range(0,5): # cn = column number
top.columnconfigure(cn, weight=1)
# FRAME 1
frame1 = Frame(root, borderwidth = 2, background = '#EFE0CD', relief = RIDGE,width = 25, height = 20)
frame1.bind("<Button-1>", mouse_click)
frame1.grid(column = 0, row = 0, columnspan = 2, rowspan = 3, sticky = N+S+E+W)
frame1_lbl = Label(frame1, text='Frame 1', font='comic-sans-MS 10 ', fg ='red', bg = '#EFE0CD')
frame1_lbl.grid(row=0, column =0)
# FRAME 2
frame2 = Frame(root, borderwidth = 2, background = '#CCC6B0', relief = RIDGE,width = 25, height = 20)
frame2.bind("<Button-1>", mouse_click)
frame2.grid(column = 0, row = 3, columnspan = 2, rowspan = 3, sticky = N+S+E+W)
frame2_lbl = Label(frame2, text='Frame 2', font='comic-sans-MS 10', fg ='red', bg = '#CCC6B0')
frame2_lbl.grid(row=0, column =0,)
root.mainloop()
I know that this is a really dumb question. How do I identify the Frame in which the mouse is clicked so that report prints clicked frame1 or frame2 at x y coordinates?. I found a bit about using winfo_parent but have obviously not used it properly.
Thank you
The event object that is passed in to the callback has a widget attribute which is a reference to the widget that got the event. So, event.widget is what you want to print.

Resources