Resizing both height and width textInput in kivy - python-3.x

<AutoResizedText>
GridLayout:
cols:1
size: root.width, root.height
TextInput:
multiline:True
size_hint:(None,None)
size:(self.height,self.minimum_height )
text: "hello my cat"
I'm currently trying to get a TextInput that expands in width and height based upon what string it contains within it. I've been able to get the height to expand alongside the text. But not the width for some reason. self.minimum_width does not appear to be a method when I try to replace self.height with self.minimum_height

The TextInput can't do what you want without some modifications. The standard TextInput needs you to set the width, then it will fill its text field, splitting the text as needed to keep it to that width, and calculating a minimum_height based on that.
Here is a version of TextInput that I have modified to do what I think you want:
class MyTextInput(TextInput):
minimum_width = NumericProperty(0)
def _split_smart(self, text):
# modified to always split on newline only
lines = text.split(u'\n')
lines_flags = [0] + [FL_IS_LINEBREAK] * (len(lines) - 1)
return lines, lines_flags
def _refresh_text(self, text, *largs):
# this is modified slightly just to calculate minimum_width
# Refresh all the lines from a new text.
# By using cache in internal functions, this method should be fast.
mode = 'all'
if len(largs) > 1:
mode, start, finish, _lines, _lines_flags, len_lines = largs
# start = max(0, start)
cursor = None
else:
cursor = self.cursor_index()
_lines, self._lines_flags = self._split_smart(text)
_lines_labels = []
_line_rects = []
_create_label = self._create_line_label
# calculate minimum width
min_width = 0
for x in _lines:
lbl = _create_label(x)
min_width = max(min_width, lbl.width)
_lines_labels.append(lbl)
_line_rects.append(Rectangle(size=lbl.size))
self.minimum_width = min_width + self.padding[0] + self.padding[2]
if mode == 'all':
self._lines_labels = _lines_labels
self._lines_rects = _line_rects
self._lines = _lines
elif mode == 'del':
if finish > start:
self._insert_lines(start,
finish if start == finish else (finish + 1),
len_lines, _lines_flags,
_lines, _lines_labels, _line_rects)
elif mode == 'insert':
self._insert_lines(
start,
finish if (start == finish and not len_lines)
else (finish + 1),
len_lines, _lines_flags, _lines, _lines_labels,
_line_rects)
min_line_ht = self._label_cached.get_extents('_')[1]
# with markup texture can be of height `1`
self.line_height = max(_lines_labels[0].height, min_line_ht)
# self.line_spacing = 2
# now, if the text change, maybe the cursor is not at the same place as
# before. so, try to set the cursor on the good place
row = self.cursor_row
self.cursor = self.get_cursor_from_index(self.cursor_index()
if cursor is None else cursor)
# if we back to a new line, reset the scroll, otherwise, the effect is
# ugly
if self.cursor_row != row:
self.scroll_x = 0
# with the new text don't forget to update graphics again
self._trigger_update_graphics()
def on_text(self, *args):
# added to update minimum width on each change
cc, cr = self.cursor
text = self._lines[cr]
lbl = self._create_line_label(text)
self.minimum_width = max(self.minimum_width, lbl.width + self.padding[0] + self.padding[2])
This version of TextInput has a minimum_width property. I have modified _smart_split() so that it only splits lines on newlines. The _refresh_text() is almost identical to the original, but includes a calculation of minimum_width. I added a on_text() method to update minimum_width each time the text changes. So, now you can use self.minimum_width and self.minimum_height to size the Widget as:
MyTextInput:
multiline: True
size_hint:(None,None)
size:(self.minimum_width, self.minimum_height)
text: "hello my cat"

Related

Tkinter image_create performance when inserting image into text box

I'm building a Python (3.7.4) app to display items from a text database of vendor manuals. One of the functions is to display a list of "item names" from the database for each manual (aka "product"). I'm using a Tkinter scrolled text box widget for this function and simply building rows with item names with tabs to separate them. I would like to insert a small icon (16x20 pixels) in front of each item name, and have successfully done so using the code below. The problem I am having is that for large manuals in the database (e.g., 10K+ item names) I take a significant performance hit from the image_create function. Without inserting the images, displaying the list of item names is almost instantaneous for 10K item names. With inserting the images, it may take upwards of 10-12 seconds.
Any suggestions on how to improve performance? I've even looked into creating a "image" font using FontForge, but would prefer not to go that route if possible.
Thanks in advance for your help.
Per Bryan Oakley's request, I have attached executable code here. If you un-comment the following lines:
tabContents_text.image_create("current", image=open_book_image)
you will see the difference in performance.
Link to the png file is HERE
import tkinter as tk
import tkinter.scrolledtext as tkst
win = tk.Tk()
frame1 = tk.Frame(master = win)
frame1.pack(fill='both', expand='yes')
win.state('zoomed')
tabContents_text = tkst.ScrolledText(frame1, cursor="arrow", wrap="none", tabs=150, font=('helvetica', 10, 'normal'))
tabContents_text.pack(side='top')
open_book_image = tk.PhotoImage(file="C:\\Users\\rhkea\\Downloads\\document_icon.png")
product_item_list=[]
for i in range(10000):
product_item_list.append("Item" + str(i).zfill(5))
col_count=4
row_count=2500
row_remain=0
tabContents_text.delete("1.0", "end")
row = 0
item = 0
while row < row_count:
col = 0
while col < col_count:
# tabContents_text.image_create("current", image=open_book_image)
tabContents_text.insert("end", product_item_list[item] + '\t')
col += 1
item += 1
tabContents_text.insert("end", "\n")
row += 1
col = 0
while col < row_remain:
# tabContents_text.image_create("current", image=open_book_image)
tabContents_text.insert("end", product_item_list[item] + '\t')
col += 1
item += 1
tabContents_text.insert("end", "\n")
win.mainloop()
Unfortunaly,I think there is no way to have a better performance.But you can use .update()
to show the image right away instead of blocking it in your code.
I don't know what's the purpose of second while loop
You can try this code,it will continue to load the image after you run it:
import tkinter as tk
import tkinter.scrolledtext as tkst
win = tk.Tk()
frame1 = tk.Frame(master = win)
frame1.pack(fill='both', expand='yes')
win.state('zoomed')
tabContents_text = tkst.ScrolledText(frame1, cursor="arrow", wrap="none", tabs=150, font=('helvetica', 10, 'normal'))
tabContents_text.pack(side='top')
open_book_image = tk.PhotoImage(file="document_icon.png")
product_item_list=[]
for i in range(10000):
product_item_list.append("Item" + str(i).zfill(5))
col_count=4
row_count=2500
row_remain=0
tabContents_text.delete("1.0", "end")
row = 0
item = 0
try:
while row < row_count:
col = 0
while col < col_count:
tabContents_text.image_create("end", image=open_book_image) # It's "end" instead of current.
tabContents_text.insert("end", product_item_list[item] + '\t')
win.update() # update right away.
col += 1
item += 1
tabContents_text.insert("end", "\n")
win.update()
row += 1
col = 0
# This while loop seems that it will create two empty lines
while col < row_remain:
tabContents_text.image_create("current", image=open_book_image)
tabContents_text.insert("end", product_item_list[item] + '\t')
win.update()
col += 1
item += 1
tabContents_text.insert("end", "\n")
except BaseException: # Catch the raised exception when you close the window if it doesn't load image completely.
pass
except Exception as e:
print(e.args)
win.mainloop()
Maybe use .after() is also OK.
You can combine the image and the text into a single Label and then use .window_create(...) to insert into the Text box:
font = tabContents_text.cget('font') # get the Text font
for i in range(len(product_item_list)):
# create label with both image and text
lbl = tk.Label(tabContents_text, text=product_item_list[i]+'\t',
image=open_book_image, compound='left',
bg='white', font=font)
# insert the label into text box
tabContents_text.window_create('end', window=lbl)
# insert line break after showing 'col_count' items
if i%col_count == col_count-1:
tabContents_text.insert('end', '\n')
It can reduce the total items inserted into text box by half.

How to make a button Stay where it is when text is changing length

So i Have been trying to make this button stay in the same position but when ever the text changes its length the button always moves
i have tried removing the row and column values that doesn't work
i have tried changing the row and column values that doesn't work
so i don't really know what to do
from tkinter import *
win = Tk()
win.title('ab')
win.config(bg='blue')
win.geometry('200x100')
i = 0
def changetext():
global i
i = i + 1
if i == 1:
lbl.config(text='a')
if i == 2:
lbl.config(text='ab')
if i == 3:
lbl.config(text='abc')
if i == 4:
lbl.config(text='abcd')
if i == 5:
lbl.config(text='abcde')
lbl = Label(win,text='111111111111', font=("Courier", 9))
lbl.grid(row=1,column=2)
btn = Button(win,text='u', command =changetext)
btn.grid(row=2,column=2)
win.mainloop()
When you make the button (or pretty much any widget for that matter), you can define its width.
lbl = Label(win, width= 20, text = '111111111111', font = ("Courier",9))
btn = Button(win, width = 20, text = 'u', command = changetext)

ValueError with entry-field. Tkinter math-program

writing a tkinter program for my kids to do some math.
It first shows a label with the math-question, for example "What is 5 + 3?"
Then an inputfield (entry) shows to get the answer (entry-field checks if integers are entered)
A Button is created to start a function to check the solution.
Function to create random numbers and create entry-field:
def Do_Math(self):
nr1 = random.choice(self.numbers) #random number from list
nr2 = random.choice(self.numbers) #random number from list
do_math = nr1 + nr2 #do the math
txt_som = Label(tk, text = 'wat is de som van ' + str(nr1) + ' en ' + str(nr2) + ' ?', state='normal', \
font=('Courier', 14, "bold"), justify=LEFT, padx = 10, background='LightCyan2')
txt_som.place(x = 20, y = 170)
tk.update()
oplossing = Entry(tk, validate="key") #create input-field #validate to check for integer
oplossing['validatecommand'] = (oplossing.register(self.testVal),'%P','%d') #validate to check for integer
oplossing.place(x = 20, y = 200) #place inputfield on screen
oplossing.focus_set() #set focus so user can directly input.
self.oplossing = oplossing
self.do_math = do_math
#knop voor ingeven oplossing:
knop_oplossing = Button(tk, text='Ok?', command=self.solution) #create button
knop_oplossing.place(x = 20, y = 250) #place button on screen
tk.update()
Function to check the solution:
If the solution is good then the above function runs again to create new numbers.
def solution(self):
while True:
if int(self.oplossing.get()) == self.do_math:
#self.oplossing.delete(0, END) #clear entr-value
play.random_sound('good')
self.lbl.place(self.lbl.pi) #Place label
self.lbl_w.place_forget() #Hide label
tk.update()
#global score
#score = score + 1
#print('GOED GEDAAN!', score, 'van', asked_maths, 'pogingen goed')
game.Do_Math() #Choose new random numbers
elif int(self.oplossing.get()) != self.do_math:
play.random_sound('wrong')
self.lbl.place_forget() #Hide label
self.lbl_w.place(self.lbl_w.pi) #Place label
tk.update()
break #Go out the while loop and do nothing
Every runs ok, but in the background i get following error every time the solution is good:
if int(self.oplossing.get()) == self.do_math:
ValueError: invalid literal for int() with base 10: ''
I think the problem is that the function "solution" tries this:
int(self.oplossing.get()) == self.do_math
but the entry-field has no value jet.
What do you think? I wanna solve these error messages before going further.
Thnx in advanced!

pygame - How to read a file and blit the text onto the screen

So I have been reading files lately and a challenge was to read a file and then screen.blit all of the text in pygame.
import pygame
import sys
pygame.init()
screenSizeX = 1080
screenSizeY = 720
screenSize = (screenSizeX,screenSizeY)
screen = pygame.display.set_mode(screenSize,0)
pygame.display.set_caption("Display Text")
WHITE = (255,255,255)
GREEN = (0,255,0)
BLUE = (0,0,255)
RED = (255,0,0)
YELLOW = (255,255,0)
BLACK = (0,0,0)
x = 100
y = 100
file = input("Enter the name of the file you want to display(no quotes) ")
file = str(file)
inputedFile = open(file, "r")
def textOutput(line):
fontTitle = pygame.font.SysFont("Arial", 72)
textTitle = fontTitle.render(line, True, GREEN)
screen.blit(textTitle, (x,y))
pygame.display.update()
for line in inputedFile:
text = line
go = True
while go:
for event in pygame.event.get():
if event.type ==pygame.QUIT:
go = False
screen.fill(WHITE)
fontTitle = pygame.font.SysFont("Arial", 72)
textTitle = fontTitle.render(text, True, GREEN)
screen.blit(textTitle, (x,y))
pygame.display.update()
inputedFile.close()
pygame.quit()
sys.exit()
So this kind of works. It will display the last line of the file you input for it to read. So I was wondering if there was a way to make it display every single line from a text file. It also display a rectangle after the line, which I think has something to do with a \n at the end of the line of text.
In this loop
for line in inputedFile:
text = line
you actually overwrite text all the times with the last line. You would actually want to append the new lines. Like this:
text = []
for line in inputedFile:
text.append(line)
text = '\n'.join(text)
You can also try to use the read function, as described here.
It's not too hard to to work through the lines of text, justifying each one.
The multilineRender() function presented below does this. It first generates bitmaps of each line, and determines the maximum line-width. Once this width is known it becomes easy to left/right/centre justify by adjusting the x-coordinate.
Each of the bitmaps is then blitted to the pygame screen in turn. Obviously the y-coordinate is increased by the height of each bitmap as we go.
import sys
import pygame
from pygame.locals import *
mline_text="The Scroobious Pip went out one day\nWhen the grass was green, and the sky was grey.\nThen all the beasts in the world came round\nWhen the Scroobious Pip sat down on the ground.\n"
WIDTH = 600
HEIGHT= 500
WHITE = 255,255,255
BLUE = 0,0,200
###
### Draw a multi-line block of text to the screen at (x,y)
### With optional justification
###
def multilineRender(screen, text, x,y, the_font, colour=(128,128,128), justification="left"):
justification = justification[0].upper()
text = text.strip().replace('\r','').split('\n')
max_width = 0
text_bitmaps = []
# Convert all the text into bitmaps, calculate the justification width
for t in text:
text_bitmap = the_font.render(t, True, colour)
text_width = text_bitmap.get_width()
text_bitmaps.append((text_width, text_bitmap))
if (max_width < text_width):
max_width = text_width
# Paint all the text bitmaps to the screen with justification
for (width, bitmap) in text_bitmaps:
xpos = x
width_diff = max_width - width
if (justification == 'R'): # right-justify
xpos = x + width_diff
elif (justification == 'C'): # centre-justify
xpos = x + (width_diff // 2)
screen.blit(bitmap, (xpos, y) )
y += bitmap.get_height()
#start pygame, create a font for the text
pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.font.init
myfont = pygame.font.Font(None,14)
screen.fill(BLUE)
# three copies of the same text, different justificaiton
multilineRender(screen, mline_text, 20, 20, myfont, WHITE)
multilineRender(screen, mline_text, 20,100, myfont, WHITE, justification="right")
multilineRender(screen, mline_text, 20,180, myfont, WHITE, justification="centre")
pygame.display.update()
while (True):
event = pygame.event.wait()
if event.type == QUIT:
pygame.quit()
sys.exit()

How do I print colored output with Python 3?

I have a simple print statement:
print('hello friends')
I would like the output to be blue in the terminal. How can I accomplish this with Python3?
It is very simple with colorama, just do this:
import colorama
from colorama import Fore, Style
print(Fore.BLUE + "Hello World")
And here is the running result in Python3 REPL:
And call this to reset the color settings:
print(Style.RESET_ALL)
To avoid printing an empty line write this:
print(f"{Fore.BLUE}Hello World{Style.RESET_ALL}")
Here's a class of mine I use to color specific output in Python 3 scripts. You could import the class and use like so:
from colorprint import ColorPrint as _
_.print_fail('Error occurred, quitting program')
import sys
# Colored printing functions for strings that use universal ANSI escape sequences.
# fail: bold red, pass: bold green, warn: bold yellow,
# info: bold blue, bold: bold white
class ColorPrint:
#staticmethod
def print_fail(message, end = '\n'):
sys.stderr.write('\x1b[1;31m' + message.strip() + '\x1b[0m' + end)
#staticmethod
def print_pass(message, end = '\n'):
sys.stdout.write('\x1b[1;32m' + message.strip() + '\x1b[0m' + end)
#staticmethod
def print_warn(message, end = '\n'):
sys.stderr.write('\x1b[1;33m' + message.strip() + '\x1b[0m' + end)
#staticmethod
def print_info(message, end = '\n'):
sys.stdout.write('\x1b[1;34m' + message.strip() + '\x1b[0m' + end)
#staticmethod
def print_bold(message, end = '\n'):
sys.stdout.write('\x1b[1;37m' + message.strip() + '\x1b[0m' + end)
Put these classes into Color.py file near your test.py file and run test.py.
I've tested these classes on Ubuntu Server 16.04 and Linux Mint 18.2 . All classes worked very good except GColor (RGB), that, it is usable in graphical terminal like Linux Mint terminal.
Also, you can use these classes like this:
print(Formatting.Italic + ANSI_Compatible.Color(12) + "This is a " + Formatting.Bold + "test" + Formatting.Reset_Bold + "!" + ANSI_Compatible.END + Formatting.Reset)
print(Color.B_DarkGray + Color.F_LightBlue + "This is a " + Formatting.Bold + "test" + Formatting.Reset_Bold + "!" + Base.END)
Result:
Note: It's not working on Windows!
File Color.py :
class Base:
# Foreground:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
# Formatting
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
# End colored text
END = '\033[0m'
NC ='\x1b[0m' # No Color
class ANSI_Compatible:
END = '\x1b[0m'
# If Foreground is False that means color effect on Background
def Color(ColorNo, Foreground=True): # 0 - 255
FB_G = 38 # Effect on foreground
if Foreground != True:
FB_G = 48 # Effect on background
return '\x1b[' + str(FB_G) + ';5;' + str(ColorNo) + 'm'
class Formatting:
Bold = "\x1b[1m"
Dim = "\x1b[2m"
Italic = "\x1b[3m"
Underlined = "\x1b[4m"
Blink = "\x1b[5m"
Reverse = "\x1b[7m"
Hidden = "\x1b[8m"
# Reset part
Reset = "\x1b[0m"
Reset_Bold = "\x1b[21m"
Reset_Dim = "\x1b[22m"
Reset_Italic = "\x1b[23m"
Reset_Underlined = "\x1b[24"
Reset_Blink = "\x1b[25m"
Reset_Reverse = "\x1b[27m"
Reset_Hidden = "\x1b[28m"
class GColor: # Gnome supported
END = "\x1b[0m"
# If Foreground is False that means color effect on Background
def RGB(R, G, B, Foreground=True): # R: 0-255 , G: 0-255 , B: 0-255
FB_G = 38 # Effect on foreground
if Foreground != True:
FB_G = 48 # Effect on background
return "\x1b[" + str(FB_G) + ";2;" + str(R) + ";" + str(G) + ";" + str(B) + "m"
class Color:
# Foreground
F_Default = "\x1b[39m"
F_Black = "\x1b[30m"
F_Red = "\x1b[31m"
F_Green = "\x1b[32m"
F_Yellow = "\x1b[33m"
F_Blue = "\x1b[34m"
F_Magenta = "\x1b[35m"
F_Cyan = "\x1b[36m"
F_LightGray = "\x1b[37m"
F_DarkGray = "\x1b[90m"
F_LightRed = "\x1b[91m"
F_LightGreen = "\x1b[92m"
F_LightYellow = "\x1b[93m"
F_LightBlue = "\x1b[94m"
F_LightMagenta = "\x1b[95m"
F_LightCyan = "\x1b[96m"
F_White = "\x1b[97m"
# Background
B_Default = "\x1b[49m"
B_Black = "\x1b[40m"
B_Red = "\x1b[41m"
B_Green = "\x1b[42m"
B_Yellow = "\x1b[43m"
B_Blue = "\x1b[44m"
B_Magenta = "\x1b[45m"
B_Cyan = "\x1b[46m"
B_LightGray = "\x1b[47m"
B_DarkGray = "\x1b[100m"
B_LightRed = "\x1b[101m"
B_LightGreen = "\x1b[102m"
B_LightYellow = "\x1b[103m"
B_LightBlue = "\x1b[104m"
B_LightMagenta = "\x1b[105m"
B_LightCyan = "\x1b[106m"
B_White = "\x1b[107m"
And,
File test.py:
from Color import *
if __name__ == '__main__':
print("Base:")
print(Base.FAIL,"This is a test!", Base.END)
print("ANSI_Compatible:")
print(ANSI_Compatible.Color(120),"This is a test!", ANSI_Compatible.END)
print("Formatting:")
print(Formatting.Bold,"This is a test!", Formatting.Reset)
print("GColor:") # Gnome terminal supported
print(GColor.RGB(204,100,145),"This is a test!", GColor.END)
print("Color:")
print(Color.F_Cyan,"This is a test!",Color.F_Default)
Result:
On Ubuntu Server 16.04
On Linux Mint 18.2
Since Python is interpreted and run in C, it is possible to set colors without a module.
You can define a class for colors like this:
class color:
PURPLE = '\033[1;35;48m'
CYAN = '\033[1;36;48m'
BOLD = '\033[1;37;48m'
BLUE = '\033[1;34;48m'
GREEN = '\033[1;32;48m'
YELLOW = '\033[1;33;48m'
RED = '\033[1;31;48m'
BLACK = '\033[1;30;48m'
UNDERLINE = '\033[4;37;48m'
END = '\033[1;37;0m'
When writing code, you can simply write:
print(color.BLUE + "hello friends" + color.END)
Note that the color you choose will have to be capitalized like your class definition, and that these are color choices that I personally find satisfying. For a fuller array of color choices and, indeed, background choices as well, please see: https://gist.github.com/RabaDabaDoba/145049536f815903c79944599c6f952a.
This is code for C, but can easily be adapted to Python once you realize how the code is written.
Take BLUE for example, since that is what you are wanting to display.
BLUE = '033[1;37;48m'
\033 tells Python to break and pay attention to the following formatting.
1 informs the code to be bold. (I prefer 1 to 0 because it pops more.)
34 is the actual color code. It chooses blue.
48m is the background color. 48m is the same shade as the console window, so it seems there is no background.
# Pure Python 3.x demo, 256 colors
# Works with bash under Linux and MacOS
fg = lambda text, color: "\33[38;5;" + str(color) + "m" + text + "\33[0m"
bg = lambda text, color: "\33[48;5;" + str(color) + "m" + text + "\33[0m"
def print_six(row, format):
for col in range(6):
color = row*6 + col + 4
if color>=0:
text = "{:3d}".format(color)
print (format(text,color), end=" ")
else:
print(" ", end=" ")
for row in range(-1,42):
print_six(row, fg)
print("",end=" ")
print_six(row, bg)
print()
# Simple usage: print(fg("text", 160))
Try this way, without import modules, just use colors code numbers, defined as constants:
BLUE = '34m'
message = 'hello friends'
def display_colored_text(color, text):
colored_text = f"\033[{color}{text}\033[00m"
return colored_text
Example:
>>> print(display_colored_text(BLUE, message))
hello friends
To use colour in the console see here and here.
There are modules dedicated to this task such as colorama and curses
I use the colors module. Clone the git repository, run the setup.py and you're good. You can then print text with colors very easily like this:
import colors
print(colors.red('this is red'))
print(colors.green('this is green'))
This works on the command line, but might need further configuration for IDLE.
This one answer I have got from the earlier python2 answers that is
Install termcolor module.
pip3 install termcolor
Import the colored class from termcolor.
from termcolor import colored
Use the provided methods, below is an example.
print(colored('hello', 'red'), colored('world', 'green'))
For lazy people:
Without installing any additional library, it is compatible with every single terminal i know.
Class approach:
First do import config as cfg.
clipped is dataframe.
#### HEADER: ####
print('{0:<23} {1:>24} {2:>26} {3:>26} {4:>11} {5:>11}'.format('Road name','Classification','Function','Form of road','Length','Distance') )
#### Now row by row: ####
for index, row in clipped.iterrows():
rdName = self.colorize(row['name1'],cfg.Green)
rdClass = self.colorize(row['roadClassification'],cfg.LightYellow)
rdFunction = self.colorize(row['roadFunction'],cfg.Yellow)
rdForm = self.colorize(row['formOfWay'],cfg.LightBlue)
rdLength = self.colorize(row['length'],cfg.White)
rdDistance = self.colorize(row['distance'],cfg.LightCyan)
print('{0:<30} {1:>35} {2:>35} {3:>35} {4:>20} {5:>20}'.format(rdName,rdClass,rdFunction,rdForm,rdLength,rdDistance) )
Meaning of {0:<30} {1:>35} {2:>35} {3:>35} {4:>20} {5:>20}:
0, 1, 2, 3, 4, 5 -> columns, there are 6 in total in this case
30, 35, 20 -> width of column (note that you'll have to add length of \033[96m - this for Python is a string as well), just experiment :)
>, < -> justify: right, left (there is = for filling with zeros as well)
What is in config.py:
#colors
ResetAll = "\033[0m"
Bold = "\033[1m"
Dim = "\033[2m"
Underlined = "\033[4m"
Blink = "\033[5m"
Reverse = "\033[7m"
Hidden = "\033[8m"
ResetBold = "\033[21m"
ResetDim = "\033[22m"
ResetUnderlined = "\033[24m"
ResetBlink = "\033[25m"
ResetReverse = "\033[27m"
ResetHidden = "\033[28m"
Default = "\033[39m"
Black = "\033[30m"
Red = "\033[31m"
Green = "\033[32m"
Yellow = "\033[33m"
Blue = "\033[34m"
Magenta = "\033[35m"
Cyan = "\033[36m"
LightGray = "\033[37m"
DarkGray = "\033[90m"
LightRed = "\033[91m"
LightGreen = "\033[92m"
LightYellow = "\033[93m"
LightBlue = "\033[94m"
LightMagenta = "\033[95m"
LightCyan = "\033[96m"
White = "\033[97m"
Result:
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def colour_print(text,colour):
if colour == 'OKBLUE':
string = bcolors.OKBLUE + text + bcolors.ENDC
print(string)
elif colour == 'HEADER':
string = bcolors.HEADER + text + bcolors.ENDC
print(string)
elif colour == 'OKCYAN':
string = bcolors.OKCYAN + text + bcolors.ENDC
print(string)
elif colour == 'OKGREEN':
string = bcolors.OKGREEN + text + bcolors.ENDC
print(string)
elif colour == 'WARNING':
string = bcolors.WARNING + text + bcolors.ENDC
print(string)
elif colour == 'FAIL':
string = bcolors.HEADER + text + bcolors.ENDC
print(string)
elif colour == 'BOLD':
string = bcolors.BOLD + text + bcolors.ENDC
print(string)
elif colour == 'UNDERLINE':
string = bcolors.UNDERLINE + text + bcolors.ENDC
print(string)
just copy the above code.
just call them easily
colour_print('Hello world','OKBLUE')
colour_print('easy one','OKCYAN')
colour_print('copy and paste','OKGREEN')
colour_print('done','OKBLUE')
Hope it would help
I would like to show you about how to color code. There is also a game to it if you would like to play it down below. Copy and paste if you would like and make sure to have a good day everyone! Also, this is for Python 3, not 2.
( Game )
# The Color Game!
# Thank you for playing this game.
# Hope you enjoy and please do not copy it. Thank you!
#
import colorama
from colorama import Fore
score = 0
def Check_Answer(answer):
if (answer == "no"):
print('correct')
return True
else:
print('wrong')
answer = input((Fore.RED + "This is green."))
if Check_Answer(answer) == True:
score = score + 1
else:
pass
answer = input((Fore.BLACK + "This is red."))
if Check_Answer(answer) == True:
score = score + 1
else:
pass
answer = input((Fore.BLUE + "This is black."))
if Check_Answer(answer) == True:
score = score + 1
else:
pass
print('Your Score is ', score)
Now for the color coding. It also comes with a list of colors YOU can try.
# Here is how to color code in Python 3!
# Some featured color codes are : RED, BLUE, GREEN, YELLOW, OR WHITE. I don't think purple or pink are not out yet.
# Here is how to do it. (Example is down below!)
import colorama
from colorama import Fore
print(Fore.RED + "This is red..")
Approach 1 -- for alien robots
The simplest, most direct answer appears to be something like:
print('\033[94m' + 'hello friends' + '\033[0m')
This answer is however difficult to suggest because:
it's written in alien code (what is '\033[94m'?? Not good enough for us humans)
it is locked to one color only, and, in practice, it is often useful to have a palete available on the spot to choose the color that feels right
Approach 2 -- 3rd-party package approach
Installing something like colorama or termcolor can be a way to go. However:
This approach does not apply to every person because there are many situations in which it is not practical to install a package from pypi.
Approach 3 -- Just put it in a class
Some of the answers here already suggest this approach. Basically, just dump the alien codes (e.g. \033[95m,\033[94m, \033[0m, ...) into the attributes of a class and then build strings using the names of the class attributes. Example:
class Colors:
OKBLUE='\033[94m'
ENDC='\033[0m'
print(Colors.OKBLUE + 'hello friends' + Colors.END)
This solves the problem and allows adding more alien codes for other colors if needed. In many projects, this approach is good and enough.
However, in some projects, this approach doesn't work well. As we use the Colors class over and over again, the whole process of writing string concatenations (using additions or equivalent approaches) becomes a bit problematic in terms of making your code less readable.
Approach 4 -- Just put it in a metaclass
A nice API could be something like this:
from utils import Colors # `utils` is a fictional module where we would have our `Colors` class
greeting = Colors.okblue('hello friends')
print(greeting)
# Or even shorter
Colors.print_okblue('hello friends')
In this example, the .okblue(...) and .print_okblue(...) are class methods that provide a shortcut through an automatic conversion of the method names to the respective alien codes. This type of shortcut method can be implemented using something like the __getattr__ customization.
However, I have tried doing that in the Colors class, but it didn't work well because I would then need to create an instance of the Colors class (colors = Colors()) in order to use the shortcut methods. Instead, I wanted to keep using these methods as class methods. Therefore, I had to go for a metaclass.
Let's say we have the following utils.py:
from functools import partial
class _MetaColors(type):
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
BOLD = '\033[1m'
B = '\033[1m'
UNDERLINE = '\033[4m'
U = '\033[4m'
_ENDC = '\033[0m'
def __getattr__(cls, name):
if name.startswith('print_'):
key = name.lstrip('print_').upper()
assert not key.startswith('_'), 'Color key cannot start with `_`'
return partial(cls.print, key)
else:
key = name.upper()
assert not key.startswith('_'), 'Color key cannot start with `_`'
return partial(cls.colorize, key)
#classmethod
def colorize(cls, key, *args):
ini = getattr(cls, key.upper(), None)
assert ini != None, f'Color key "{key}" not recognized'
string = ' '.join(str(a) for a in args)
return ini + string + cls._ENDC
#classmethod
def print(cls, key, *args, **kwds):
colorized = cls.colorize(key, *args)
print(colorized, **kwds)
class Colors(metaclass=_MetaColors):
pass
Then, you can just use colors from other modules like this:
from utils import Colors
print(Colors.okblue('hello friends'))
# or
greeting = Colors.okblue('hello friends')
print(greeting)
print('hello', Colors.okblue('friends'))
print(f'hello {Colors.okblue("friends")}')
Colors.print_okblue('hello friends')
Similar to solutions above, but with a dict
def c(color):
color_dict = {
"PURPLE": "\033[95m",
"CYAN": "\033[96m",
"DARKCYAN": "\033[36m",
"BLUE": "\033[94m",
"GREEN": "\033[92m",
"YELLOW": "\033[93m",
"RED": "\033[91m",
"BOLD": "\033[1m",
"UNDERLINE": "\033[4m",
"END": "\033[0m"}
for k, v in color_dict.items():
k = k.lower()[0:1]
if k == color :
return v
print(c("y")+"Hello World")
For windows just do this:
import os
os.system("color 01")
print('hello friends')
Where it says "01" that is saying background black, and text color blue. Go into CMD Prompt and type color help for a list of colors.

Resources