PySimpleGUI textbox border color - python-3.x

Is there a way to change the color of the textbox border only?
This code results in changing the background color. I just want the border color changed to red.
[sg.Input("textbox",size=(20, 1),background_color="red")]

There's no option for boder color in sg.InputText, here's example for you and it work under my WIN 10. Tkinter code required for it.
import PySimpleGUI as sg
def main():
layout = [
[sg.Input("textbox", size=(20, 1), key='-INPUT-')],
]
window = sg.Window("Title", layout, finalize=True)
window['-INPUT-'].Widget.configure(highlightcolor='red', highlightthickness=2)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
print(event, values)
window.close()
if __name__ == '__main__':
main()

Related

How to display TEXT ONLY (transparent background, with no menu bar or buttons) on screen using Python?

I have been looking everywhere for this kind of simple solution and I'm still coming up short.
All I want to do is simply splash some text only onto the screen, without a background or using a "message box" that has a menu bar/buttons with it. Just text, that's all. Maybe with a way to set a color for the font as well as I want the text to be a light gray. Using Windows 10 and Python 3.8+.
I've looked at easygui (message box, uses buttons), PySimpleGUI (best option so far, shown below, but defaults to a white background), Tkinter and pygame (but I have no clue how to set up what I'm looking for with those packages.
This is what I have using PySimpleGui, would love for this to be a transparent background if possible!
def popup_message(message):
sg.popup(str(message),
title = None,
button_color = 'white',
background_color = None,
text_color = 'grey85',#'light gray',
button_type = 5,
auto_close = True,
auto_close_duration = 20,
custom_text = (None, None),
non_blocking = False,
icon = None,
line_width = None,
font = None,
no_titlebar = True,
grab_anywhere = True,
keep_on_top = True,
location = (None, None),
relative_location = (250, 250),
any_key_closes = True,
image = None,
modal = True)
UPDATE
This is the closest thing I've got with using Tkinter. Problem now is the menu bar is still visible, and using the Label class results in a solid background. HOW CAN I ONLY SHOW TEXT ON SCREEN IN PYTHON!? I'm not even sure I'm going about this the right way, but seems like a pretty basic idea?
# Import the Tkinter Library
from tkinter import *
# Create an instance of Tkinter Frame
root = Tk()
# Create a Label to print some text
label = Label(root, text="This is a New Line Text", font= ('Helvetica 14 bold'), foreground= "red3")
label.pack()
# Create a transparent window
root.wm_attributes('-transparentcolor','#add123')
# Set the geometry of window
root.geometry("700x350")
# Add a background color to the Main Window
root.config(bg = '#add123')
root.mainloop()
Transparent background of Text in popupis not supported.
New popup function required and defined by yourself in PySimpleGUI.
Set option background_color of your Text element to one specified color for transparency, like '#add123'.
Set option transparent_color in Window to the specified color for transparency.
Set option no_titlebar in Window to hide the titlebar.
Following code show the way
import PySimpleGUI as sg
def popup(message):
global win
if win:
win.close()
layout = [[sg.Text(message, background_color=bg, pad=(0, 0))]]
win = sg.Window('title', layout, no_titlebar=True, keep_on_top=True,
location=(1000, 200), auto_close=True, auto_close_duration=3,
transparent_color=bg, margins=(0, 0))
event, values = win.read(timeout=0)
return win
bg = '#add123'
sg.set_options(font=("Courier New", 24))
layout = [[sg.Button('POPUP')]]
window = sg.Window('title', layout)
win = None
while True:
event, value = window.read()
if event == sg.WIN_CLOSED:
break
elif event == 'POPUP':
win = popup('Here is the message.')
window.force_focus()
if win:
win.close()
window.close()
You're trying to make a sort of screen without a title-menu. In, that case I can help you by telling you to use root.overrideredirect(True) which is a crucial part of your code.
You have two options for drawing text without a background.
The first is to use the canvas to draw the text as seen below. With this approach, you'd have to center the text yourself everytime the window is resized if you care about resizability.
canvas.create_text(x, y, "Text with no bg!")
Second approach is to use a disabled button with an empty img inside.
img = PhotoImage(file="file.png")
b = tk.Button(root, text="My Text", image=img, relief="FLAT", state="DISABLED")
b.image = img
b.pack()
See this answer for more info.
Let me know if you have any other questions.

How do I display text on the screen in pygame [duplicate]

This question already has answers here:
pygame - How to display text with font & color?
(7 answers)
Closed 1 year ago.
My question is all I want to do is display text on the screen in pygame. If someone known how to do this please tell me!
My code
import time
import pygame
from pygame.locals import *
pygame.init
blue = (0,0,255)
WINDOW_WIDTH = 500
WINDOW_HEIGHT = 500
WINDOW = pygame.display.set_mode((WINDOW_WIDTH,WINDOW_HEIGHT))
pygame.display.set_caption("Text")
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit
exit()
font = pygame.font.SysFont(None, 25)
def show_text(msg,color):
text = font.render(msg,True,color)
WINDOW.blit(text,[WINDOW_WIDTH/2,WIDTH_HEIGHT/2])
show_text("This is a message!", blue)
pygame.display.update()
I want to just make text that says "This is a message!". That is all
You are pretty close already. To render text you need to first define a font, then use it to render(). This creates a bitmap with the text in it, which needs to be blit() to the window.
All the necessary parts are in the question-code, they are just a bit mixed-up.
import time
import pygame
from pygame.locals import *
# Constants
blue = (0,0,255)
WINDOW_WIDTH = 500
WINDOW_HEIGHT = 500
def show_text( msg, color, x=WINDOW_WIDTH//2, y=WINDOW_WIDTH//2 ):
global WINDOW
text = font.render( msg, True, color)
WINDOW.blit(text, ( x, y ) )
pygame.init()
WINDOW = pygame.display.set_mode((WINDOW_WIDTH,WINDOW_HEIGHT))
pygame.display.set_caption("Text")
# Create the font (only needs to be done once)
font = pygame.font.SysFont(None, 25)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
exit()
WINDOW.fill( ( 255, 255, 255 ) ) # fill screen with white background
show_text("This is a message!", blue)
pygame.display.update()

Change the width of an updated listbox in a ttk Combobox

This is an extension to the question and answers here.
I want to create two Comboboxes, with the items in the second Combobox depending on the selection in the first Combobox. Furthermore, I would like the dropdown listbox to resize to fit the text in the list, as in the answer here. However, I'm having some difficulties with this second part. I'd like to solve this problem using Python.
I've had varying results using .pack() and .forget() instead of .place() and .place_forget(), however I haven't been able to create a robust solution. Using .place is preferable to .pack or .grid if possible.
As an MWE, I've extended the code from one of the answers in the previous question. The dropdown listbox of c2 resizes fine, however that of c1 does not.
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
def on_combo_configure(event):
combo = event.widget
style = ttk.Style()
# check if the combobox already has the "postoffest" property
current_combo_style = combo.cget('style') or "TCombobox"
if len(style.lookup(current_combo_style, 'postoffset'))>0:
return
combo_values = combo.cget('values')
if len(combo_values) == 0:
return
longest_value = max(combo_values, key=len)
font = tkfont.nametofont(str(combo.cget('font')))
width = font.measure(longest_value + "0") - event.width
if (width<0):
# no need to make the popdown smaller
return
# create an unique style name using widget's id
unique_name='Combobox{}'.format(combo.winfo_id())
# the new style must inherit from curret widget style (unless it's our custom style!)
if unique_name in current_combo_style:
style_name = current_combo_style
else:
style_name = "{}.{}".format(unique_name, current_combo_style)
style.configure(style_name, postoffset=(0,0,width,0))
combo.configure(style=style_name)
def update_c1_list(event):
c1.place_forget()
_ = c.get()
if _ == "fruit":
c1['values'] = ('apples are the best', 'bananas are way more better')
elif _ == "text":
c1['values'] = ("here's some text", "and here's some much longer text to stretch the list")
else:
pass
c1.place(x=10,y=40)
root = tk.Tk()
root.title("testing the combobox")
root.geometry('300x300+50+50')
c = ttk.Combobox(root, values=['fruit','text'], state="readonly", width=10)
c.bind('<Configure>', on_combo_configure)
c.bind('<<ComboboxSelected>>', update_c1_list)
c.place(x=10,y=10)
c1 = ttk.Combobox(root, state="readonly", width=10)
c1.bind('<Configure>', on_combo_configure)
c1.place(x=10,y=40)
c2 = ttk.Combobox(root, state="readonly", width=10)
c2.bind('<Configure>', on_combo_configure)
c2.place(x=10,y=70)
c2['values']=('this list resizes fine','because it is updated outside of the function')
root.mainloop()
Any help is welcome, thanks.
After playing around I came up with a function which updates the listbox width of a combobox "on the fly". However, it's a bit like fixing a window with a hammer and causes some issues.
def Change_combo_width_on_the_fly(combo,combo_width):
style = ttk.Style()
# check if the combobox already has the "postoffest" property
current_combo_style = combo.cget('style') or "TCombobox"
combo_values = combo.cget('values')
if len(combo_values) == 0:
return
longest_value = max(combo_values, key=len)
font = tkfont.nametofont(str(combo.cget('font')))
width = font.measure(longest_value + "0") - (combo_width*6+23)
if (width<0):
# no need to make the popdown smaller
return
# create an unique style name using widget's id
unique_name='Combobox{}'.format(combo.winfo_id())
# the new style must inherit from curret widget style (unless it's our custom style!)
if unique_name in current_combo_style:
style_name = current_combo_style
else:
style_name = "{}.{}".format(unique_name, current_combo_style)
style.configure(style_name, postoffset=(0,0,width,0))
combo.configure(style=style_name)
As a MWE, the code can be used as follows:
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
root = tk.Tk()
c1 = ttk.Combobox(root, state="readonly", width=10)
c1.place(x=10,y=40)
Change_combo_width_on_the_fly(c1,10)
root.mainloop()
While the function does the job, it causes problems elsewhere in my code. In particular, it messes with a previously packed widget (scrollbar). I think it is changing the style the last placed widget, but I don't know how to fix this.

PySimpleGUI how to make transparent click-through window?

I want to draw a circle on the screen but it should be click-through and I should be able to click somethings behind in this circle. So far, I achieved to draw circle and made it transparent but i couldn't make it click-through. I know that it is possible with pywin32 win32con.WS_EX_LAYERED flag but there is no information about this on PySimpleGUI documentation. How can I solve this problem?
My current window configuration:
window = sg.Window('Sample window', layout,
keep_on_top=True,
auto_size_buttons=False,
grab_anywhere=False,
no_titlebar=True,
return_keyboard_events=False,
alpha_channel=0.8,
use_default_focus=False,
transparent_color='red',
finalize=True)
If it is not possible with PySimpleGUI, is it possible to do with pywin32 module combination?
The transparent_color property can be used to create "click-through" windows. All you need to do is make whatever you want to be click through the same color as the transparent_color. Here is an example where you can toggle the transparency of a shape in a canvas to the transparent color and make it click through.
import PySimpleGUI as sg
layout = [
[sg.Canvas(size=(100, 100), key= 'canvas',)],
[sg.T('Change circle color to:'), sg.Button('Red'), sg.Button('Blue')]
]
window = sg.Window('Sample window', layout,
keep_on_top=True,
auto_size_buttons=False,
grab_anywhere=False,
no_titlebar=True,
return_keyboard_events=False,
alpha_channel=0.8,
use_default_focus=False,
transparent_color='red',
finalize=True)
window.Finalize()
canvas = window['canvas']
cir = canvas.TKCanvas.create_oval(50, 50, 100, 100)
while True:
event, values = window.read()
if event is None:
break
if event == 'Blue':
canvas.TKCanvas.itemconfig(cir, fill="Blue")
elif event == 'Red':
#Here is where the cirle changes to a recolor making it transparent and click through
canvas.TKCanvas.itemconfig(cir, fill="Red")
layout = [[sg.Button("Button) ],
[sg.Graph(canvas_size =(400,100),
graph_bottom_left=(-400,-400),
graph_top_right=(400,400),
background_color='red') ]]
window = sg.Window('Click through transparent',
layout,background_color='red',keep_on_top=True,
transparent_color='red', alpha_channel=.5,
grab_anywhere=True, resizable=True).Finalize()
while True:
event, values = window.Read()
if event == sg.WIN_CLOSED:
break
if event == 'Click':
print(" Button Clicked")
Remember to put keep_on_top = True
This works well on windows, don't know if other os

pygame graphics grid

Hello, I am new to Python and graphics programming in general. At present I am messing around with creating grids as practice, and I am having problems with getting pygame to put objects on top of the surface window.
Below is my code with comments. I reckon that the problem may be to do with the blit function but I am unsure. Any help would be appreciated. Also, the Python shell does not highlight any exceptions or errors, but the program does not run.
import sys, random, pygame
from pygame.locals import *
def main():
#settings
boardDims = (20,20) #number of cells on board
#pygame settings
cellDims = (20,20) #number of pixels on cells
framerate = 50
colours = {0:(0,0,0), 1:(255,255,255)}
#pygame
pygame.init()
#sets x and y pixels for the window
dims = (boardDims[0] * cellDims[0],
boardDims[1] * cellDims[1])
#sets window, background, and framrate
screen = pygame.display.set_mode(dims)
background = screen.convert()
clock = pygame.time.Clock()
#create new board
board = {}
#iterates over x and y axis of the window
for x in range(boardDims[0]):
for y in range(boardDims[1]):
board[(x,y)] = 0 #sets whole board to value 0
board[(1,1)] = 1 #sets one square at co-ordinates x=1,y=1 to cell
# value 1
return board
running = 1
while running:
# 1 PYGAME
#get input
for event in pygame.event.get():
if event.type == QUIT or \
(event.type == KEYDOWN and event.key == K_ESCAPE):
running = 0
return
#link pygames clock to set framerate
clock.tick(framerate)
for cell in board:
#adds cells dimensions and co-ordinates to object rectangle
rectangle = (cell[0]*cellDims[0], cell[1]* cellDims[1],
cellDims[0], cellDims[1])
#pygame draws the rectabgle on the background using the relevant
#colour and dimensions and co-ordinates outlined in 'rectangle'
square = pygame.draw.rect(background, colours[board[cell]],
rectangle)
#blits and displays object on the background
background.blit(square)
screen.blit(background, (0,0))
pygame.display.flip()
if __name__ == "__main__":
main()
The "return board" statement is exiting your program before any blitting is done.
Also, you can blit the squares directly on the screen variable, ie: you don't need the background variable.

Resources