[C++] QTimer wskazanie opcji wyboru wewnątrz funkcji slota


(look997) #1

Chcę w QTimer przekazać argument do slota.

Z tego co wyczytałem to jest niemożliwe, jednak chciałbym aby funkcja slot wiedziała kto się do niej odnosi i na podstawie tego jaką opcję z instrukcji warunkowej wewnątrz tej funkcji ma wybrać.

Jeśli nie chcecie podać konkretnego rozwiązania to chociaż powiedzcie czy w C++ istnieje coś w rodzaju event.target z JavaScriptu lub jakiś inny sposób na osiągnięcie tego celu.


(etam) #2

Skąd to wyczytałeś? Chyba nie stąd https://qt-project.org/doc/qt-5.0/qtcor ... slots.html ? Chyba, że chodzi o jakiś już istniejący slot?


(look997) #3

Z różnych for pomocy na temat QTimer, kiedy chce ktoś przekazać argument to pojawia się "no such slot".

Takie coś:

int ddd = 1;

ShotTimer->singleShot(9000, this, SLOT(mielenie(ddd)));

Mam 3 opcje i chcę poinformować funkcję mielenie(), którą opcję wybrałem. Jak jest jakiś inny sposób bez użycia zmiennej to proszę podać.


(etam) #4

https://qt-project.org/doc/qt-5.0/qtcore/qtimer.html

A teraz konkrety. Co chcesz do czego podłączyć i co ma się w związku z tym dziać?

Jeżeli chodzi o start i stop, to faktycznie nic im nie przekażesz, to tak zostały zadeklarowane.

Jeżeli dobrze domyślam się o co ci chodzi, to możesz zrobić coś takiego:

class MyTimer : public QTimer {

    Q_OBJECT


public:

    MyTimer(QObject* parent = 0) : QTimer(parent) { }


public slots:

    void start(Whatever* who) {

        if (we_like(who))

            QTimer::start();

    }


    void start(Whatever* who, int msec) {

        if (we_like(who))

            QTimer::start(msec);

    }


    void stop(Whatever* who) {

        if (we_like(who))

            QTimer::stop();

    }

};

-- Dodane 04.09.2013 (Śr) 15:39 --

W C++ nie ma. Może być w jakiejś bibliotece wykorzystującej zdarzenia typu GTKmm i Qt (wtedy obsługa zdarzeń jest częścią biblioteki), ale w samym C++ nie ma czegoś takiego.


(look997) #5

Tyle, że u mnie jest tak:

void OknaKlasa::mielenie(int ddd){


    liczMiel += 1;

    if(liczMiel == licz){


        if(ddd == 0){

            kontrolZ->setStyleSheet("background-color: rgb(120,20,100); font-size:8px; color: black;");

        } else if(ddd == 1){

            kontrolJ->setStyleSheet("background-color: rgb(120,20,100); font-size:8px; color: black;");


        } else {

            kontrolD->setStyleSheet("background-color: rgb(120,20,100); font-size:8px; color: black;");

        }

    }

}



void OknaKlasa::Shot(int ddd){

    licz += 1;


    ShotTimer->singleShot(9000, this, SLOT(mielenie(ddd))); // wiem że tak nie można ale efekt ma być tak jakby działało


    kontrol->setStyleSheet("background-color: rgb(120,120,200); font-size:8px; color: black;");


    // ...

}



void OknaKlasa::Shot(){

    licz += 1;

    ShotTimer->singleShot(9000, this, SLOT(mielenie()));


    kontrol->setStyleSheet("background-color: rgb(120,120,200); font-size:8px; color: black;");

}


OknaKlasa::OknaKlasa(QWidget *parent) :

    QMainWindow(parent), //, Qt::WindowStaysOnTopHint

    ui(new Ui::OknaKlasa){

    ui->setupUi(this);


    // ...


    Shot(Zero);

    Shot(Jeden);

    Shot(Dwa);



    // ...

}

Jeśli da się inaczej lub prościej określić której opcji dotyczy wybór to proszę podać.

Może całość jest niepotrzebnie utrudniona przez moją niewiedzę?


(etam) #6

Metoda singleShot jest statyczna. "ShotTimer->singleShot(...)" jest bez sensu, bo wywołanie singleShot nie ma nic wspólnego z ShotTimer. Poprawne jest "QTimer::singleShot(...)".

Mam nadzieję, że używasz Qt5 i C++11

class ShotTimer : public QObject

{

    Q_OBJECT


    QTimer *timer;

    OknaKlasa *target;

    int value;

public:

    ShotTimer(int delay, OknaKlasa *t, int v) : QObject(), target(t), value(v) {

        timer = new QTimer(this);

        timer->setSingleShot(true);

        connect(timer, &QTimer::timeout, [this]() {

            emit target->mielenie(value);

            delete this;

        });

        timer->start(delay);

    }

};

Sposób użycia:

new ShotTimer(9000, this, ddd);

(look997) #7

Taki błąd się pojawia:

błąd:no matching function for call to 'ShotTimer::connect(QTimer*&, void (QTimer::*)(QTimer::QPrivateSignal), ShotTimer::ShotTimer(int, OknaKlasa*, int)::)'

(etam) #8

Dziwne. U mnie działa. Którą masz wersję Qt?

-- Dodane 05.09.2013 (Cz) 2:45 --

Wersja bez lambdy:

class ShotTimer : public QObject

{

    Q_OBJECT


    QTimer *timer;

    OknaKlasa *target;

    int value;

public:

    ShotTimer(int delay, OknaKlasa *t, int v) : QObject(), target(t), value(v) {

        timer = new QTimer(this);

        timer->setSingleShot(true);

        connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));

        timer->start(delay);

    }

private slots:

    void timeout() {

        emit target->mielenie(value);

        delete this;

    }

};

(look997) #9

Qt Creator 2.7.0

Based on Qt 5.0.2 (32 bit)

Built on Apr 9 2013 at 09:32:03

Z poprawki b6257ef735

Ta przerobiona wersja daje taki błąd:

błąd:undefined reference to `vtable for ShotTimer'

(etam) #10

Dziwne. Według dokumentacji https://qt-project.org/doc/qt-5.0/qtcor ... -arguments powinno działać.

Bo nie umieściłeś deklaracji klasy w osobnym pliku nagłówkowym.