I am working on a small application on ipywidgets that has multiple frames. This means users can click a button, and then the original set of widgets will be closed and a new set of widgets will appear. The function which I am using has a simplified structure as below:
def to_next_page(x):
current_page.close()
display(next_page)
I have a button in current_page that goes to next_page, and vice versa. When I tried to go back from next_page to current_page, the following message appeared instead of the widget:
Tab(children=(VBox(children=(Text(value='', description='Username:'), Password(description='Password:'), Button(description='Login', style=ButtonStyle()), Button(description='Forget Password', style=ButtonStyle()))), VBox(children=(Text(value='', description='Username:'), Password(description='Password:'), Button(description='Login', style=ButtonStyle()), Button(description='Forget Password', style=ButtonStyle()), Button(description='Sign up', style=ButtonStyle())))), _titles={'0': 'Staff', '1': 'Member'})
Is there any way to go back and forth between widget sets? Thank you.
you cant use .close
use this
out = Output()
def to_next_page(x):
out.clear_output()
with out:
display(next_page)
and for displaying everytime use:
with out:
display(anything)
and for closing use:
out.clear_output()
Related
I am testing a website which has a menu with submenus appearing on hover.
I have created a function to interact with this menu:
def go_to(navbar_item, menu_item):
# find the navbar item
assets_main_menu = driver.find_element(By.ID, navbar_item)
#hover over the navbar item, so the submenu appears
hover.move_to_element(assets_main_menu).perform()
# find the submenu item
xpath = "//*[contains(text(), \'" + menu_item + "\')]"
destination = driver.find_element_by_xpath(xpath)
# hover over the submenu item and clicks
hover.move_to_element(destination).click().perform()
The problem is that i use this function more than once such as:
# action 1
go_to('navbar item1 id', 'submenu item1')
do_something()
# action 2
go_to('navbar item1 id', 'submenu item2')
do something()
# action 3
go_to('navbar item1 id', 'submenu item3')
do_something()
selenium actually repeats the previous steps going through the past menu items like:
ACTUAL OUPTUP
action 1, do something -> action 1, action 2, do something -> action 1, action 2, action 3, do something
Instead my DESIRED OUTPUT would be:
action 1, do something -> action 2, do something -> action 3, do something
I tried unsetting the variables:
navbar_item, menu_item, hover, xpath, destination.
at the end of the function with no luck.
I have also tried to instantiate hover within my function
hover = ActionChains(driver);
but in this last attempt my code stopped working.
When you call an action chain, perform() does not clear out the previous steps. You've only really shared your function so the real culprit is the structure of your code and how python consumes variables.
I note in your function, you pass in two strings but your function knows what driver and hover are. Which sounds like you're using global variables.
To demo your problem I created this simple page for you with a click counter:
<html>
<body>
<button id="button" onclick="document.getElementById('input').value = parseInt(document.getElementById('input').value) + 1">Click me</button>
<input id="input" value="0"></input>
</body>
</html>
It's a flat page that just knocks up a number each time you press the button:
Then, to show you what's happening, i created a similar version of your code:
driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get(r"c:\git\test.html")
actions = ActionChains(driver)
def ClickByActions(element):
actions.move_to_element(element).click().perform()
#find the button and click it a few times...
button = driver.find_element_by_id('button')
ClickByActions(button)
ClickByActions(button)
ClickByActions(button)
With this, you expect the end click-count-value to be 3. However, it is 6.
Same as your problem. First call does +1, second call does +1 +1, third call does +1 +1 +1.
Finally! the solution - create action chain in the function with your driver:
def ClickByActions(element):
localActions = ActionChains(driver)
localActions.move_to_element(element).click().perform()
I note in the comments you say you tried this. Can you please try:
not using hover but another name -
pass in driver instead of relying on it being a global variable. For this you would use go_to(navbar_item, menu_item, driver)
Apparently hover.reset_actions() should also work - but this didn't work for me.
If these don't work, please share your site URL so I can try on your actual site or say what the error is and describe what happens.
I am building a front end which displays the row of data from sqlite database. For backend, I am using flask. I have a check button on the front end. What I need to do is to display the data one by one as I click the check button.
I would do something like this:
The first thing I would do would be to define an address in Flask that send the information that you want to the browser.
#app.route('/get_info')
def get_info():
df = query_your_db()
return df.to_json(orient = 'split')
And in javascript I would call this address when I press de button like this:
function render_info() {
console.log('render_info()');
$.post('get_info', function(data_json)
{
window.info= JSON.parse(data_json);
$('#name_div').append(info);
}
);
}
And the html button would be like this:
<a id="get_info_button" onclick="render_info()"></a>
Hope it helps you
I have written a Python Telegram program but I need a bit of help on navigating the inline keyboard. When user clicks on one of the custom keyboard button [Feedback], an inline keyboard appears:
"Message: Do you find this app useful"
[No], [Yes], [Leave Comments].
When pressing [No], only a text message appears "Thank you and we hope you can leave some comments how to improve the app", goes back to main menu.
When pressing [Yes], a second inline button message appears with wording "Please vote for this app!" which hyperlinks to external website.
When pressing [Leave Comments], user needs to type in comments which is saved into a database.
My problem is upon pressing any of the 3 inline button, it leads to the same function "insert_UserFeedback".
Part of my codes as follows.
keyboard03 = [[InlineKeyboardButton("No", callback_data='no'),
InlineKeyboardButton("Yes", callback_data='yes')],
[InlineKeyboardButton("Leave Comments", callback_data='comments')]]
reply_markup03 = InlineKeyboardMarkup(keyboard03)
update.message.reply_text('Do you find the app useful?',
reply_markup=reply_markup03)
user = update.message.from_user
return FEEDBACK
At conv_handler states={
FEEDBACK: [MessageHandler(Filters.text,
insert_UserFeedback,
pass_user_data=True),
def insert_UserFeedback(bot, update, user_data):
user = update.message.from_user
#some codes..
sql10 = "UPDATE `subscribers` SET `feedback`='" + userFeedbackTxt + "',
`feedbackDate`='" + todaydatestamp + "' WHERE `id`=" + str(user.id) + ";"
cc.execute(sql10)
copp.commit()
copp.close()
update.message.reply_text(user.first_name + ', thank you for your feedback!')
return KEYBOARDVAL
So regardless if I choose which inline button I chose, "insert_UserFeedback" is called which then requires user to write a comment, because the program did not know in advance which inline button was selected.
The response object InlineQuery has a field query where the result of the user action is returned. Check the structure at Telegram API Inline Query
I need some hints to find a simple solution for inserting a popup window inside a python console app.
This app runs normally unattended, because it's done to be launched from crontab.
It uses everywhere logging to display messages and save them to logfiles.
However, in some cases, the app needs user intervention to choose some options when it is not able to find a suitable one.
That's why I inserted a --interactive option in argparse, and when the app needs user intervention, a popup window in console should appear, allowing the user to choose between some items in a list.
Here's an extract of the output to give you an example :
INFO : Try to fuzzy-match 'Orange Itbn'
INFO : Fuzzy-matched alternative entries : ['Orange Is The New Black']
INFO : Fuzzy matched 'Orange Itbn' as seriesname 'Orange Is The New Black'
INFO : MOVE /Users/spadazz/testing/orange itbn.s03e10.hdtv.720p.mkv TO:
/Volumes/NAS/TV Shows/Orange Is The New Black/S03/Orange Is The New Black.S03E10.hdtv.720p.mkv
INFO : Try to fuzzy-match 'Sur'
INFO : Fuzzy-matched alternative entries : ['Survivors 2008', 'Survivors']
WARNING :
Series 'Sur' not uniquely matched in titles
Choose between these titles :
['Survivors 2008', 'Survivors']
WARNING :
******************************************
**** INSERT HERE THE CALL TO THE POPUP ***
******************************************
Now, I've read some documentation about tkinter, curses and npyscreen but I wasn't able to come up with something simple for this purpose.
I don't wanna mess with the app structure or put the log messages in a main window..
I just wanna a popup that allows me to choose between some options, even with a simple keypress like '1' and '2' etc...
This should be a python solution too, possibly without calling external commands from os.
Any ideas ??
Thanks
With a little help from Nicholas Cole, who wrote npyscreen, I was able to fix this :
import npyscreen as np
class myPop(np.NPSApp):
def setopt(self, title, oList, multi):
self.title = title
self.options = oList
self.multi = multi
self.height = len(self.options)+1
def main(self):
F = np.Popup(name="Choose an option")
if self.multi:
opt = F.add(np.TitleMultiSelect, name=self.title, max_height=self.height, values=self.options, scroll_exit=True)
else:
opt = F.add(np.TitleSelectOne, name=self.title, max_height=self.height, values=self.options, scroll_exit=True)
F.edit()
self._values = opt.get_selected_objects()
self.result = ( self._values if self.multi and len(self._values) > 1 else self._values[0] )
def ChooseOption(title, oList, multi=False):
pop = myPop()
pop.setopt(title, oList, multi)
pop.run()
return pop.result
# Show a popup with radiobuttons to select 1 item from a list
print ChooseOption('choose a single element', ['a','b','c','d'])
# Show a popup with radiobuttons to multi-select items from a list
print ChooseOption('choose multi-elements', ['a','b','c','d'], True)
Hope this helps.
Enrico
Since npyscreen was written to make that kind of thing really simple, I'd use npyscreen. :)
The example code here is almost exactly what you are asking for.
I want to launch a warning using tkMessageBox in Python3. This warning is supposed to launch when a user doesn't select an element from a listbox. Unfortunately whenever I try to implement message box it does not launch like it is supposed to. I have code for a script called pietalkgui.py which contains the code where I want to implement the message box:
from tkinter import messagebox
# Gives warning if no user is selected for whisper
def whisperwarning(self):
# show warning to user
showwarning("Select User","Select a user to whisper to!")
# Handles whisper
def whispermessage(self):
# stores element selected in temp variable
temp = self.userslist.get(self.userslist.curselection())
# if no item is selected from userslist (listbox)
if temp == "":
# launch warning to user if no item is selected
self.whisperwarning()
else:
# retrieves usernames from userslist
username = temp
# storing whisper
outwhisper = ' /w "' + username +'" ' + self.messagebox.get("0.0",END)
# handling whisper
self.handler(outwhisper)
# erase message in message box
self.messagebox.delete("0.0",END)
Am I doing something wrong in the implementation of tkMessageBox? Or am I not properly checking if not item is selected from the listbox?
It appears that you are calling the method showwarning, but haven't defined it or imported it. That is the name of a function the messagebox module, so perhaps you need to change this:
showwarning("Select User","Select a user to whisper to!")
... to this:
messagebox.showwarning("Select User","Select a user to whisper to!")
Also, FWIW, this code is slightly incorrect: self.messagebox.delete("0.0",END) -- text indices start at "1.0", not "0.0".