Will signals automatically disconnect, when target object is destroyed? Without recording the signal id from g_signal_connect(), can I remove that signal?
If you didn't save the signal handler ID, you can search for it using g_signal_handler_find() and disconnect it the usual way, or disconnect any signals that match certain criteria with g_signal_handlers_disconnect_matched() or g_signal_handlers_disconnect_by_func().
Of course when the target object is destroyed, the signals connected to it are removed (otherwise there would be a massive memory leak, but read the warning on g_signal_connect_object). However, to call g_signal_handler_disconnect you need the handler id given by g_signal_connect and friends.
You can use the *handler_block_by_func* and *handler_unblock_by_func* methods.
Example (PyGTK):
def on_treeview_fixedexpenses_cursor_changed(self, widget):
self.checkbutton_fixedexpensetax.handler_block_by_func(self.on_checkbutton_fixedexpensetax_toggled)
self.updateCurrentFixedExpense()
self.checkbutton_fixedexpensetax.handler_unblock_by_func(self.on_checkbutton_fixedexpensetax_toggled)
Source: http://www.pygtk.org/docs/pygobject/class-gobject.html
Related
I am new to STM32 and freertos. I need to write a program to send and receive data from a module via UART port. I have to send(Transmit) a data to that module(for eg. M66). Then I would return to do some other tasks. once the M66 send a response to that, my seial-port-receive-function(HAL_UART_Receive_IT) has to be invoked and receive that response. How can I achieve this?
The way HAL_UART_Receive_IT works is that you configure it to receive specified amount of data into given buffer. You give it your buffer to which it'll read received data and number of bytes you want to receive. It then starts receiving data. Once exactly this amount of data is received, a callback function HAL_UART_RxCpltCallback gets called (from IRQ) where you can do whatever you want with this data, e.g. add it to some kind of queue for later processing in the task context.
If I was to express my experiences related to working with HAL's UART module is that it's not the greatest one for generic use where you don't know the amount of data you expect to receive in advance. In the case of M66 modem you mention, this will happen all the time.
To solve this you have two choices:
Simply don't use HAL functions at all in case of UART, other than the initialization functions. Implement your own UART interrupt handler (most of the code can be copied from handler in HAL) where upon receiving data you place received bytes in a receive byte queue handled in your RTOS task. In this task you implement protocol parsing. This is the approach I use personally.
If you really want to use HAL but also work with a module that sends varying amount of data, call HAL_UART_Receive_IT and specify that you want to receive 1 byte each time. This will work, but will be (potentially much) slower than the first approach. Assuming you'll later want to implement some tcp/ip communication (you mentioned M66 GPRS module) you probably don't want to do it this way.
You should try the following way.
Enable UARTX Rx interrupt in NVIC.
Set Interrupt priority.
Unmask Interrupt request in EXTI.
Then use USARTX Interrupt Handler Function Define in you Vector.
Whenever the data is received from USARTX this function get automatically called and you can copy data from USARTX Receive Data Register.
I would rather suggest another approach. You probably want to archive higher speeds (lets say 921600 bods) and the interrupt way is fat to slow for it.
You need to implement the DMA transmition with the data end detection features. Run your USART in the DMA mode in the circular mode. You will have two events to serve. The first one is the DMA end of thransmition interrupt (then you copy the data from the current tail pointer to the end of the buffer to avoid data override) and USART IDLE interrupt - this will detect the end of the receive.
As we all know,the Hal Lib provides some callback function to manage hardware interrupt.But i don't know how them work?
Te fact is that I am using HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) this function so as to receive other devices' data and check those data.So I use the usart interrupt to receive them.
But I don't know when the callback function will be executed,is it depends on the receive buffer's length or the data's buffer?
I guess the hardware interrupt will be triggered while a character has been received,but the callback function will be executed after the receive buffer is full.
PS:I am using the stm32-nucleo-f410 development board to communicate with an AT commend device,and I am a novice about it.
(So sorry for my poor English!)
Thanks a lot.
The callback you are referring to is called when the amount of data specified in the receive functions (the third argument to HAL_UART_Receive_IT). You are correct that the UART interrupt service routine (ISR) is called every time a character is received, but when using the HAL that happens internally to the library and doesn't need to be managed by you. Every time the ISR is called, the received character is moved into the array you provide via the second argument of HAL_UART_Receive_IT, and when the number of characters specified by the call is reached, the callback will be called in that ISR (so make sure not to do anything that will take too much time to complete - ISRs should be short, and the ISRs in the HAL library are already pretty lengthy to handle every possible use case).
Further, if you find that the callback is not being triggered even if you are sending enough data to the peripheral, make sure the interrupt is actually enabled - the HAL_UART_Receive_IT function doesn't actually enable the interrupt, that has to be done during initialization of the peripheral.
I have the following code fragments:
win = new Gtk::Window;
m_canvas = new Goocanvas::Canvas;
sigc::connection conn_t1 = m_canvas->signal_event().connect( sigc::ptr_fun( &AnyEvent));
sigc::connection conn_t2 = win->signal_event().connect( sigc::ptr_fun( &WinHandler));
Now I also register an IdleHandler which generates signals:
Glib::signal_idle().connect( sigc::mem_fun( *this, &IdleSendEvent::Do));
What I want to achieve:
The handler of the canvas should receive an event and should generate a new one and this one should send to the object, so that it will call again the handler of the m_canvas->signal_event().
In other words: Indirectly via the Idle Handler the signal should be send to the sending object itself.
But if I fire to
g_signal_emit_by_name (m_canvas->gobj(), "button-press-event", event, &return_val);
the signal is not received in the canvas itself, but in some child objects there.
Q: How to emmit again to the canvas? Is there something like "get_the_parent_signal_object_handler_father_receiver" or something strange?
I did a lot of gtk_widget_get_parent_window() but all results in runtime errors like:
(go:15430): GLib-GObject-WARNING **: gsignal.c:3484: signal name 'button-press-event' is invalid for instance '0x9afbc48' of type 'GdkX11Window'
I simply have no idea where to find the correct instance which I have to emmit a signal which is then received for the canvas. It looks that the instance for g_signal_emit_by_name fires not to the object itself but all child instances. I can not find a documentation how the signals are processed and how the hierarchy can be walked through. One of the problems is that gtk+ and gtkmm are related but the documentation totally unclear and scattered.
You can't emit a signal to a particular object. You can only emit a signal from an object, that will be received by any signal handlers that are connected to that signal of the emitting object. Objects don't receive signals, only signal handlers do. (Although the signal handler may be, for example, a method of an object.)
The first argument of g_signal_emit_by_name() must be the emitting object.
To make a signal handler receive a signal, use g_signal_connect(emitter, signal_name, handler, user_data) or its C++ equivalent, sigc::signal::connect() as you have done in the example code above.
Is there any way to monitor all signals emitted from a widget with GTK3? I know that the event signal is emitted before an event, but I'm not sure of the distinction between "event" and "signal" in GTK terminology - as this does not seem to capture all signals.
I know GDK has a function gdk_set_show_events but this mostly shows events which are sent to the window from the operating system. Is there a GTK3 equivalent?
There is not built in function AFAIK, but I'm sure you can hack something together yourself:
Use g_signal_lookup to get all signal ids for a gtype. Then use g_signal_add_emission_hook on each signal of your instance to register a hook to be called whenever that particular signal is emitted. Inside the hook function, you're provided with the signal id via *ihint, from which g_signal_query should provide you with all the information you need to print debug messages. (I didn't test it, but it should work)
Note that this will unfortunately not work for signals defined with G_SIGNAL_NO_HOOKS.
Use g_signal_lookup to get all signal ids
It's a little more complicated than described. In order to use g_signal_lookup, you first need a signal-name. If you want to monitor every signal independent of the object-type, you first need to list all signals of the specific instance-type. This can be arranged by g_signal_list_ids for exactly one single GType. To get really ALL signals emitted on the instance, you need to iterate over all parent-types of this instance. You can do this by using g_type_parent.
I have build some utility-functions by myself, that provide this functionality for the same debugging purpose the question was intended. You can connect an Emission-Hook for all signals of a GObject-instance with gemu_glib_util_connect_to_all_signals or connect an emission-Hook to a GtkWidget-instance and all its children with gemu_gtk_util_signal_connect_to_widget_children.
I am trying to catch the enter/return key in a GtkEntry widget. Should I make a signal hander for key-press-event or key-release event?
Alternatively you could look at connecting to the "activate" signal which gets fired when the user hits enter or activates it through some other method.
It depends when you want to act on the event as either signal will do. If you handle key-press-event and the user holds down the key, then you'll keep getting signals. If you handle key-release-event then you'll only get one signal when the user releases the key.
I think most commonly you'll want to use key-release-event.