Multiple Images in EasyGui - python-3.x

Basically I want to create type of quiz in Python 3.4 with EasyGui using multiple images on the button boxes.
How I'd imagine it'd work would be like this:
import easygui as eg
# A welcome message
eg.msgbox ("Welcome to the quiz", "Quiz!")
# A short splash screen this could be looped
Finish = "Start"
while Finish == "Start":
Finish = eg.buttonbox("Do you want to start the quiz or quit?","Welcome",["Start","Quit"])
if Finish == "Quit":
break
#Question 1
image = "mickey.gif"
choices = ["Mickey","Minnie","Daffy Duck","Dave"]
reply=eg.buttonbox("Who is this?",image = image,choices = choices)
if reply == "Mickey":
eg.msgbox("Well done!","Correct")
else:
eg.msgbox("Wrong","Failure")
This works, but if I change the line
reply=eg.buttonbox("Who is this?",image=[image,image2,image3,image4],choices = choices)
But that doesn't seem to work, does anyone know if you can have more than one image per buttonbox?

at the current version of easygui, you can't have multiple images, only one image.
You could either:
use an external tool to create one big merged image out of several smaller images.
try to make the necessary changes direct inside easygui.py (it's all in one single file) if you have knowledge in tkinter
help / contact Robert Lugg as he works on an improved version of easygui https://github.com/robertlugg/easygui

allpic = ("image", "image2", "image3")
reply=eg.buttonbox("Who is this?",image=allpic,choices = choices)

Related

How can i create a terminal like design using tkinter

I want to create a terminal like design using tkinter. I also want to include terminal like function where once you hit enter, you would not be able to change your previous lines of sentences. Is it even possible to create such UI design using tkinter?
An example of a terminal design may look like this:
According to my research, i have found an answer and link that may help you out
Firstly i would like you to try this code, this code takes the command "ipconfig" and displays the result in a new window, you can modify this code:-
import tkinter
import os
def get_info(arg):
x = Tkinter.StringVar()
x = tfield.get("linestart", "lineend") # gives an error 'bad text index "linestart"'
print (x)
root = tkinter.Tk()
tfield = tkinter.Text(root)
tfield.pack()
for line in os.popen("ipconfig", 'r'):
tfield.insert("end", line)
tfield.bind("<Return>", get_info)
root.mainloop()
And i have found a similar question on quora take a look at this
After asking for additional help by breaking down certain parts, I was able to get a solution from j_4321 post. Link: https://stackoverflow.com/a/63830645/11355351

searching for tags in Tkinter Text widget

i am using a tkinter Text widget to display the content of gerber-code files.
the program runs on a raspberry pi and send code over serial to a machine one line of text at at time.
i set the current active line as follows:
class TextEditor(tkinter.Text):
def __init__(self, tkRoot):
...
self.tag_configure("activeLine", background="#87e8ed")# set the colour used for activeLine
def setLine(self, lineNumber):
self.tag_remove("activeLine", "1.0", "end")
self.tag_add("activeLine", str(lineNumber)+".0 linestart", str(lineNumber)+".0 lineend+1c")
def getLine(self):
pass # need to return the activeLine line number
there should only ever be one line at a time highlighted with "activeLine" so the first instance would be fine.
i could store a variable in the call to setLine and read it back in getLine but i would prefer not to as any edits to the text it could go out of sink
i notice using IDLE that the debugger uses what looks the same principle as i am trying to achieve here to set breakpoints, is it possible and if so where would i start looking for the IDLE source code to look into how it is achieved there, i am currently writing this on a Ubuntu 18.04 desktop i would like to no best ways to search IDLE source from
any help would be greatly appreciated, i am quite new to python and tkinter as i am generally a windows dot.net programmer but i am now learning to use Linux
i have now found an answer to my own question
listing all the functions of the text widget that start with "tag_" like this:
d = dir(self.tkRoot.text)
for dv in d:
s = str(dv)
if s.startswith("tag_"):
print(dv)
i found the method "tag_ranges(name)" that returns me this
(<textindex object: '5.0'>, <textindex object: '6.0'>)
at the time of calling the current line was 5

Why is there no response when i call the function in the if statement?

Hi I'm new to python and my first project is to create a GUI app with a few buttons to play songs. The problem is in the if statement, VLC will not play the file no matter what i do. This if statement worked in another program only running in the Terminal.
import vlc
import easygui
x = easygui.buttonbox(choices=("x","y","z"))
if x == "y":
p = vlc.MediaPlayer("/directory/to/mp3/file")
p.play()
Looking at the documentation for easygui it appears that the choices for a buttonbox are stored as a list and not as a tuple. Try easygui.buttonbox(choice=["x","y","z"]) instead.

Looking for help on how to get started with my first programming project

Step 1:
Open google chrome to the chess.com website
Step 2:
Login into my account via the homepage
Step 3:
Hover mouse cursor over the big “Learn” button on the banner on the left hand side of the web page. This will extend into another menu.
Step 4:
On this menu that has popped up, I will click the button which says “Videos”, which will navigate me to this url: “https://www.chess.com/videos”
Step 5:
Then I click the “Library” button to take me to: “https://www.chess.com/videos/library”
Step 6:
I open up a specific video (out of the many which are in a list) by clicking on the title link.
This is how the list looks like:
https://photos.app.goo.gl/VsxhQH5siigGMMoJA
Step 7:
On the new page, with the video player in plain sight, I right click and then inspect element- in order to enter Chrome development tools
Like so:
https://photos.app.goo.gl/96YgYTfLa58MHSmp7
Step 8:
Then I click the “pointer arrow” button in the top left hand corner of the dev tool box.
Step 9:
Then I “select” on the video player to highlight it.
Cf. this image:
https://photos.app.goo.gl/6wsLFEzmcBJVJTHJ9
Step 10:
Then I open the .mp4 link which has appeared in the elements tab, which will thus open a new tab which only contains the video player on the screen
Step 11 (Final step):
Then I click the button in the bottom right hand corner and then select “Download” in order to get the .mp4 file.
Cf. this image: https://photos.app.goo.gl/gDMxwmNBSwBCq4LP8
I find it very tedious to do this process of downloading all the embedded videos from a website such as this, because I must actually open a new video in order to get a chance to download it.
Thus, I was thinking of making my very first project as a complete novice programmer (to keep myself motivated!) to try and program something which can automate this process.
My questions is: Is it possible to automate this algorithm that I have stated above (perhaps with some kind of bot or web crawler), and what topics should I learn about in order to develop the skills in order to do what is necessary?
Thank you so much for the help everyone! I am very grateful :)
I realize you may not be looking for a code-solution, but I have included one that you can use for inspiration. It downloads all the videos into a directory "chessvideos" (note that there are 123 pages with ~25 videos on each, so it will take a long time to finish).
Building a webcrawler like this is a process. Knowing that you can get the HTML of a url using requests and that you can "query" the DOM to find elements using BeautifulSoup, open your browser and do the inspections as you mention in your question. E.g which HTML-attributes should you be looking for? Classes, Id's, tags etc.
Part of this process is also to realize how the system will respond to your requests, e.g you mention logging in - this may often be a requirement, but it is not actually for this website, making the problem a lot simpler. Hope it is of some use.
import requests
from bs4 import BeautifulSoup
import os
class ChessDownloader():
download_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), "chessvideos")
def __init__(self):
res = requests.get("https://www.chess.com/videos/library")
if res.status_code == 200:
b = BeautifulSoup(res.text, features='html5lib')
a = b.find('a', text='Last').get('href')
pages = int(a.replace('https://www.chess.com/videos/library?page=', '')) # get the number of pages using the "Last" button
for i in range(pages):
self.download_videos_from_page(i)
def download_videos_from_page(self, page_number):
if page_number == 0:
res = requests.get('https://www.chess.com/videos/library')
else:
res = requests.get('https://www.chess.com/videos/library?page=' + str(page_number))
if res.status_code == 200:
b = BeautifulSoup(res.text, features='html5lib')
links = b.find_all('a', { 'class' : 'content-image' })
links = [a.get('href') for a in links]
for link in links:
r = requests.get(link)
if r.status_code == 200:
b = BeautifulSoup(r.text, features='html5lib')
video_url = b.find('meta', {'property': 'og:video:secure_url'}).get('content')
self.download_video(video_url)
def download_video(self, url):
if not os.path.exists(self.download_directory):
os.mkdir(self.download_directory)
res = requests.get(url)
if res.status_code == 200:
name = url.rsplit('/', 1)[-1]
file_path = os.path.join(self.download_directory, name)
if not os.path.exists(file_path): # Dont download if we already have it
with open(file_path, 'wb+') as f:
f.write(res.content)
c = ChessDownloader()

Gtk Window Non-Responsive During Selenium Automation

Good Afternoon :) Having a problem with my Python3 Gtk3 application and Selenium WebDriver (ChromeDriver). Also, using Linux if it matters.
Basically, the user presses a button to start the Selenium webdriver automation and then as the automation process is going, it 'SHOULD' give feedback to the user in the GUI (See Content.content_liststore.append(list(item)) and LogBox.log_text_buffer).
However, it's not adding anything into the content_liststore until after fb_driver.close() is done. In the meantime, the Gtk window just "hangs".
Now, I've been looking into multithreading in hopes of the GUI being responsive to this feedback but I've also been reading that Selenium doesn't like multithreading (but I presume thats running multiple browsers/tabs (which this is not)).
So, my question is; Is multithreading the go-to fix for getting this to work?
# ELSE IF, FACEBOOK COOKIES DO NOT EXIST, PROCEED TO LOGIN PAGE
elif os.stat('facebook_cookies').st_size == 0:
while True:
try: # look for element, if not found, refresh the webpage
assert "Facebook" in fb_driver.title
login_elem = fb_driver.find_element_by_id("m_login_email")
login_elem.send_keys(facebook_username)
login_elem = fb_driver.find_element_by_id("m_login_password")
login_elem.send_keys(facebook_password)
login_elem.send_keys(Keys.RETURN)
except ElementNotVisibleException:
fb_driver.refresh()
StatusBar.status_bar.push(StatusBar.context_id, "m_login_password element not found, trying again...")
ProblemsLog.text_buffer.set_text("Facebook has hidden the password field, refreshing page...")
else:
query_elem = fb_driver.find_element_by_name("query")
query_elem.send_keys(target)
query_elem.send_keys(Keys.RETURN)
break
m_facebook_url_remove = "query="
m_facebook_url = fb_driver.current_url.split(m_facebook_url_remove, 1)[1] # Remove string before "query="
facebook_url = "https://www.facebook.com/search/top/?q=" + m_facebook_url # Merge left-over string with the desktop url
StatusBar.status_bar.push(StatusBar.context_id, "Facebook elements found")
fb_title = fb_driver.title
fb_contents = [(target_name.title(), "Facebook", facebook_url)]
for item in fb_contents:
Content.content_liststore.append(list(item))
#progress_bar.set_fraction(0.10)
LogBox.log_text_buffer.set_text("Facebook Search Complete")
with open('facebook_cookies', 'wb') as filehandler:
pickle.dump(fb_driver.get_cookies(), filehandler)
fb_driver.close()
I've considered it not working because of the 'while' loop, but another piece of code doesn't have a loop and does the exact same thing, it waits for Selenium to finish before adding content to the GUI.
Additionally, the user can select multiple websites to do this with, so the application can first go to Facebook (do it's business then close), go to LinkedIn (do it's business then close) and so fourth. And it still waits for all the Selenium code to finish before adding anything to the Gtk GUI.
I really hope that makes sense! Thank you :)
Your`s question is the answer you are lookig for. Take a read here https://wiki.gnome.org/Projects/PyGObject/Threading

Resources