I have a very long automation that uses a very long WHILE loop. I would like to be able to have the text in a textbox update as the process is progressing. However, based on the research I have done, this does not seem to be possible and all of the results "dump" at once when the WHILE loop completes. This is useless for me.
I would love it if the textbox could update as the SHELL updates as that follows along synchronously with the actual process.
I have made a simple TEST file to see if I can get it to work. Here is the code for the TEST file:
from tkinter import *
import time
import tkinter as tk
import tkinter.font as tkFont
root=Tk()
myFont = tkFont.Font(family = 'Helvetica', size = 18, weight = 'bold')
text_cell_bg="cyan" #TEXT CELL BACKGROUND COLOR
text_cell_fg="black" #TEXT CELL TEXT COLOR
text_cell_height=2 #TEXT CELL HEIGHT
text_cell_width=30 #TEXT CELL WIDTH
button_bg="blue" #BUTTON CELL BACKGROUND COLOR
button_fg="white" #BUTTON CELL TEXT COLOR
button_height=2 #BUTTON CELL HEIGTH
button_width=10 #BUTTON CELL WIDTH
textbox=Text(root)
textbox.insert(END, 'Default Text\n\n')
def count_print ():
count = 0
letter = "A"
while count < 5:
print("Count = ",count,". Letter = ",letter,".")
textbox_value = "Count = {}. Letter = {}.\n".format(count,letter)
textbox.insert(1.0, textbox_value)
count += 1
time.sleep(1)
textbox.pack()
button1=tk.Button(root, text='output', command=count_print, font = myFont,
height=button_height,
width=button_width,
bg = button_bg,
fg = button_fg)
button1.pack()
root.mainloop()
You can call your function using Tkinter from inside the function itself.
Tkinter has a special function for this.
from tkinter import *
import time
import tkinter as tk
import tkinter.font as tk_font
root = Tk()
myFont = tk_font.Font(family='Helvetica', size=18, weight='bold')
text_cell_bg = "cyan" # TEXT CELL BACKGROUND COLOR
text_cell_fg = "black" # TEXT CELL TEXT COLOR
text_cell_height = 2 # TEXT CELL HEIGHT
text_cell_width = 30 # TEXT CELL WIDTH
button_bg = "blue" # BUTTON CELL BACKGROUND COLOR
button_fg = "white" # BUTTON CELL TEXT COLOR
button_height = 2 # BUTTON CELL HEIGHT
button_width = 10 # BUTTON CELL WIDTH
textbox = Text(root)
textbox.insert(END, 'Default Text\n\n')
def count_print(n_times=0): # tell your function how many times you have called it
(on the first call this will be 0)
n = n_times + 1
letter = "A"
if n <= 5:
print("Count = ", n, ". Letter = ", letter, ".")# you can change the n var on these lines to n_times if you want 0-4 rather than printing 1-5.
textbox_value = "Count = {}. Letter = {}.\n".format(n, letter)
textbox.insert(1.0, textbox_value)
root.after(1000, count_print, n) # this number replaces and time.sleep it's set to 1 second right now it also call the count_print function passing n as a variable
textbox.pack()
button1 = tk.Button(root, text='output', command=count_print, font=myFont,
height=button_height,
width=button_width,
bg=button_bg,
fg=button_fg)
button1.pack()
root.mainloop()
I hope this helps. also, I don't use Tkinter for my projects and am definitely not very good at using it either so credit for me knowing about root. after goes to this answer,
Make Tkinter force a "refresh" a text widget in mid-command?
Related
import tkinter as tk
from tkinter import *
root=tk.Tk()
root.geometry("720x1320")
root.title('Calculator')
root.resizable(0, 0)
root['background']='#444444'
def bclick(num):
global exp
exp= exp+str(num)
input.set(exp)
def bclear():
global exp
exp=""
input.set("")
def bequal():
global exp
result=str(eval(exp))
input.set(result)
exp=""
exp=""
input=StringVar()
input_frame = Frame(root, width = 312, height = 100, bd = 0, highlightbackground = "black", highlightcolor = "black", highlightthickness = 1)
input_frame.pack(side = TOP)
#label
dis=Entry(input_frame,textvariable=input,bg='#cccccc',fg='#000000',justify=RIGHT,font= ("sans-serif 16"))
dis.place(x=0,y=0)
dis.pack(ipady=197)
#0 row
bC=tk.Button(root,text='C',padx=166,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclear())
bC.place(x=0,y=479)
bX=tk.Button(root,text='X',padx=78,pady=40,fg='#FFFFFF',bg='#d21405',font=('sans-serif, 14'))
bX.place(x=360,y=479)
bdiv=tk.Button(root,text='÷',padx=78,pady=40,fg='#ffffff',font=('sans-serif, 14'),command=lambda:bclick("/"),bg='#1138be')
bdiv.place(x=540,y=479)
#1 row done
b7=tk.Button(root,text='7',padx=78,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("7"))
b7.place(x=0,y=631)
b8=tk.Button(root,text='8',padx=78,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("8"))
b8.place(x=180,y=631)
b9=tk.Button(root,text='9',padx=78,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("9"))
b9.place(x=360,y=631)
bmul=tk.Button(root,text='×',padx=78,pady=40,bg='#1138be',fg='#ffffff',font=('sans-serif, 14'),command=lambda:bclick("*"))
bmul.place(x=540,y=631)
#2 row
b4=tk.Button(root,text='4',padx=78,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("4"))
b4.place(x=0,y=783)
b5=tk.Button(root,text='5',padx=80,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("5"))
b5.place(x=180,y=783)
b6=tk.Button(root,text='6',padx=79,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("6"))
b6.place(x=360,y=783)
badd=tk.Button(root,text='+',padx=80,pady=40,bg='#1138be',fg='#ffffff',font=('sans-serif, 14'),command=lambda:bclick("+"))
badd.place(x=540,y=783)
#3row
b1=tk.Button(root,text='1',padx=78,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("1"))
b1.place(x=0,y=935)
b2=tk.Button(root,text='2',padx=78,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("2"))
b2.place(x=180,y=935)
b3=tk.Button(root,text='3',padx=78,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("3"))
b3.place(x=360,y=935)
bsub=tk.Button(root,text='-',padx=82,pady=40,bg='#1138be',fg='#ffffff',font=('sans-serif, 14'),command=lambda:bclick("-"))
bsub.place(x=540,y=935)
#4 row
b0=tk.Button(root,text='0',padx=165,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("0"))
b0.place(x=0,y=1087)
bdot=tk.Button(root,text='.',padx=85,pady=40,bg='#FFFFFF',font=('sans-serif, 14'),command=lambda:bclick("."))
bdot.place(x=360,y=1087)
bans=tk.Button(root,text='=',padx=80,pady=40,bg='#002366',fg='#ffffff',font=('sans-serif, 14'),command=lambda:bequal())
bans.place(x=540,y=1087)
root.mainloop()
The way I would do it is the same way you've done the last buttons instead of using the text='1' or a number just change it to text='backspace'.
As for the logic behind it since you have a global exp variable storing the maths equation created using the calculator you will need to remove the last bit of the equation added. i.e. if the equation was 12 + 15 + 17 - 20 you'd need to look through it and remove 20 because that was the last part of the equation. If they hit backspace again you'd need to remove the -.
So you're looking to create a function called bRemove() which removes the last part of your equation.
hint : to look at the last character in your string you can access it doing exp[len(exp)-1], you can check if this is a number and if it is you can remove it and look at the next element in the string (exp[len(exp)-2]) and then see if that is also a number.
[
also some general stack overflow advice to help you on your programming journey, it's better to be more specific about the help requested - some background information is nice and if you are going tto paste code you should use the ``` notation which lets you turn code into blocked code like this
block of code
]
Try this in my example.
from tkinter import *
#definging height and width of button.
button_height=1
button_width=3
#defining height and width of screen
screen_width =450
screen_height= 600
root=Tk()
root.title("SIMPLE CALCULATOR")
root.geometry(f"{screen_width}x{screen_height}")
root.maxsize(screen_width,screen_height)
root.minsize(screen_width,screen_height)
root.configure(background="gray")
scvalue=StringVar()
scvalue.set("")
#This defines the function for click event
def click_me(event):
value=event= event.widget.cget("text")
#print(value)
if value == "=":
try:
if scvalue.get().isdigit():
finalvalue= int(scvalue.get())
else:
finalvalue=eval(scvalue.get())
scvalue.set(finalvalue)
screen.update()
except:
scvalue.set(scvalue.get()[:-1])
screen.update()
elif value=="<=": #for backspace
scvalue.set(scvalue.get()[:-1])
screen.update()
elif value =="1/x": #for calculating reciprocal
if scvalue.get().isdigit():
val=int(scvalue.get())
scvalue.set(1/val)
screen.update()
else:
scvalue.set("Unknown error")
elif value== "C": #for clearing the screen.
scvalue.set("")
screen.update()
else:
scvalue.set(scvalue.get() +value)
screen.update()
screen= Entry(root,textvar=scvalue,font="lucida 40 bold" ,justify=RIGHT)
screen.pack(fill=X,padx=5,pady=5)
#list of all the inputs
valuelist=["/","%","C","<=","7","8","9","*","4","5","6","-","1","2","3","+","1/x","0",".","="]
#this loop
for i in range(20):
if i%4 == 0:
frame=Frame(root,bg="gray")
frame.pack()
b=Button(frame,text=valuelist[i],height=button_height,width=button_width,font="lucida 35 bold")
b.bind("<Button-1>",click_me)
b.pack(side=LEFT,padx=3,pady=3)
root.mainloop()
I wanted to create a table like below
The data from the rows is generated continuously . I want to create my table in such a way that rows are created dynamically . I wrote below code (Very new to tinkter, may be just 6 hours new) but the no data is inserted .
from scapy.all import *
from scapy.layers.http import HTTPRequest,HTTPResponse,HTTP # import HTTP packet
from tkinter import ttk
import tkinter as tk
def generateData():
sniff_packets()
def sniff_packets():
window.mainloop() # <<---The window loop
window.after(300, process_packet)
sniff(filter="port 80", prn=process_packet, iface="utun2", store=False)
def process_packet(packet):
print("Called to process_packet() ")
http_packet = str(packet)
if packet.haslayer(HTTP):
#if "www.xyz.com" in http_packet:
# print(http_packet)
if 'XYZ' in http_packet:
if HTTPRequest in packet:
http_request = packet[HTTPRequest]
insertDataDynamic((arrangePacket(str(http_request)))
if HTTPResponse in packet:
http_response = packet[HTTPResponse]
insertDataDynamic((arrangePacket(str(http_request)))
def insertDataDynamic(api_data):
print("Called to insertDataDynamic() ")
treev.insert("", 'end', text ="L1",
values =("DATA ", api_data, "HTTP"))
def arrangePacket(httpLayer):
ret = "***************************************GET PACKET****************************************************\n"
ret += "\n".join(httpLayer.split(r"\r\n"))
ret += "\n *****************************************************************************************************\n"
return ret
if __name__ == "__main__":
window = tk.Tk()
window.resizable(width = 1, height = 1)
treev = ttk.Treeview(window, selectmode ='browse')
treev.pack(side ='right')
# Constructing vertical scrollbar
# with treeview
verscrlbar = ttk.Scrollbar(window,
orient ="vertical",
command = treev.yview)
# Calling pack method w.r.to verical
# scrollbar
verscrlbar.pack(side ='right', fill ='x')
# Configuring treeview
treev.configure(xscrollcommand = verscrlbar.set)
# Defining number of columns
treev["columns"] = ("1","2","3")
# Defining heading
treev['show'] = 'headings'
# Assigning the width and anchor to the
# respective columns
treev.column("1", width = 500, anchor ='c')
treev.column("2", width = 500, anchor ='se')
treev.column("3", width = 500, anchor ='se')
# Assigning the heading names to the
# respective columns
treev.heading("1", text ="Name")
treev.heading("2", text ="Sex")
treev.heading("3", text ="Age")
generateData()
Also as soon as the mainloop starts ,the prn function of scapy doesn't work .
I put your function in the mainloop so it will be called when your gui is generated.
Also note that I put the after() method in your function so it will call itself every 300 ms.
from tkinter import ttk
import tkinter as tk
treev = None
window = None
def generateData(self):
#This is my API which makes a rest call and gets data
api_data = restcall()
insertDataDynamic(api_data)
window.after(300, generateData)
def insertDataDynamic(self,api_data):
treev.insert("", 'end', text ="L1",
values =(api_data.name, api_data.gender, api_data.age))
if __name__ == "__main__":
window = tk.Tk()
window.resizable(width = 1, height = 1)
treev = ttk.Treeview(window, selectmode ='browse')
treev.pack(side ='right')
# Constructing vertical scrollbar
# with treeview
verscrlbar = ttk.Scrollbar(window,
orient ="vertical",
command = treev.yview)
# Calling pack method w.r.to verical
# scrollbar
verscrlbar.pack(side ='right', fill ='x')
# Configuring treeview
treev.configure(xscrollcommand = verscrlbar.set)
# Defining number of columns
treev["columns"] = ("1","2","3")
# Defining heading
treev['show'] = 'headings'
# Assigning the width and anchor to the
# respective columns
treev.column("1", width = 500, anchor ='c')
treev.column("2", width = 500, anchor ='se')
treev.column("3", width = 500, anchor ='se')
# Assigning the heading names to the
# respective columns
treev.heading("1", text ="Name")
treev.heading("2", text ="Sex")
treev.heading("3", text ="Age")
generateData()
window.mainloop()
an exampel can be found here:
import tkinter as tk
def test():
print('test')
window.after(300, test)
window = tk.Tk()
test()
window.mainloop()
window.mainloop() will not end until you close the window. It allows to expose the GUI and process events.
There are several questions related to that topic. This one for instance: When do I need to call mainloop in a Tkinter application?
I am creating a GUI with a ".grid" of buttons. And I want to make each of those buttons display a different image on press. So when I click button 1, it will bring up "image1", on the bottom of the buttons. When I click button 2, it will bring up "image2" and etc.
Through some research, I was able to make the buttons run a function that takes in a parameter through the method below. However, I can't seem to make the button display the image. rather, it just makes an empty white space underneath the buttons, when I press any buttons.
Disclaimer:
- I do not want there to be loads of images, there will only be 1 image, and it will change depending on what button i press.
Here's the code:
from tkinter import *
def funct(numimg):
image = PhotoImage(file="image"+str(numimg)+".png")
label = Label(image=image)
label.grid(row = row_no+1, column = 0, columnspan = num_of_cols)
def make_funct(number):
return (lambda: funct(number))
root= Tk()
row_no = -1
buttons = []
num_of_cols = 3
root.resizable(0, 0)
numfiles = 6
for x in range(0, numfiles):
if(x % num_of_cols is 0):
row_no+=1
buttons.append(Button(root, text = "Button "+str(x), bg = '#4098D3', width = 30,height = 13,command = make_funct(x)))
buttons[x].grid(row = row_no, column = x % num_of_cols)
root.mainloop()
So my question is, how do you make each individual button, display a different image when it is pressed? this program right here just leaves an empty white space in replace of the image, and the image is not shown.
There are two major problems with the code you posted.
The first is basically the same as in this question: Why does Tkinter image not show up if created in a function?. You should keep a reference to the PhotoImage object, else it will be garbage collected and it will not show.
The second is that you create a new Label on every button click. You should only make one Label and change the image with the label.config() method.
I would (without wrapping your GUI in a class, which might be a nicer solution) load all images on initialization, save them in a list as attribute of the label and only change the image upon a button click.
I also removed your make_funct function and replaced it with a lambda, which is the most used way to pass variables to a function on callback.
from tkinter import *
def funct(numimg):
label.config(image=label.images[numimg])
root= Tk()
row_no = -1
buttons = []
num_of_cols = 3
root.resizable(0, 0)
numfiles = 3
for x in range(0, numfiles):
if(x % num_of_cols is 0):
row_no+=1
buttons.append(Button(root, text = "Button "+str(x), bg = '#4098D3', width = 30,height = 13, command = lambda n=x: funct(n)))
buttons[x].grid(row = row_no, column = x % num_of_cols)
label = Label(root)
label.grid(row = row_no+1, column = 0, columnspan = num_of_cols)
label.images=[]
for x in range(0, numfiles):
label.images.append(PhotoImage(file="image"+str(x)+".png"))
root.mainloop()
I have a Text widget that holds a custom string that contains \n chars (multiple lines).
The widget is placed within a vertical panedwindow which I want to adjust the panedwindow's sash to display the whole string in the Text widget.
The string is dynamic by nature (which means, it is being updated by other methods in my application).
As the Text widget is configured with wrap='word', how can I calculate the string height in pixels to adjust the sash accordingly?
I tried to use text.dlineInfo('end -1c')[1] + text.dlineinfo('end -1c')[3] (for line's y coordinate + height) after the string was loaded to the widget. The problem is that if the last line is not visible, then dlineinfo returns none.
I also tried to use Font.measure routine, but this doesn't include wrap aspects of the Text widget.
Here is a Minimal, Complete, and Verifiable example:
import tkinter
from tkinter import scrolledtext
class GUI():
def __init__(self, master):
self.master = master
self.body_frame = tkinter.PanedWindow(self.master, orient='vertical', sashwidth=4)
self.body_frame.pack(expand=1, fill='both')
self.canvas_frame = tkinter.Frame(self.body_frame)
self.description_frame = tkinter.Frame(self.body_frame)
self.body_frame.add(self.canvas_frame, sticky='nsew')
self.body_frame.add(self.description_frame, sticky='nsew')
tkinter.Button(self.canvas_frame, text='Update Text', command = lambda : self.update_text("""
A very long string with new lines
A very long string with new lines
A very long string with new lines
A very long string with new lines
A very long string with new lines
A very long string with new lines
""")).pack(fill='x')
self.field_description = scrolledtext.ScrolledText(self.description_frame, width=20, wrap='word')
self.field_description.pack(expand=1, fill='both')
self.master.update()
self.body_frame.sash_place(0,0,self.body_frame.winfo_height() - 50) # force sash to be lower
def update_text(self, description):
self.field_description.delete('1.0', 'end')
self.field_description.insert('1.0', description)
height = self.body_frame.winfo_height()
lastline_index = self.field_description.index('end - 1c')
text_height = self.field_description.dlineinfo(lastline_index)[1] + \
self.field_description.dlineinfo(lastline_index)[3]
self.body_frame.sash_place(0, 0, height - text_height)
root = tkinter.Tk()
my_gui = GUI(root)
root.mainloop()
I don't know of any built-in method that returns the total number of lines (including wrapped lines) in a tkinter Text widget.
However, you can manually calculate this number by comparing the lengths of the unbroken strings in the Text widget to the Text widget's exact width (minus padding). This is what the LineCounter class below does:
# python 2.x
# from tkFont import Font
# python 3.x
from tkinter.font import Font
class LineCounter():
def __init__(self):
"""" This class can count the total number of lines (including wrapped
lines) in a tkinter Text() widget """
def count_total_nb_lines(self, textWidget):
# Get Text widget content and split it by unbroken lines
textLines = textWidget.get("1.0", "end-1c").split("\n")
# Get Text widget wrapping style
wrap = text.cget("wrap")
if wrap == "none":
return len(textLines)
else:
# Get Text widget font
font = Font(root, font=textWidget.cget("font"))
totalLines_count = 0
maxLineWidth_px = textWidget.winfo_width() - 2*text.cget("padx") - 1
for line in textLines:
totalLines_count += self.count_nb_wrapped_lines_in_string(line,
maxLineWidth_px, font, wrap)
return totalLines_count
def count_nb_wrapped_lines_in_string(self, string, maxLineWidth_px, font, wrap):
wrappedLines_count = 1
thereAreCharsLeftForWrapping = font.measure(string) >= maxLineWidth_px
while thereAreCharsLeftForWrapping:
wrappedLines_count += 1
if wrap == "char":
string = self.remove_wrapped_chars_from_string(string,
maxLineWidth_px, font)
else:
string = self.remove_wrapped_words_from_string(string,
maxLineWidth_px, font)
thereAreCharsLeftForWrapping = font.measure(string) >= maxLineWidth_px
return wrappedLines_count
def remove_wrapped_chars_from_string(self, string, maxLineWidth_px, font):
avgCharWidth_px = font.measure(string)/float(len(string))
nCharsToWrap = int(0.9*maxLineWidth_px/float(avgCharWidth_px))
wrapLine_isFull = font.measure(string[:nCharsToWrap]) >= maxLineWidth_px
while not wrapLine_isFull:
nCharsToWrap += 1
wrapLine_isFull = font.measure(string[:nCharsToWrap]) >= maxLineWidth_px
return string[nCharsToWrap-1:]
def remove_wrapped_words_from_string(self, string, maxLineWidth_px, font):
words = string.split(" ")
nWordsToWrap = 0
wrapLine_isFull = font.measure(" ".join(words[:nWordsToWrap])) >= maxLineWidth_px
while not wrapLine_isFull:
nWordsToWrap += 1
wrapLine_isFull = font.measure(" ".join(words[:nWordsToWrap])) >= maxLineWidth_px
if nWordsToWrap == 1:
# If there is only 1 word to wrap, this word is longer than the Text
# widget width. Therefore, wrapping switches to character mode
return self.remove_wrapped_chars_from_string(string, maxLineWidth_px, font)
else:
return " ".join(words[nWordsToWrap-1:])
Example of use:
import tkinter as tk
root = tk.Tk()
text = tk.Text(root, wrap='word')
text.insert("1.0", "The total number of lines in this Text widget is " +
"determined accurately, even when the text is wrapped...")
lineCounter = LineCounter()
label = tk.Label(root, text="0 lines", foreground="red")
def show_nb_of_lines(evt):
nbLines = lineCounter.count_total_nb_lines(text)
if nbLines < 2:
label.config(text="{} line".format(nbLines))
else:
label.config(text="{} lines".format(nbLines))
label.pack(side="bottom")
text.pack(side="bottom", fill="both", expand=True)
text.bind("<Configure>", show_nb_of_lines)
text.bind("<KeyRelease>", show_nb_of_lines)
root.mainloop()
In your specific case, the height of the wrapped text in your ScrolledText can be determined in update_text() as follows:
from tkinter.font import Font
lineCounter = LineCounter()
...
class GUI():
...
def update_text(self, description):
...
nbLines = lineCounter.count_total_nb_lines(self.field_description)
font = Font(font=self.field_description.cget("font"))
lineHeight = font.metrics("linespace")
text_height = nbLines * lineHeight
...
You know the number of lines in your Text. And you can tell when a line is off the scrolled region when dlineinfo returns None. So go through each line and "see" it, to make sure it's visible before you run the dlineinfo() call on it. Then sum them all up, and that's the minimum new height you need for the lines to all appear at the current width. From the height of a line's bbox and the height of the biggest font in the line, you can determine if the line is wrapped, and if so, how many times, if you care about that. The trick is to then use paneconfig() to modify the height of the paned window. Even if the child window would resize automatically normally, the paned window will not. It must be told to resize through the paneconfig() call.
If you "see" each line before measuring, you'll get all the measurements. And "seeing" each line shouldn't be a big deal since you intend to show them all at the end anyway.
So, here is my code. Essentially, what I want to do is to make a label with the background color the same as the color chosen in the color dialog, so that the person can see the color and the color hexadecimal code. Please help.
import sys
from tkinter import *
from tkinter import colorchooser
mGui = Tk()
mGui.geometry("600x300+500+500")
mGui.title("Hexadecimal Color Chooser")
def getColor():
mycolor = colorchooser.askcolor()
label = Label(mGui, bg = mycolor).pack()
mycolor = str(mycolor)
start = mycolor.index("#")
stop = mycolor.index("')")
mycolor = mycolor[start:stop]
label = Label(mGui, text = "The hexadecimal color code is: " + mycolor).pack()
button = Button(mGui, text = "Choose a color", command = getColor).place(x=0, y=0)
There are three issues here:
Importing sys if you are not going to use it does nothing.
The place, pack, and grid methods of Tkinter widgets always return None. Hence, any calls to them should always be placed on their own line.
tkinter.colorchooser.askcolor returns a two-item tuple like this:
((128.5, 64.25, 64.25), '#804040')
Futhermore, the last item in this tuple is the hex code of the chosen color.
Below is a fixed version of the script:
from tkinter import *
from tkinter import colorchooser
mGui = Tk()
mGui.geometry("600x300+500+500")
mGui.title("Hexadecimal Color Chooser")
def getColor():
color_choice = colorchooser.askcolor()[1] # get the hex code
color = Label(mGui, bg=color_choice)
color.pack()
hexcode = Label(mGui, text="The hexadecimal color code is: "+color_choice)
hexcode.pack()
button = Button(mGui, text="Choose a color", command=getColor)
button.place(x=0, y=0)
mGui.mainloop()