Я хочу подать свою заявку использовать динамическую единицу quicklists. Для того, чтобы создать мое приложение я использую C++ и QtCreator IDE. Когда действие меню инициировано, я хочу смочь иметь доступ к нестатической функции моего MainWindow
класс, чтобы смочь обновить Графический интерфейс пользователя, к которому можно получить доступ из функций 'нормального' MainWindow.
Так, я создаю свой quicklist как этот (mainwindow.cpp):
void MainWindow::enable_unity_quicklist(){
Unity_Menu = dbusmenu_menuitem_new();
dbusmenu_menuitem_property_set_bool (Unity_Menu, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
Unity_Stop = dbusmenu_menuitem_new();
dbusmenu_menuitem_property_set(Unity_Stop, DBUSMENU_MENUITEM_PROP_LABEL, "Stop");
dbusmenu_menuitem_child_append (Unity_Menu, Unity_Stop);
g_signal_connect (Unity_Stop, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(&fake_callback), (gpointer)this);
if(!unity_entry)
unity_entry = unity_launcher_entry_get_for_desktop_id("myapp.desktop");
unity_launcher_entry_set_quicklist(unity_entry, Unity_Menu);
dbusmenu_menuitem_property_set_bool(Unity_Menu, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
dbusmenu_menuitem_property_set_bool(Unity_Stop, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
}
void MainWindow::fake_callback(gpointer data){
MainWindow* m = (MainWindow*)data;
m->on_stopButton_clicked();
}
void MainWindow::on_stopButton_clicked(){
//stopping the process...
}
mainwindow.h:
private slots:
void enable_unity_quicklist();
void on_stopButton_clicked();
public slots:
static void fake_callback(gpointer data);
Это предложение было взято из http://old.nabble.com/Using-g_signal_connect-in-class-td18461823.html
Программа сразу отказывает после того, как я выберу действие 'Stop' из Единицы Quicklist. Отладка программы показывает, что я не могу получить доступ к чему-либо связанному с MainWindow в on_stopButton_clicked () без катастрофического отказа. Например, это отказывает при выполнении этой проверки (который является первыми 2 строками кода в этой функции):
if (!ui->stopButton->isEnabled())
return;
Я также протестировал много других вещей, которые я нашел в Интернете, но ничто из них не работало. Одно интересное решение состояло бы в том, чтобы использовать gtkmm (http://developer.gnome.org/gtkmm-tutorial/stable/sec-connecting-signal-handlers.html.en), но я не используюсь при всей работе над приложениями GTK (я работаю только в QT), и я не знаю, подходит ли это даже к моему случаю.
Редактирование: хорошо, после изрядного количества расследования (который включил выполнение valgrind
), мне наконец удалось выяснить то, что продолжается здесь. Подпись Вашего обратного вызова не корректна.
подпись для статического метода должна быть:
void MainWindow::fake_callback(DbusmenuMenuitem *, guint, gpointer data)
{
//...
}
Уведомление добавление DbusmenuMenuitem *
и guint
. Первым является указатель на пункт меню DBus, испускающий сигнал, и второй является метка времени. Оба должны присутствовать в подписи, даже если Вы не используете их.
g_signal_connect
вызывается во времени выполнения и не имеет никакого способа знать, какие параметры Ваша функция принимает и вслепую просто продвигает параметры на стеке, предполагающем, что подписи соответствуют. (Это отличается от того, к чему Вы, вероятно, привыкли в QT, где MOC (Компилятор Метаобъекта) генерирует достаточно информации для знания, когда Вы пытаетесь подключить сигнал к слоту с несовместимой подписью.)