Qt łączenie okien za pomocą sygnałów

0

Witam,
Tak więc pisze program który, wywołuje widgety i potrzebne mi przesyłanie wartości do tego widgetu
zrobiłem to za pomocą sygnału no ale nie wiem czy dobrze to robie bo wywala mi pełno błędów i za każdym razem jak próbuje je naprawić pojawiają się nowe :p
wzorowałem się na http://stackoverflow.com/questions/6199962/how-to-pass-data-from-one-form-to-another-in-qt
fragment kodu:
Oknogłówne
-plik .h

 signals:

    void tableNameEntered(const QString &text);

-pli.cpp konstruktor

connect(ui->listWidget->itemDoubleClicked(), SIGNAL(doubleClicked(QModelIndex)),this, SIGNAL(on_listWidget_itemDoubleClicked()));

pli.cpp funkcja

 void okno::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{

    Elementy*o = new Elementy();

    QObject::connect(this, SIGNAL(tableNameEntered(const QString&)),
                         &o, SLOT(onNewTextEntered(const QString&)));

    emit this->tableNameEntered(item->text());

    o->show();
}

a w Widget mam tak:
-plik .h

     
private slots:
    void onTableNameEntered(const QString &text);

-plik.cpp

void SecondForm::onNewTextEntered(const QString &text)
{
    this->setWindowTitle(text);
} 

tak to zrobiłem wzorując się na tamtej stronie.
ale generuje mi błędy:
problemy_jpg_300x300_q85.jpg

0

łączysz sygnał ze sygnałem! " SIGNAL(on_listWidget_itemDoubleClicked()) " to jest na pewno, źle bo już po nazwie "on_*" widać, że to jest slot.
SIGNAL/SLOT to jest makra, które dopisują na początek 0 lub 1 dla odróżnienia slotów i sygnałów.

na dodatek "ui->listWidget->itemDoubleClicked()" to chyba za dużo, czy tam nie powinno być ui->listWidget.

Podsumowując:

connect(ui->listWidget, SIGNAL(doubleClicked(QModelIndex)),this, SLOT(on_listWidget_itemDoubleClicked()));
0

Czytaj błędy ze zrozumieniem:

  1. Funkcja itemDoubleClicked nie ma wersji bezparametrowej. Musisz przekazać jej argument typy QListWidgetItem*. W takim wydaniu jak to masz musiałbyś łączyć to dla każdego QListWidgetItem jaki dodajesz. Lepiej jest wyłapywać sygnał kliknięcia na widoku i za jego pomocą wyłuskać z QModelIndex to który item został kliknięty.
  2. Okno musi dziedziczyć po QObject. Inaczej nie może korzystac z funkcji connect, nieprawdaż?
0

Jak jeszcze patrze co wypatrzył Malootki, to stwierdzam, że cały kod to totalna kaszana, pokaż lepiej całość, bo już widzę, że masz więcej kwiatków (szczególnie, że na zrzucie ekranu masz błędy kompilacji).

0
Malootki napisał(a):

Czytaj błędy ze zrozumieniem:

  1. Funkcja itemDoubleClicked nie ma wersji bezparametrowej. Musisz przekazać jej argument typy QListWidgetItem*. W takim wydaniu jak to masz musiałbyś łączyć to dla każdego QListWidgetItem jaki dodajesz. Lepiej jest wyłapywać sygnał kliknięcia na widoku i za jego pomocą wyłuskać z QModelIndex to który item został kliknięty.
  2. Okno musi dziedziczyć po QObject. Inaczej nie może korzystac z funkcji connect, nieprawdaż?

Ad1. sygnal kliknięcia na widoku ? to jaki to sygnał bo w mojej koncepcji zależy mi na tym, że sa wyświetlane elementy na liście i po 2xkliknięciu w niego otwiera się nam widget, który nam przekaże zawartośc tego elementu.

Ad2. w Qt pisze od tego właśnie projektu hobbistycznego, który sobie wymyśliłem. więc dzięki za info bo nie miałem zielonego pojęcia

0

Oh. Wybacz. QListWidget nie ma tego sygnału o którym myślałem.
Twoja propozycja to:

connect(ui->listWidget->itemDoubleClicked(), SIGNAL(doubleClicked(QModelIndex)),this, SIGNAL(on_listWidget_itemDoubleClicked())); 

Interesująca nas deklaracja funkcji connect to:

ool 	connect ( const QObject * sender, const char * signal, const char * method, Qt::ConnectionType type = Qt::AutoConnection ) const 

Więc ja zaproponuję coś takiego dla 4 argumentów:

  1. Obiekt ktory może wysłać sygnał. Czyli QListWidget. W Twoim przypadku ui->listWidget.
  2. Sygnał który ten obiekt rzeczywiście może wyemitować. Sprawdzam tu http://qt-project.org/doc/qt-4.8/qlistwidget.html sekcja SIGNALS. Aha. SIGNAL(itemDoubleClicked ( QListWidgetItem *))
  3. Obiekt który ma odebrać sygnał. Twierdzisz, że to this. Ok. Jest to bardzo prawdopodobne, że to jest właściwe.
  4. Slot którym może zostać obsłużony sygnal a więc musi mieć takie same parametry jak sygnał. W związku z tym Twoja funkcja on_listWidget_itemDoubleClicked() nie może być bezparametrowa. Musi pobierać QListWidgetItem * item który przekazuje jej sygnał. Dlatego musisz to zmienić i se po tym działać w funkcji na tym itemie.

Także moim zdaniem connect będzie użyty tu w ten sposób:

connect(ui->listWidget, SIGNAL(itemDoubleClicked ( QListWidgetItem*)), this, SLOT(on_listWidget_itemDoubleClicked(QListWidgetItem*)))

Czyż nie tak?

0
Malootki napisał(a):

Oh. Wybacz. QListWidget nie ma tego sygnału o którym myślałem.
Twoja propozycja to:

connect(ui->listWidget->itemDoubleClicked(), SIGNAL(doubleClicked(QModelIndex)),this, SIGNAL(on_listWidget_itemDoubleClicked())); 

Interesująca nas deklaracja funkcji connect to:

ool 	connect ( const QObject * sender, const char * signal, const char * method, Qt::ConnectionType type = Qt::AutoConnection ) const 

Więc ja zaproponuję coś takiego dla 4 argumentów:

  1. Obiekt ktory może wysłać sygnał. Czyli QListWidget. W Twoim przypadku ui->listWidget.
  2. Sygnał który ten obiekt rzeczywiście może wyemitować. Sprawdzam tu http://qt-project.org/doc/qt-4.8/qlistwidget.html sekcja SIGNALS. Aha. SIGNAL(itemDoubleClicked ( QListWidgetItem *))
  3. Obiekt który ma odebrać sygnał. Twierdzisz, że to this. Ok. Jest to bardzo prawdopodobne, że to jest właściwe.
  4. Slot którym może zostać obsłużony sygnal a więc musi mieć takie same parametry jak sygnał. W związku z tym Twoja funkcja on_listWidget_itemDoubleClicked() nie może być bezparametrowa. Musi pobierać QListWidgetItem * item który przekazuje jej sygnał. Dlatego musisz to zmienić i se po tym działać w funkcji na tym itemie.

Także moim zdaniem connect będzie użyty tu w ten sposób:

connect(ui->listWidget, SIGNAL(itemDoubleClicked ( QListWidgetItem*)), this, SLOT(on_listWidget_itemDoubleClicked(QListWidgetItem*)))

Czyż nie tak?

Ad1. zgodzę się
Ad2. This signal is emitted with the specified item when a mouse button is double clicked on an item in the widget. dokładnie o to mi chodzi według mnie taki ma być efekt.
Ad3. obik który odbiera sygnał "this" czyli nasze okno i po odebraniu sygnału emituje nam nasz powiązany tak ?
Ad4. Moja funkcja nigdy nie była bez parametrowa
cały czas wygląda tak:

void okno::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{

    Elementy*o = new Elementy();

    QObject::connect(this, SIGNAL(tableNameEntered(const QString&)),
                         &o, SLOT(onNewTextEntered(const QString&)));

    emit this->tableNameEntered(item->text());

    o->show();
} 
0

problemy_1_jpg_300x300_q85.jpg

Taki najnowszy rzut błędów

0

Ad 3. Po odebraniu sygnału NIE EMITUJE, a wykonuje wskazaną przez nas funkcję :)
Ad 4. Dostajesz QListWidgetItem* item który kliknąłeś. Rób sobie z nim co chcesz. Korzystaj z czegokolwiek co z niego wyciągniesz.
Ad 5. Proszę bardzo. Spróbuj :P Kompilator będzie doskonale wiedział o jaką funkcję Ci chodzi - jeśli nie możesz nawet napisać QObject::connect. Możesz. Ale :) Teraz zaczynają się schody. Spróbuj zmusić funkcję która jako 1 i 3 parametr MUSI przyjmować wskażnik na QObject (lub, dzięki temu że to wskażnik to równie dobrze może przyjmować wkaźniki na obiekty klas dziedziczących z QObject) aby właśnie 3 parametr potrakował jakimś cudem jako QObject. Powodzenia :) Wydaje mi się, że kompilator jest na tyle uparty, że prędzej przekonasz rolnika żeby wydoił psa powtarzając mu 100 razy, że to jednak krowa.

Do wyjadaczy: Tak, może zmusić program do skompilowania się poprzez dynamic_cast lub reinterpreter_cast na wskaźniku ale przecież doskonale wiemy czym to się zakończy :)

0

problemy_2_jpg_300x300_q85.jpg

błache czy nie...
ale jeden błąd cały czas jest odnośnie nie pasującej funkcji do okno::conect(...
niepasująca ;/

0
 #ifndef OKNO_H
#define OKNO_H

#include <QMainWindow>
#include <QListWidgetItem>

namespace Ui {
    class okno;
}

class okno : public QMainWindow, QObject
{
    Q_OBJECT

public:
    explicit okno(QWidget *parent = 0);
    ~okno();

private slots:
    void on_actionNew_triggered();

    void on_actionExit_triggered();

    void on_actionSave_triggered();

    void on_pushButton_2_clicked();

    void on_pushButton_4_clicked();

    void on_pushButton_3_clicked();

    void on_actionOpen_triggered();

    void on_pushButton_7_clicked();

    void on_pushButton_8_clicked();

    void on_pushButton_9_clicked();

    void on_pushButton_6_clicked();

    void on_actionSerch_triggered();

    void on_actionAbout_Program_triggered();

    void on_pushButton_5_clicked();

    void on_listWidget_itemDoubleClicked(QListWidgetItem *item);

signals:

    void tableNameEntered(const QString &text);

private:
    Ui::okno *ui;
};

#endif // OKNO_H
#include "okno.h"
#include "ui_okno.h"
#include "nowy.h"
#include "wyjscie.h"
#include "oprogramie.h"
#include "openerror.h"
#include "elementy.h"
#include <QDesktopWidget>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;

okno::okno(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::okno)
{
    ui->setupUi(this);
    //ustawienie nazwy Okna
    this->setWindowTitle("Kasia");
    //wyśrodkowanie okna
    QRect scr = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber());
    this->move(scr.center() - rect().center());
    //Ikona programu
    setWindowIcon(QIcon(":/icon.png"));

    connect(ui->listWidget, SIGNAL(itemDoubleClicked ( QListWidgetItem*)), this, SLOT(on_listWidget_itemDoubleClicked(QListWidgetItem*)));


    ui->widget->setVisible(true);
    ui->actionAdd_new_element->setDisabled(true);
    ui->actionClose->setDisabled(true);
    ui->actionSave->setDisabled(true);
    ui->actionOtions->setDisabled(true);
    ui->actionAdd_new_type->setDisabled(true);
    ui->actionSerch->setDisabled(true);
    ui->pushButton->setDisabled(true);
    ui->pushButton_5->setDisabled(true);
    ui->pushButton_6->setDisabled(true);

    fstream plik;
    string s;
    plik.open("tabela.kas",ios::in);
    s.clear();
    if( plik.good() == true )
    {
        while(!plik.eof())
        {
            getline(plik,s);
            QString qstr = QString::fromStdString(s);
            ui->listWidget->addItem(qstr);
            s.clear();
        }
    }
    else
    {
        plik.open("tabela.kas",ios::out | ios::out);
        plik <<"aa";
    }
    plik.close();

}

okno::~okno()
{
    delete ui;
}





//Kontrolka Nowy Plik
void okno::on_actionNew_triggered()
{
    nowy*o = new nowy();
    o->show();
}
//Kontrolka wyjścia z Pliku
void okno::on_actionExit_triggered()
{
    wyjscie*o = new wyjscie();
    o->show();


}
//Kontrolka zapisu do pliku
void okno::on_actionSave_triggered()
{
    //ZAPIS
    ui->pushButton->setEnabled(true);
    ui->pushButton_5->setEnabled(true);
    ui->pushButton_6->setEnabled(true);
}
//Potwierdzenie wyjscia bez zapisu
void okno::on_pushButton_2_clicked()
{
    exit(0);
}

void okno::on_pushButton_4_clicked()
{

}

void okno::on_pushButton_3_clicked()
{

}
//otwieranie pliku
void okno::on_actionOpen_triggered()
{
    //OPEN FILE
    ui->pushButton->setEnabled(true);
    ui->pushButton_5->setEnabled(true);
    ui->pushButton_6->setEnabled(true);
}

void okno::on_pushButton_7_clicked()
{
    //OKEY BUTTON
}
//Nowy plik (button)
void okno::on_pushButton_8_clicked()
{
    on_actionNew_triggered();
}
//Open File (button)
void okno::on_pushButton_9_clicked()
{
    on_actionOpen_triggered();
}

void okno::on_pushButton_6_clicked()
{
    on_actionSerch_triggered();
}

void okno::on_actionSerch_triggered()
{
    //SZUKAJ!!
}

void okno::on_actionAbout_Program_triggered()
{
    Oprogramie*o = new Oprogramie();
    o->show();
}

void okno::on_pushButton_5_clicked()
{
    OpenError*o = new OpenError();
    o->show();
}



void okno::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{

    Elementy*o = new Elementy();

    QObject::connect(this, SIGNAL(tableNameEntered(const QString&)),
                         &o, SLOT(onNewTextEntered(const QString&)));

    emit this->tableNameEntered(item->text());

    o->show();
}
 
1
  1. QMainWindow dziedziczy z QObject. Dziedzicząc z QMainWindow dziedziczysz też QObject. Zmień class okno : public QMainWindow, QObject na class okno : public QMainWindow
  2. Klasa Elementy tez musi w jakiś sposób dziedziczyć z QObject. To właśnie pokazuje Ci błąd... Od razu mówię, gdy to poprawisz pojawi się kolejny błąd. Ampersand przy o jest zdecydowanie niepotrzebny.

1 użytkowników online, w tym zalogowanych: 0, gości: 1