I'm very new to Python, so I'm sorry ahead of time if this is a simple mistake.
class TaskTabs(QtGui.QTabWidget):
...(some init stuff here)....
def remove(self):
self.removeTab(0)
self.addTab(Tabs.General(self.nao, self.parent), 'General')
In another class:
self.taskTabs = TaskTabs(self.nao, mainWidget)
....(Some other stuff here)....
loadEmpathy = QtGui.QAction(QtGui.QIcon(), '&Load Empathy', self)
loadEmpathy.setShortcut('Ctrl+E')
loadEmpathy.triggered.connect(self.taskTabs.remove())
There error that I am getting is:
TypeError: connect() slot argument should be a callable or a signal, not 'NoneType'
What I am trying to do is to remove a tab in my GUI and add in various ones (which I'll implement later, just testing this now) from a menu. My menu code works perfectly, and now I want to set an action for what happens when it's clicked. I created this remove method in my TaskedTabs file, the remove function works great in my init function, but I want to separate it (for purposes later on). Can anyone explain what is wrong with my code?
As the error message says, connect() needs a callable method. But what you are giving it is the result of a method, because you're calling it. remove() returns None, which is then used as the argument for connect(), which doesn't work. Solve this by removing the brackets after remove.
loadEmpathy.triggered.connect(self.taskTabs.remove)
Related
I have been developing a full-stack application that checks for files and uploads them to a cloud. However, I have come across an interesting problem that I was not able to solve.
I have a problem with instantiating a class, as you will see below:
class UploadFastq:
def __int__(self,
some_list, some_str, some_obj, **kwargs):
self.some_list = some_list
self.some_obj = some_obj
self.some_str = some_str
def process(self):
self.some_methods_calling_processes()
...
As you can imagine, I have trimmed the original code for privacy concerns (company dictates, sorry). This class is to handle some-backend related processes, and arguments only contain back related variables. Also, this class is on the different py script, which imports again back-related functions.
Now, the problem is, when I import to another script and try to call and instantiate the class, something funny happens...
from lib.some_back_related_script import UploadFastq
uploads = UploadFastq(some_list=the_list,some_str=the_str,some_obj=the_obj)
uploads.process
OUTPUT:
TypeError: UploadFastq() takes no arguments
I have looked if there are indentation problems, I could not find any. (I am using PyCharm as IDE, and reformatting the file also did not solve)
I have also tried this on an another script(the gui script) and could partially solve it as:
from lib.some_back_related_script import UploadFastq
uploader = UploadFastq()
uploader.__int__( ##TODO how is this possible???)
some_list=the_list,some_str=the_str,some_obj=the_obj
)
However, on the script the class suppose to be called, "__init__" method did not solve the case, and produced this error:
TypeError: UploadFastq.__init__() takes exactly one argument (the instance to initialize)
At this point I am clueless about what is going on and how to solve it. I have experiencing something like this for first time. I also could not find this kind of problem on the internet. soo, I would be much grateful if you could explain how to approach the problem.
P.S.: I work as a bioinformatician/python developer for a quite time and I found many many solutions on this platform. But, this is actually my first question on the stackoverflow!!!
Cheers!
You mispelled the constructor name __init__ as __int__ :
def __int__(self, some_list, some_str, some_obj, **kwargs):
Thus the default constructor (which takes as arguments only the "instance to initialize") was called, and the interpreter is complaining about the given arguments.
TypeError: UploadFastq.__init__() takes exactly one argument (the instance to initialize)
I am using a library that takes some keyword arguments during the initialization of the object. These keyword arguments define the callback objects/functions that are called when a specific event occurs. The callback objects themselves need to reference the object that called them and have some additional data that comes from the class/object instance itself.
What I would like to do is pass a reference to another object into one of these call backs when initializing in order to avoid using a global variable.
How/where would I pass the reference to the object? Do I need to subclass? If I do need to subclass can I accomplish this without understanding the working behind the class/library? I tried looking at the source to try and figure something out but unfortunately it's a bit past my understanding.
Example which will hopefully get my point across:
def One(eI):
*...do some stuff...*
def Two(eI, data, ref_I_want_to_add):
*do some other stuff*
ref_I_want_to_pass = anotherClass(diff_arg,diff_arg2):
*...you know the deal...*
eI = exampleClass(argOne=One, ..., argN=N)
The first thing that comes to mind is to use something like
eI = exampleClass(argOne=One, argTwo=Two(ref_I_want_to_pass), ..., argN)
But that obviously doesnt work because I get a TypeError: argTwo takes 0 positional arguments but 1 was given
More precisely I am using the websocket client library and in order to create a WebSocketApp object which handles the connection you instaniate the object with something like
ws = websocket.WebSocketApp(uri, on_open=on_open, on_message=on_message, on_ping=on_ping)
now I have a function named on_message that handles the incoming messages and I told the ws object during instantiation of WebSocketApp that I would like to use that function to handle the incoming messages or rather what to do with them.
I would like to update another object when a new message comes in, now I can of course use a global variable for that but it doesn't seem like the right way to do it and it would be nice if I could pass a reference to that object when initializing a WebSocketApp object, with something like:
ws = websock.WebSocketApp(uri, on_message=on_message(ref_to_Obj), on_open=on_open, on_ping=on_ping)
But obviously that doesnt work because again I get a TypeError: argTwo takes 0 positional arguments but 1 was given error.
I'm not entirely sure how to do this. Subclassing comes to mind but even then I'm kind of lost, I will admit that subclassing is a topic I need more work on, I get the idea behind it and can do all the basic examples they use in tutorials but more complex classes can stump me.
If you want a local variable to be passed onto a function, you need to create a closure around that variable. We can do that with lambda.
eI = exampleClass(argOne=One, ..., argN=lambda x, y: N(x, y, ref_I_want_to_pass))
This is my first question on StackOverflow. So far lurking was enough to solve all my problems.
I'm a python newbie and I don't fully understand the meaning behind 'self' yet.
I defined a function (not a method. It's not inside a class) as
def pcal_thresh(self):
p_th = p_thresh.get()
print('p_th')
I am trying to use it in 2 separate conditions. First as a command for Tkinter
p_thresh = tk.Scale(calibration, from_=255, to=1, length=int(y_height*1.2), command=pcal_thresh)
Second, inside another function
def confirm():
if not top_distance == 0:
pcal_thresh()
In this exact configuration the function "pcal_thresh()" executes correctly as a Tkinter command, but not inside another function. If I remove 'self' from the declaration, it's the opposite. Works fine when used inside a function, but not as a Tkinter command. What can be the issue here?
self does not have a default value, so even if you don't use it, you still need to provide a value when you call pcal_thresh. As a callback, it receives the new scale value when called.
Either provide a dummy argument
def confirm():
if not top_distance == 0:
pcal_thresh(None)
or provide a default value:
def pcal_thresh(self=None):
p_th = p_thresh.get()
print('p_th')
I have a GtkComboBox's changed signal connected to the following function:
def changeCombo(self, widget):
selected = self.ui['comboBox'].get_active_iter()
...
This sort-of-works. However, when the combo's associated model -- a ListStore -- is emptied (and rebuilt), I get this error when the function is invoked:
AttributeError: 'gtk.TreeView' object has no attribute 'get_active_iter'
Thereafter, the code destabilises and stops working properly. (If you select a valid entry, before getting this warning, it works fine.)
What's going on here? I realise the combobox is probably implemented as a TreeView by GTK, but get_active_iter is definitely a member of ComboBox... Does this error imply that the availability of this function is contingent on the model containing items? The documentation, however, implies that a combobox without a selection (or an empty model) should return None for get_active_iter.
I have a small app with a table. This table has some data and a button on each row. These buttons should allow the user to remove corresponding row data. I'm trying to implement it via the clicked button signal, but I need to pass the row number, so I tried using QSignalMapper, as shown in the excerpt below
btnRemoveItem = QPushButton()
btnRemoveItem.clicked.connect(self.removeItem)
self.mapper = QSignalMapper(self)
self.connect(btnRemoveItem, QtCore.SIGNAL("clicked()"), self.mapper,
QtCore.SLOT("map()"))
self.mapper.setMapping(btnRemoveItem, nextRow)
self.connect(self.mapper, QtCore.SIGNAL("mapped(int)"), self.removeItem(),
QtCore.SIGNAL("clicked(int)"))
Problem is, my removeItem(self, index) method is an instance method (because my table belongs to a specific class) and I'm having trouble mapping it in a way I can pass self along with index.
Currently, my code fails with the following error:
TypeError: removeItem() takes exactly 2 arguments (1 given)
Is there a way to make this work correctly? Or is it impossible to map instance methods with QSignalMapper in PySide?
I tried to reproduce your code in PyQt but I'm not fully aware of the differences between Pyside and PyQt so my answer is more of a guess.
Try to remove the second line of your code and replace the last one with:
self.mapper.mapped.connect(self.removeItem)
In the last line of your code, in the connect method, I believe you have a typo in your code
self.connect(self.mapper, QtCore.SIGNAL("mapped(int)"), self.removeItem(),
QtCore.SIGNAL("clicked(int)"))
should be
self.connect(self.mapper, QtCore.SIGNAL("mapped(int)"), self.removeItem,
QtCore.SIGNAL("clicked(int)"))
Having self.removeItem() in the connect method will actually try to call the self.removeItem method rather than providing the subsystem an address to connect the function
As finmor suggests, you should look at new syntax signals and slots as they will dramatically help to clarify your code and make it more Pythonic.