• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Funkcja zwracająca slot qt

Object Storage Arubacloud
0 głosów
212 wizyt
pytanie zadane 22 lutego 2018 w C i C++ przez chucksqll Stary wyjadacz (12,930 p.)

Witam. Jak napisać funkcję, którą będzie można użyć w

disconnect(... SLOT(ta funkcja)

Załóżmy, że mamy taki slot

void MainWindow::on_P1_clicked()

Próbowałem napisać coś w stylu

void * MainWindow::Slotname(QPushButton *PB)
{
    void (*pfnWskaznik)();
    if(PB==ui->P1)
        pfnWskaznik = &(on_P1_clicked());
return pfnWskaznik;

No, ale po pierwsze wyskakuje błąd "lvalue required as unary '&' operand"

Po drugie jest też błąd z konwersją typów. Jak sobie z tym poradzić?

komentarz 22 lutego 2018 przez mokrowski Mędrzec (155,460 p.)

Ktoś powinien zadać pytanie:

W jakim celu chcesz to zrobić?

Zwracasz wewnętrzne dane klasy (w tym przypadku slot) w celu operowania na nich przez... kogoś. Nie lepiej zaimplementować w niej metodę która rozłączy slot niż przerzucać się danymi na zewnątrz? Tym bardziej że MainWindow ma komplet danych by to robić (jest więc Information Expert ) a zwracając dane na zewnątrz pośrednio dehermetyzujesz klasę.

2 odpowiedzi

+1 głos
odpowiedź 22 lutego 2018 przez j23 Mędrzec (194,920 p.)
edycja 22 lutego 2018 przez j23

Po drugie jest też błąd z konwersją typów.

Pewnie, że jest. I to z trzech powodów:

  • linia 5: prawa strona przypisania to wywołanie on_P1_clicked(), próbujesz przypisać adres tego, co zwraca... a ona nic nie zwraca.
  • linia 5: nawet jakbyś dał pfnWskaznik = &on_P1_clicked; to i tak to nie przejdzie, bo pfnWskaznik jest wskaźnikiem na funkcję, a on_P1_clicked() jest metodą klasy MainWindow, to dwa różne typy wskaźnikow.
  • linia 1 i 6: tego kompletnie nie rozumiem. Próbujesz wskaźnik na funkcję zwrócić jako void*. Why?

Możesz zrobić tak:

auto MainWindow::Slotname(QPushButton *PB)
{
	void (MainWindow::*pfnWskaznik)();

	if(PB == ui->P1)
		pfnWskaznik = &on_P1_clicked;
		
	return pfnWskaznik;
}

 

komentarz 22 lutego 2018 przez chucksqll Stary wyjadacz (12,930 p.)

Niestety, nie działa mi w taki sposób auto, wyskakują 2 błędy.

deduced return type only available with -std=c  14 or -std=gnu  14

'Slotname' function uses 'auto' type specifier without trailing return typ

Z tego co widzę to problemem jest, że kompiluje w c++11, a taki sposób jest dozwolony dopiero w c++14, jak więc przerobić ten kod, żeby działał w c++11?

Co do

linia 1 i 6: tego kompletnie nie rozumiem. Próbujesz wskaźnik na funkcję zwrócić jako void*. Why?

Myślałem, że skoro slot nic nie zwraca, to muszę zrobić w jakiś sposób zwrócić wskaźnik na typ void(ten slot).

komentarz 22 lutego 2018 przez j23 Mędrzec (194,920 p.)

Spróbuj tak:

auto MainWindow::Slotname(QPushButton *PB) -> void (MainWindow::*)()

{
        ...
}

 

komentarz 22 lutego 2018 przez chucksqll Stary wyjadacz (12,930 p.)

Kompilować się kompiluje, ale niestety nie działa poprawnie.

 disconnect(Tabname(i,j), SIGNAL (clicked()),this, SLOT (Slotname(PB)));

disconnect(Tabname(i,j), SIGNAL (clicked()),this, SLOT (on_P1_clicked()));

Zakładając, że PB wskazuje na P1 to te dwie funkcje nie dają tego samego rezultatu i tylko druga z nich działa tak jak ma. To znaczy, że funkcja poniżej nie spełnia tego co miała :/

auto MainWindow::Slotname(QPushButton *PB)-> void (MainWindow::*)()
{

    void (MainWindow::*pfnWskaznik)();
    if(PB==ui->P1)
        pfnWskaznik=&on_P1_clicked;
    else if(PB==ui->P2)
        pfnWskaznik=&on_P2_clicked;
    else if(PB==ui->P3)
        pfnWskaznik=&on_P3_clicked;
    else if(PB==ui->P4)
        pfnWskaznik=&on_P4_clicked;
    else if(PB==ui->P5)
        pfnWskaznik=&on_P5_clicked;
    else if(PB==ui->P6)
        pfnWskaznik=&on_P6_clicked;
    else if(PB==ui->P7)
        pfnWskaznik=&on_P7_clicked;
    else if(PB==ui->P8)
        pfnWskaznik=&on_P8_clicked;
    else if(PB==ui->P9)
        pfnWskaznik=&on_P9_clicked;
    return pfnWskaznik;
}

 

komentarz 22 lutego 2018 przez j23 Mędrzec (194,920 p.)

Zapewne problemem jest to, że używasz makr SIGNAL() i SLOT(). Powinieneś użyć metody disconnect() w wersji, która przyjmuje w parametrach wskaźniki na metody. Spróbuj tak:

disconnect(Tabname(i,j), &QPushButton::clicked, this, Slotname(PB));
 

Zakładam, że Tabname() zwraca wskaźnik na obiekt klasy QPushButton.

 

komentarz 23 lutego 2018 przez chucksqll Stary wyjadacz (12,930 p.)

Tak,  Tabname()  zwraca ten wskaźnik. Niestety nadal nic :/ Trudno będę musiał to zrobić mniej estetycznie.

komentarz 23 lutego 2018 przez j23 Mędrzec (194,920 p.)

Sprawdzałeś debuggerem, czy Slotname() zwraca właściwy wskaźnik?

–1 głos
odpowiedź 22 lutego 2018 przez Bondrusiek Maniak (61,370 p.)

Witam,

spróbuj poprawić adres funkcji, która jest pobierana przez wskaźnik

void * MainWindow::Slotname(QPushButton *PB)
{
    void (*pfnWskaznik)();
    if(PB==ui->P1)
{
        //pfnWskaznik = &(on_P1_clicked());
       pfnWskaznik = on_P1_clicked;// ewentualnie pfnWskaznik = &on_P1_clicked;
}
return pfnWskaznik;
}

Nazwa funkcji(bez nawiasów) jest jednocześnie adresem funkcji.

Podobne pytania

+1 głos
1 odpowiedź 148 wizyt
pytanie zadane 2 września 2016 w C i C++ przez folt3k Początkujący (330 p.)
0 głosów
1 odpowiedź 222 wizyt
0 głosów
2 odpowiedzi 281 wizyt
pytanie zadane 14 lutego 2018 w C i C++ przez chucksqll Stary wyjadacz (12,930 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...