0

I want to be able to change the background color of Python's console (python.exe) to any RGB color.

I know that I can use the color command (documentation link 1 and documentation link 2) to pick the background and foreground (font) colors from 16 available colors:

import os

os.system('color 8f')

image of the console with the background colored from running the code above

I also know that I can manually change the RGB values of those 16 colors by right-clicking the top bar of the console and then clicking in properties and going to the colors' tab.

I would like to know if there's a programmatic solution though, just as there is for changing the font color to an RGB value:

import os

os.system('')

def rgb(red, green, blue):
  return f'\x1b[38;2;{red};{green};{blue}m'

red_color = rgb(255, 0, 0)
green_color = rgb(0, 255, 0)
blue_color = rgb(0, 0, 255)

print(f'{red_color}red {green_color}green {blue_color}blue')

image of the console with the font colored from running the code above

I'm asking for the background color of the whole console screen, not the background color of the text. I also don't want to install some different console or a module that somehow does it without understanding how.

user7393973
  • 2,270
  • 1
  • 20
  • 58
  • Are you asking how to change IDLE's background color? – wwii Aug 01 '20 at 00:32
  • @wwii Not the IDLE shell (which is from `C:\Users\Username\AppData\Local\Programs\Python\Python38-32\pythonw.exe "C:\Users\Username\AppData\Local\Programs\Python\Python38-32\Lib\idlelib\idle.pyw"`). The `python.exe` one (`C:\Users\Username\AppData\Local\Programs\Python\Python38-32\python.exe`). – user7393973 Aug 01 '20 at 08:13

1 Answers1

1

I found out that I can use the GetConsoleScreenBufferInfoEx and SetConsoleScreenBufferInfoEx functions to programmatically change the values of any of the 16 colors of the console.

The code below is a combination of the code found in the question and answers:

Why does the console window shrink when using GetConsoleScreenBufferInfoEx in Windows?

Executable called via subprocess.check_output prints on console but result is not returned

Change entire console background color (Win32 C++)

import ctypes
from ctypes import wintypes
import os
import sys
import time

class COORD(ctypes.Structure):
  _fields_ = (('X', wintypes.SHORT), ('Y', wintypes.SHORT))

class CONSOLE_SCREEN_BUFFER_INFOEX(ctypes.Structure):
  _fields_ = (
    ('cbSize', wintypes.ULONG),
    ('dwSize', COORD),
    ('dwCursorPosition', COORD),
    ('wAttributes', wintypes.WORD),
    ('srWindow', wintypes.SMALL_RECT),
    ('dwMaximumWindowSize', COORD),
    ('wPopupAttributes', wintypes.WORD),
    ('bFullscreenSupported', wintypes.BOOL),
    ('ColorTable', wintypes.DWORD * 16))
  def __init__(self, *args, **kwds):
    super(CONSOLE_SCREEN_BUFFER_INFOEX, self).__init__(*args, **kwds)
    self.cbSize = ctypes.sizeof(self)

def rgb_values_to_integer_color(red, green, blue):
  integer_color = red + (green * 256) + (blue * 256 * 256)
  return integer_color

STD_OUTPUT_HANDLE = -11
console_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
console_screen_information = CONSOLE_SCREEN_BUFFER_INFOEX()

# get the original color to later set it back
ctypes.windll.kernel32.GetConsoleScreenBufferInfoEx(console_handle, ctypes.byref(console_screen_information))
original_color = console_screen_information.ColorTable[0]

# prevent the console screen's height from shrinking
console_screen_information.srWindow.Bottom += 1

# set the new rgb color
console_screen_information.ColorTable[0] = rgb_values_to_integer_color(red=84, green=170, blue=255)
ctypes.windll.kernel32.SetConsoleScreenBufferInfoEx(console_handle, ctypes.byref(console_screen_information))

# wait 3 seconds
time.sleep(3)

# change back to the original color
console_screen_information.ColorTable[0] = original_color
ctypes.windll.kernel32.SetConsoleScreenBufferInfoEx(console_handle, ctypes.byref(console_screen_information))

The first color (black by default) is the one being changed since it's the default one being used out of the 16 as background color.

If you need to update the screen color for example at the start of a program you can just do os.system('cls') (after SetConsoleScreenBufferInfoEx).

user7393973
  • 2,270
  • 1
  • 20
  • 58