Responding to multiple mouse clicks to produce a different output - Tkinter - button

I'm working on a problem requiring me to create a GUI (in Tkinter) which shows a different word in the label (referencing from a list) each time the button is pressed.
I've tried researching and have found similar problems but haven't found a working solution yet. I have tried 'for each' and 'while' loops, and 'if' statements, but haven't been able to get the code working correctly.
the_window.counter = 0
if the_window.counter == 0:
top_label['text'] = words [0]
the_window.counter + 1
elif the_window.counter == 1:
top_label['text'] = words [1]
the_window.counter + 1
the code shown above produces the first word in the list only, and multiple clicks don't have any effect. does anyone have any ideas?
Thanks.

You need need to keep a global counter, and update it each time it is clicked.
The following code illustrates the technique:
# initialized to -1, so that the first time it is called
# it gets set to zero
the_window_counter = -1
def handle_click():
global the_window_counter
the_window_counter += 1
try:
top_label.configure(text=words[the_window_counter])
except IndexError:
top_label.configure(text="no more words")

Related

I need help for gamemaker 2.3

Pls help me
A few weeks ago it came out of gamemaker 2.3, practically in the gamemaker language they changed the scripts into functions, but now after converting the files to be able to reopen them, I double-checked all the scripts and etc but anyway when I start it it remains a black screen, however it doesn't give me any compilation errors or whatever, what could be the problem?
Ps.
I might sound stupid, but if someone has the same program as me I can pass the project to them so they can see the scripts for themselves, so basically it's just the base and there is only the script to make the player walk and for collisions, I know that no one would want to waste time, but I ask the same
Its possible that your code is stuck in an infinite loop, here's an example of what that might look like:
var doloop = true
while(doloop == true){
x += 1
y += 1
}
the "doloop" variable is never changed within the while loop, so it is always equal to true and the loop never ends. Because the code never finishes looping, it can never get around to drawing anything, so you end up with a black screen. The easiest way to check for these is to put a breakpoint/debugging point at the beginning and just after every while/for/do/ect loop and debug it. e.g. (I am using asterisks "*" to represent breakpoints)
var doloop = true
* while(doloop == true){
x += 1
y += 1
}
*
When you get to one of the loops remove the first breakpoint and hit the "continue" button in the debugger. If it (it being the computer) takes an longer than it should to hit the second breakpoint (as in, you wait for a ten seconds to or two minutes (depends on how complex the code is) and it still hasn't hit the second breakpoint), then you should replace the breakpoint at the beginning of the loop to check and make sure it is still in there. If it is still in the loop, then that is likely where the code is getting stuck. Review the loop and everywhere any associated variables are set/changed, and you should be able to find the problem (even if it takes a while).
Majestic_Monkey_ and the commentors are correct: use the debugger. It's easy and it's your friend. Just place a red circle on the very first line of code that runs, and click the little bug icon and you can step through your code easily.
But to address your specific issue (or if anyone in the future has this issue): scripts have changed into files that can have many functions. Where you used to have
//script_name
var num = argument0 + argument1;
return num;
You would now have
function script_name(a, b) {
var num = a + b;
return num;
}
All you have to do is create a decleration for your new function:
function my_function_name(argument_names, etc...)
Then wrap all your old code in { }, and replace all those ugly "argument0" things with actual names. It's that easy. Plus you can have more than one function per script!

Multiple altair charts generated by the same cell

I have a list of pandas dataframes I named entries, which I want to visualize after running code from the same cell. Below is the code I used :
alt.data_transformers.disable_max_rows()
for entry in entries :
entry['ds'] = entry.index
entry['y'] = entry['count']
entry['floor'] = 0
serie = alt.Chart(entry).mark_line(size=2, opacity=0.7, color = 'Black').encode(
x=alt.X('ds:T', title ='date'),
y='y'
).interactive().properties(
title='Evolution of '+entry.event.iloc[0]+' events over time'
)
alt.layer(serie)\
.properties(width=870, height=450)\
.configure_title(fontSize=20)
When i run the same code out of the 'for' loop, I get to see the one chart that corresponds to one dataframe, but once I run the code above, I don't get any graphs at all.
Does anyone know why It's not working or how to solve this issue?
TLDR: use chart.display()
Unless a chart appears at the end of the cell, you must manually display it.
By analogy, if you run
x + 1
by itself, Python will display the result. However, if you run
for x in range(10):
x + 1
Python will not display anything, because the last statement in the cell (in this case the for loop) has no return value to display. Instead you have to write
for x in range(10):
print(x + 1)
For altair, the mechanism is similar: if the chart is defined in the last statement in the cell, it will be automatically displayed. Otherwise, you have to manually trigger the display, which you can do using the display method:
for i in range(10:
chart = alt.Chart(...)
chart.display()
For more information on display troubleshooting in Altair, see https://altair-viz.github.io/user_guide/troubleshooting.html

How to fix List Box returning null value using UIA wrapper

I want to access text values from a List BOX (pywinauto uia wrapper)that is nested inside LIST view inside the application used.
code snippet:
#upper window
up_window.ListView.wait('visible').Select('Enforcement').click_input(double=True)
time.sleep(5)
#after this enforcement window opens and i need to select the third tab which is performed below and its working fine.
enfwin = guilib.get_window('Enforcement', backend='uia')
# guilib is user defined library which will retun the window handle
if enf_win.TabControl.get_selected_tab() != 2:
log.debug("Clicking on 'Targets' tab in Enforcement window")
enf_win.TabControl`enter code here`.wait('enabled', timeout=60).select(2)
time.sleep(30)
list_rows = enf_win.ListBox.wait('ready', timeout=60).texts()
dcs_win.ListView.wait('visible').Select('Enforcement').click_input(double=True)
time.sleep(5)
enf_win = guilib.get_window('Enforcement', backend='uia')
if enf_win.TabControl.get_selected_tab() != 2:
log.debug("Clicking on 'Targets' tab in Enforcement window")
enf_win.TabControl.wait('enabled', timeout=60).select(2)
time.sleep(30)
list_rows = enf_win.ListBox.wait('ready', timeout=60).texts()
The problem here is, when I am calling this function two times from script, 1 st run its fetching the list_rows whereas in second run its returning blank. It seems like it needed some time in between. But increasing time is not helping.
Please suggest if any modification I need to do to fetch list box value each time.

Fill-In validation with N format

I have a fill-in with the following code, made using the AppBuilder
DEFINE VARIABLE fichNoBuktiTransfer AS CHARACTER FORMAT "N(18)":U
LABEL "No.Bukti Transfer"
VIEW-AS FILL-IN NATIVE
SIZE 37.2 BY 1 NO-UNDO.
Since the format is N, it blocks the user from entering non-alphanumeric entries. However, it does not prevent the user from copypasting such entries into the fill-in. I have an error checking like thusly to prevent such entries using the on leave trigger:
IF LENGTH(SELF:Screen-value) > 18 THEN DO:
SELF:SCREEN-VALUE = ''.
RETURN NO-APPLY.
END.
vch-list = "!,*, ,#,#,$,%,^,&,*,(,),-,+,_,=".
REPEAT vinl-entry = 1 TO NUM-ENTRIES(vch-list):
IF INDEX(SELF:SCREEN-VALUE,ENTRY(vinl-entry,vch-list) ) > 0 THEN DO:
SELF:SCREEN-VALUE = ''.
RETURN NO-APPLY.
END.
END.
However, after the error handling kicked in, when the user inputs any string and triggers on leave, error 632 occurs:
error 632 occurs
Is there any way to disable the error message? Or should I approach the error handling in a different way?
EDIT: Forgot to mention, I am running on Openedge version 10.2B
You didn't mention the version, but I'll assume you have a version in which the CLIPBOARD system handle already exists.
I've simulated your program and I believe it shouldn't behave that way. It seems to me the error flag is raised anyway. My guess is even though those symbols can't be displayed, they are assigned to the screen value somehow.
Conjectures put aside, I've managed to suppress it by adding the following code:
ON CTRL-V OF FILL-IN-1 IN FRAME DEFAULT-FRAME
DO:
if index(clipboard:value, vch-list) > 0 then
return no-apply.
END.
Of course this means vch-list can't be scoped to your trigger anymore, in case it is, because you'll need the value before the leave. So I assigned the special characters list as an INIT value to the variable.
After doing this, I didn't get the error anymore. Hope it helps.
To track changes in a fill-in I always use at first this code:
ON VALUE-CHANGED OF FILL-IN-1 IN FRAME DEFAULT-FRAME
DO:
/* proofing part */
if ( index( clipboard:value, vch-list ) > 0 ) then do:
return no-apply.
end.
END.
You could add some mouse or developer events via AppBuilder to track changes in a fill-in.

Lua: Doing arithmetic in for k,v in pairs(tbl) loops

I have a table such as the following:
mafiadb:{"Etzli":{"alive":50,"mafia":60,"vigilante":3,"doctor":4,"citizen":78,"police":40},"Charneus":{"alive":29,"mafia":42,"vigilante":6,"doctor":14,"citizen":53,"police":33}}
There are more nested tables, but I'm just trying to keep it simple for now.
I run the following code to extract certain values (I'm making an ordered list based on those values):
sortmaf={}
for k,v in pairs(mafiadb) do
sortmaf[k]=v["mafia"]
end
That's one of the codes I run. The problem I'm running into is that it doesn't appear you can do arithmetic in a table loop. I tried:
sortpct={}
for k,v in pairs(mafiadb) do
sortpct[k]=(v["alive"]*100)/(v["mafia"]+v["vigilante"]+v["doctor"]+v["citizen"]+v["police"])
end
It returns that I'm attempting to do arithmetic on field "alive." What am I missing here? As usual, I appreciate any consideration in answering this question!
Editing:
Instead of commenting on the comment, I'm going to add additional information here.
The mafiadb database I've posted IS the real database. It's just stripped down to two players instead of the current 150+ players I have listed in it. It's simply structured as such:
mafiadb = {
Playername = {
alive = 0
mafia = 0
vigilante = 0
doctor = 0
police = 0
citizen = 0
}
}
Add a few hundred more playernames, and there you have it.
As for the error message, the exact message is:
attempt to perform arithmetic on field 'alive' (nil value)
So... I'm not sure what the problem is. In my first code, the one with sortmaf, it works perfectly, but suddenly, it can't find v["alive"] as a value when I'm trying to do arithmetic? If I just put v["alive"] by itself, it's suddenly found and isn't nil any longer. I hope this clarifies a bit more.
This looks like a simple typo to me.
Some of your 150 characters is not well written - probably they don't have an "alive" property, or it's written incorrectly, or it's not a number. Try this:
for k,v in pairs(mafiadb) do
if type(v.alive) ~= 'number' then
print(k, "doesn't have a correct alive property")
end
end
This should print the names of the "bad" characters.

Resources