2013-07-01 3 views
1

Я не понимаю, почему этот код не работает, возможно, я не понимаю концепцию SIGNAL и SLOT.C++ - QT - понимание SIGNAL и SLOT

Например: У меня есть класс с именем MainWindow, этот класс содержит компоненты ui. В этом пользовательском интерфейсе я могу запустить и закрыть локальный сервер. Этот сервер определен в классе MyServer. Класс MainWindow имеет ссылку на MyServer class '&myServer'. Если я это сделать в классе mainwindow.cpp это работает:

connect(ui->startServer,SIGNAL(clicked()),&myServer,SLOT(startServer())); 
connect(ui->shutdownServer,SIGNAL(clicked()),&myServer,SLOT(shutDownServer())); 

, но эта линия не:

connect(&myServer,SIGNAL(signalMessage()), this, SLOT(slotUpdate())); 

Эта проблема является: У меня есть сигнал под названием void signalMessage(); в классе MyServer, этот сигнал называется функция void startServer(); и void shutDownServer()

signals: 
    void signalMessage(); 

Обычно после вызова singalMessage() в MyServer класса, функц ион slotUpdate() в классе MainWindow. Но вызывается только signalMessage(), а не slotUpadate().

Я надеюсь, что кто-нибудь поймет мою проблему. Я могу определить слот и сигнал от MainWindow до MyServer, но не наоборот. :(

Edit: Окей, вот некоторый код для понимания моей проблемы:

mainwindow.h

... 
public: 
    Ui::MainWindow *ui; 
    MyServer myServer; 


public slots: 
    void slotUpdate(); 
... 

mainwindow.cpp

... 
connect(ui->startServer,SIGNAL(clicked()),&myServer,SLOT(startServer())); 
connect(ui->shutdownServer,SIGNAL(clicked()),&myServer,SLOT(shutDownServer())); 
connect(&myServer,SIGNAL(signalMessage()), this, SLOT(slotUpdate())); 
... 
void MainWindow::slotUpdate() 
{ 
    qDebug()<< "update()"; 
} 
... 

myserver.h

public slots: 
void startServer();//start the server on 127.0.0.1 port: 1234 
void shutDownServer();//disconnect threads, shut down server 

signals: 
    void signalMessage(); 

myserver.cpp

... 
void MyServer::startServer(){ 
if(!this->listen(QHostAddress::Any,1234)){ 
    message.append("Could not start server, because server is already running"); 
}else{ 
    message.append("Listening..."); 
} 

emit signalMessage(); 
} 

... 
void MyServer::signalMessage() 
{ 
    qDebug() << "getMessage()"; 
} 
+1

с «сигналом называется», вы имеете в виду, что вы «испускаете» его, правильно? –

+0

да, я написал «emit signalMessage();» – user1895683

+0

Можете ли вы показать еще какой-нибудь код с соответствующими частями (особенно определениями слотов и сигналов) из вашего файла '.h'? Когда вы запускаете отладочную сборку вашего приложения из командной строки, получаете ли вы какой-либо вывод, например «Нет такого слота»? –

ответ

0

Вы не должны реализовывать signalMessage себя, как вы сделали в файле myserver.cpp. Таким образом, один из QObject будет переопределен, а сигнал не будет отправлен.

+0

Что вы имеете в виду «реализовать ... себя, как вы это делали в файле myserver.cpp»? – user1895683

+0

Вы предоставили реализацию для функции в исходном файле, то есть '' void MyServer :: signalMessage() { qDebug() << "getMessage()"; } ''. Это неверно. – arne

+0

@ user1895683 Тело сигналов определяется moc (компилятором метаобъекта), поэтому, если вы объявите функцию в разделе сигналов и добавите Q_OBJECT в определение класса, вы не сможете определить их сам. На этапе компоновки у вас будет ошибка «множественного определения». – alexisdm

1

Если вам нужно установить функцию signalMessage, это значит, что вы не использовали макрос Q_OBJECT в определении класса MyServer.

1

Для того чтобы получить/испускают сигналы:

  1. Ваш класс должен быть производным от QObject.
  2. Ваш класс должен содержать макрос Q_OBJECT в его объявлении.
  3. Файл заголовка с этим классом должен обрабатываться с помощью moc (происходит автоматически, когда вы используете qmake для генерации файла проекта).

Устранение:

  1. Если заголовок первоначально не имеют классы с сигнальными/слотах и ​​вы добавили их, вам необходимо повторно запустить QMAKE и регенерировать Makefile (или файл проекта Visual Studio).
  2. Создайте отладочные версии вашей программы в качестве консольных приложений (в файле * .pro) ИЛИ прочитайте отладочный вывод при запуске вашей программы. Если вы делаете опечатку, и qt не может подключиться к сигналу, он будет печатать сообщение об этой проблеме либо в окне вывода отладки, либо в stdout/stderr. Это единственный способ заметить, что вам не удалось установить соединение. Соединения устанавливаются при запуске приложения (во время выполнения), а не во время компиляции.
  3. Если вы забыли добавить Q_OBJECT в объявление класса или если вы не запускали заголовки (с классами, которые имеют сигналы/слот) через moc, вы не сможете подключиться к сигналам/слотам.

Не должно быть необходимости писать тело функции для сигналов. Если вам нужно написать тело функции, есть проблемы с вашим кодом.

также:
Qt имеет большую документацию, так что вы должны прочитать его Если вы установили Qt, документация должна быть доступна через программу «помощника», и это также available online.

+0

okey, спасибо: D – user1895683

1

Решение:

@arne:

«Вы обеспечили выполнение для функции в исходном файле, то есть пустота MyServer :: signalMessage() {QDebug() < < "GetMessage()" Это неправильно.

«Заявление о соединении было уже правильным. Тот факт, что ваш сервер получает другой сигнал, указывает на то, что макрос QOBJECT существует. Просто удалите реализацию функции, то есть код, который я цитировал в своем предыдущем комментарии (из файла cpp) "

Поэтому я должен удалить реализацию singalMessage(); в .cpp-файле. После этого строка connect (& myServer, SIGNAL (singalMessage()), это, SLOT (slotUpdate())); работает.

Смежные вопросы