Pyside2 receivers func - pyside

For the below 2 examples for receivers functions, the result for the destroyed signal is correct.
As I already connect the ObjectNameChanged signal, why the output is 0 ?
self.signal_obj = QObject()
def destroy_slot_handler():
print("The object is destroyed.")
self.signal_obj.destroyed.connect(destroy_slot_handler)
print(self.signal_obj.receivers(SIGNAL("destroyed()")))
The output is "1"
def name_changed_slot_handler(name):
print("The name of object is changed.", name)
self.signal_obj.objectNameChanged.connect(name_changed_slot_handler)
print(self.signal_obj.receivers(SIGNAL("objectNameChanged()")))
The output is "0"

objectNameChanged has a QString argument; even if the connected function/slot won't use it, the signal signature still requires that argument.
If you call the macro with the proper argument type(s), it will work as expected:
>>> print(self.signal_obj.receivers(SIGNAL("objectNameChanged(QString)")))
1

Related

Problems interrupting a python Input (Mac)

I am trying to allow a user to input multiple answers but only within an allocated amount of time. The problem is I have it running but the program will not interrupt the input. The program will only stop the user from inputing if the user inputs an answer after the time ends. Any ideas? Is what I am trying to do even possible in python?
I have tried using threading and the signal module however they both result in the same issue.
Using Signal:
import signal
def handler(signum, frame):
raise Exception
def answer_loop():
score = 0
while True:
answer = input("Please input your answer")
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
try:
answer_loop()
except Exception:
print("end")
signal.alarm(0)
Using Threading:
from threading import Timer
def end():
print("Time is up")
def answer_loop():
score = 0
while True:
answer = input("Please input your answer")
time_limit = 5
t = Timer(time_limit, end)
t.start()
answer_loop()
t.cancel()
Your problem is that builtin input does not have a timeout parameter and, AFAIK, threads cannot be terminated by other threads. I suggest instead that you use a GUI with events to finely control user interaction. Here is a bare bones tkinter example.
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text='answer')
entry = tk.Entry(root)
label.pack()
entry.pack()
def timesup():
ans = entry.get()
entry.destroy()
label['text'] = f"Time is up. You answered {ans}"
root.after(5000, timesup)
root.mainloop()

Tkinter grid and time.sleep()

I would like a label to be .grid() then the program to wait 3 seconds and then .grid_forget(). I am very confused at the point .grid is executed. For example:
def remove_choice(self):
while True:
try:
get = int(self.entry_remove_choice.get())
except ValueError:
self.label_error_remove.grid(row=10,column=6) #A
time.sleep(3)
self.label_error_remove.grid_forget() #B
#Empty entry box
break
else:
#continue code
break
Once the button is pressed and remove_choice is executed, the button is displayed to be pressed in for three seconds then #A and #B are executed in one go and nothing is displayed.
If #B is removed then the error message is displayed after three seconds.
If #A and #B are swapped for print to terminal then program works how you would think, with one message, a wait of three seconds, then another message.
If you do a very sloppy solution (which Im not that bothered about for this program) and do this:
def remove_choice(self):
while True:
try:
get = int(self.entry_remove_choice.get())
except ValueError:
self.label_error_remove.grid(row=10,column=6) #A
for n in range (1,1000):
print("abc")
self.label_error_remove.grid_forget()
break
else:
#continue code
break
When executed "abc" is printed 1000 times taking around 1.5 seconds and then after this the program displays the grid.
Any suggestions to how to make TKinter wait please.
Also can someone explain why grid works like this, thanks.
Rather than trying 'forgetting' the label each time, why not just clear the error message text?
My example below will wait for the user to press the button and display the error message for 3 seconds. I'm using the .after method to schedule the hideError method 3 seconds (3000 ms) after the error message is displayed.
try:
import tkinter as tk
except:
import Tkinter as tk
import time
class App(tk.Frame):
def __init__(self,master=None,**kw):
tk.Frame.__init__(self,master=master,**kw)
self.errorMessage = tk.StringVar()
self.ErrorLabel = tk.Label(textvar=self.errorMessage)
self.ErrorLabel.grid()
self.button = tk.Button(text="Press Me",command=self.showError)
self.button.grid()
def showError(self):
# Disable the button and show the error message
self.button['state'] = tk.DISABLED
self.errorMessage.set("Error Message!!!!")
self.after(3000,self.hideError)
def hideError(self):
#Enable the button and clear the error message.
self.button['state'] = tk.NORMAL
self.errorMessage.set("")
if __name__ == '__main__':
root = tk.Tk()
App(root).grid()
root.mainloop()
It is considered bad practice to use while True loops or time.sleep inside GUI applications. They prevent the GUI from updating so in your code both actions appear to happen at the same time because the time.sleep operation is blocking the GUI and preventing the screen from being redrawn.
EDIT: Passing arguments from callbacks.
Current problem is that the after method expects to receive a reference to a function. self.hideError(3) returns NoneType not reference to a function call. We can solve this using anonymous functions and lambda.
I've started to use this snippet of code to help, its from guizero
def with_args( func_name, *args):
"""Helper function to make lambda functions easier
Thanks to guizero"""
return lambda: func_name(*args)
Then in your main section of code the line would look like this.
self.after(3000,with_args(self.hideError,3))
EDIT: There is an even simpler way. The .after method can take arguments itself.
self.after(3000,self.hideError,3)

Expected type '{__name__}', got '() -> None' instead

I have a question about my Python(3.6) code or PyCharm IDE on MacBook
I wrote a function using "timeit" to test time spent by other function
def timeit_func(func_name, num_of_round=1):
print("start" + func_name.__name__ + "()")
str_setup = "from __main__ import " + func_name.__name__
print('%s() spent %f s' % (func_name.__name__,
timeit.timeit(func_name.__name__ + "()",
setup=str_setup,
number=num_of_round)))
print(func_name.__name__ + "() finish")
parameter "func_name" is just a function need to be tested and has already been defined.
and I call this function with the code
if __name__ == "__main__":
timeit_func(func_name=another_function)
the function works well, but pycharm show the info with this code "func_name=another_function":
Expected type '{__name__}', got '() -> None' instead less... (⌃F1 ⌥T)
This inspection detects type errors in function call expressions. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases. Types of function parameters can be specified in docstrings or in Python 3 function annotations
I have googled "Expected type '{name}', got '() -> None" but got nothing helpful.I am new on Python.
I want to ask what it means? And how can I let this information disappear? because now it is highlighted and let me feel uncomfortable.
I use it in Python3.6 byimport time,this is what I found in the doc of timeit module()(timeit.timeit())
def timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number, globals=None):
"""Convenience function to create Timer object and call timeit method."""
return Timer(stmt, setup, timer, globals).timeit(number)
Your parameter func_name is badly named because you are passing it a function, not the name of a function. This probably indicates the source of your confusion.
The error message is simply saying that pycharm is expecting you to pass an object with an attribute __name__ but it was given a function instead. Functions do have that attribute but it is part of the internal detail, not something you normally need to access.
The simplest solution would be to work with the function directly. The documentation for timeit isn't very clear on this point, but you can actually give it a function (or any callable) instead of a string. So your code could be:
def timeit_func(func, num_of_round=1):
print("start" + func.__name__ + "()")
print('%s() spent %f s' % (func.__name__,
timeit.timeit(func,
number=num_of_round)))
print(func.__name__ + "() finish")
if __name__ == "__main__":
timeit_func(func=another_function)
That at least makes the code slightly less confusing as the parameter name now matches the value rather better. I don't use pycharm so I don't know if it will still warn, that probably depends whether it knows that timeit takes a callable.
An alternative that should get rid of the error would be to make the code match your parameter name by actually passing in a function name:
def timeit_func(func_name, num_of_round=1):
print("start" + func_name + "()")
str_setup = "from __main__ import " + func_name
print('%s() spent %f s' % (func_name,
timeit.timeit(func_name + "()",
setup=str_setup,
number=num_of_round)))
print(func_name + "() finish")
if __name__ == "__main__":
timeit_func(func_name=another_function.__name__)
This has the disadvantage that you can now only time functions defined and importable from in your main script whereas if you actually pass the function to timeit you could use a function defined anywhere.

Function with record as argument

I know this is very basic, but it's driving me up a wall:
peercert is defined as:
peercert(Socket) -> {ok, Cert} | {error, Reason}
Types
Socket = sslsocket()
Cert = binary()
The peer certificate is returned as a DER-encoded binary. The certificate can be decoded with public_key:pkix_decode_cert/2.
Ok, great. sslsocket is defined as -record(sslsocket, {fd = nil, pid = nil})
So I run :
New = #sslsocket{pid = Pid},
io:fwrite("~n~npeercert~p~n~n", [ssl:peercert(New)]).
But I get an error that
no function clause matching ssl:peercert({sslsocket,<0.1277.0>,undefined})
So I run it with Pid as an argument and get a similar error:
no function clause matching ssl:peercert(<0.1277.0>)
I'm totally stumped here. I had it working before, the function says it takes these as arguments...
Thank you for your help in advance!
sslsocket() type is not a record called sslsocket, otherwise it would be written as #sslsocket{}. It's a "black box type" (its real type is an implementation detail), but you can obtain it from function ssl:connect().

How do I create a file using sudo and write into it?

I created a bash script file:
#!/bin/bash
default_card=`head -1 /proc/asound/modules`
echo $default_card
if [ ! -e /etc/modprobe.d/sound.blacklist.conf ] ; then
echo "Default sound card(snd_hda_intel) is not added in black list"
/usr/bin/expect <<delim
exp_internal 0
set timeout 20
spawn sudo sh -c "echo 'blacklist snd_hda_intel' > /etc/modprobe.d/sound.blacklist.conf"
expect "password for ubuntu:"
send "1234\n"
expect eof
delim
else
echo "Default sound cardis already added in black list";
fi
I am creating a black list file in "/etc/modprobe.d". Creating or deleting any file from "/etc" requires sudo access.
I want to implement the same functionality in Ruby using a Rake task. I created the task as:
desc "Check/creates soundcard blacklist"
task :create_blacklist do
begin
if !File.exists?("/etc/modprobe.d/sound.blacklist.conf")
# code for creating new file and write into it
......
......
else
puts "Sound-card blacklist file is present at /etc/modprobe.d/sound.blacklist.conf"
end
rescue Exception => e
puts "problem creating file #{e.message}"
end
end
I don't know how to create new file using sudo, and write into it.
I am using Ruby 1.9.3 (without RVM).
Look at https://stackoverflow.com/a/18366155/128421, https://stackoverflow.com/a/18398804/128421, and "communicating w/ command-line program (OR ruby expect)" for more information.
Ruby's IO class implements expect but it's not too full-featured:
=== Implementation from IO
------------------------------------------------------------------------------
IO#expect(pattern,timeout=9999999) -> Array
IO#expect(pattern,timeout=9999999) { |result| ... } -> nil
------------------------------------------------------------------------------
Reads from the IO until the given pattern matches or the timeout is over.
It returns an array with the read buffer, followed by the matches. If a block
is given, the result is yielded to the block and returns nil.
When called without a block, it waits until the input that matches the given
pattern is obtained from the IO or the time specified as the timeout passes.
An array is returned when the pattern is obtained from the IO. The first
element of the array is the entire string obtained from the IO until the
pattern matches, followed by elements indicating which the pattern which
matched to the anchor in the regular expression.
The optional timeout parameter defines, in seconds, the total time to wait for
the pattern. If the timeout expires or eof is found, nil is returned or
yielded. However, the buffer in a timeout session is kept for the next expect
call. The default timeout is 9999999 seconds.

Resources