Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: Deiv от Август 05, 2005, 06:31
Из ui-шки транслировался такой класс load.h class LoadBase : public QDialog { Q_OBJECT public: LoadBase( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); ~LoadBase();
QLineEdit* File; QProgressBar* progress; QPushButton* buttonLoadFile; QPushButton* buttonCancel;
protected: QHBoxLayout* layout3; QSpacerItem* spacer_butt;
protected slots: virtual void languageChange(); };
load.cpp LoadBase::LoadBase( QWidget* parent, const char* name, bool modal, WFlags fl ) : QDialog( parent, name, modal, fl ) { //..... }
Я отнаследовал данный класс #include "load.h"
#include <qvariant.h> #include <qsplitter.h> #include <qlineedit.h> #include <qprogressbar.h> #include <qpushbutton.h> #include <qlayout.h> #include <qtooltip.h> #include <qwhatsthis.h>
class Load : public LoadBase { public: Load( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); public slots: // void CloseForm(); void loadFile(); };
Load::Load( QWidget* parent, const char* name, bool modal, WFlags fl ) : LoadBase ( parent, name, modal, fl ) { connect( buttonLoadFile, SIGNAL(clicked()), this, SLOT(loadFile()) ); };
void Load::loadFile() { QMessageBox::information( 0, "Info", "Load file", 0, 0, 0 ); return; };
Всё замечательно компилится, линкуется. При запуске выдается такое сообщение [dancv@dancvl load_data_from_file]$ ./InfoBytes QObject::connect: No such slot LoadBase::loadFile() QObject::connect: (sender name: 'buttonLoadFile') QObject::connect: (receiver name: 'LoadBase')
И при нажатии на клавишу ничего не выскакивает, а должно появится сообщение. Что не так? При чем, почему так - "QObject::connect: No such slot LoadBase::loadFile()", по какому праву он ищет его в классе LoadBase а не в классе Load. Дело наверное в с++ а не в QT, но кояк мне не по глазам.
Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: Deiv от Август 05, 2005, 07:47
Вот интересно: Добавил в базовый класс public slots: virtual void loadFile();
виртуальное определение слота. Теперь всё подхватилось. Это что получается дамы и господа, при наследовании нельзя добавлять свои собственные слоты? Если можно, то как это делать?
Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: Admin от Август 05, 2005, 08:34
ты еще #include "load.h" не прислал возможно было в нем
Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: jindos от Август 05, 2005, 08:38
Да все очень просто.... У тебя же в классе наследнике даже нету определения макроса Q_OBJECT... Поэтому moc и не прописал в moc-файле твой слот loadFile... А когда ты сделал это в базовом классе, где прописан Q_OBJECT, то естественно он его там и нашел... Добавь в определении наследника Q_OBJECT и будет все ок!... Удачи!
Да и еще описание наследника запихни все-таки в ашку, ведь именно по ней мок делает мок-файлы...
Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: Deiv от Август 05, 2005, 11:54
Ну ладно, уговорили :D load.h /**************************************************************************** ** Form interface generated from reading ui file 'load.ui' ** ** Created: Птн Авг 5 15:02:41 2005 ** by: The User Interface Compiler ($Id: qt/main.cpp 3.3.4 edited Nov 24 2003 $) ** ** WARNING! All changes made in this file will be lost! ****************************************************************************/
#ifndef LOADBASE_H #define LOADBASE_H
#include <qvariant.h> #include <qdialog.h>
class QVBoxLayout; class QHBoxLayout; class QGridLayout; class QSpacerItem; class QGroupBox; class QProgressBar; class QLineEdit; class QPushButton;
class LoadBase : public QDialog { Q_OBJECT
public: LoadBase( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); ~LoadBase();
QGroupBox* groupB; QProgressBar* progress; QLineEdit* File; QPushButton* buttonLoadFile; QPushButton* buttonCancel; // виртульные функции слоты public slots: virtual void loadFile(); virtual void closeForm(); // ^^виртульные функции слоты^^ protected: QGridLayout* LoadBaseLayout; QGridLayout* groupBLayout; QVBoxLayout* layout4;
protected slots: virtual void languageChange(); }; #endif // LOADBASE_H
load.cpp /**************************************************************************** ** Form implementation generated from reading ui file 'load.ui' ** ** Created: Птн Авг 5 15:02:48 2005 ** by: The User Interface Compiler ($Id: qt/main.cpp 3.3.4 edited Nov 24 2003 $) ** ** WARNING! All changes made in this file will be lost! ****************************************************************************/
#include "load.h"
#include <qvariant.h> #include <qpushbutton.h> #include <qgroupbox.h> #include <qprogressbar.h> #include <qlineedit.h> #include <qlayout.h> #include <qtooltip.h> #include <qwhatsthis.h>
/* * Constructs a LoadBase as a child of 'parent', with the * name 'name' and widget flags set to 'f'. * * The dialog will by default be modeless, unless you set 'modal' to * TRUE to construct a modal dialog. */ LoadBase::LoadBase( QWidget* parent, const char* name, bool modal, WFlags fl ) : QDialog( parent, name, modal, fl ) { if ( !name ) setName( "LoadBase" ); setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, sizePolicy().hasHeightForWidth() ) );
setMinimumSize( QSize( 360, 120 ) ); setMaximumSize( QSize( 800, 120 ) ); setBaseSize( QSize( 360, 120 ) ); setSizeGripEnabled( TRUE ); LoadBaseLayout = new QGridLayout( this, 1, 1, 11, 6, "LoadBaseLayout");
groupB = new QGroupBox( this, "groupB" ); groupB->setMinimumSize( QSize( 260, 80 ) ); groupB->setMaximumSize( QSize( 1024, 80 ) ); groupB->setLineWidth( 0 ); groupB->setColumnLayout(0, Qt::Vertical ); groupB->layout()->setSpacing( 6 ); groupB->layout()->setMargin( 11 ); groupBLayout = new QGridLayout( groupB->layout() ); groupBLayout->setAlignment( Qt::AlignTop );
progress = new QProgressBar( groupB, "progress" );
groupBLayout->addWidget( progress, 1, 0 );
File = new QLineEdit( groupB, "File" ); File->setEnabled( TRUE ); File->setMouseTracking( TRUE ); File->setFocusPolicy( QLineEdit::NoFocus );
groupBLayout->addWidget( File, 0, 0 );
LoadBaseLayout->addWidget( groupB, 0, 0 );
layout4 = new QVBoxLayout( 0, 0, 6, "layout4");
buttonLoadFile = new QPushButton( this, "buttonLoadFile" ); buttonLoadFile->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, buttonLoadFile->sizePolicy().hasHeightForWidth() ) ); buttonLoadFile->setMinimumSize( QSize( 70, 25 ) ); buttonLoadFile->setMaximumSize( QSize( 70, 30 ) ); layout4->addWidget( buttonLoadFile );
buttonCancel = new QPushButton( this, "buttonCancel" ); buttonCancel->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, buttonCancel->sizePolicy().hasHeightForWidth() ) ); buttonCancel->setMinimumSize( QSize( 70, 30 ) ); buttonCancel->setMaximumSize( QSize( 70, 30 ) ); buttonCancel->setAutoDefault( TRUE ); layout4->addWidget( buttonCancel );
LoadBaseLayout->addLayout( layout4, 0, 1 ); languageChange(); resize( QSize(360, 120).expandedTo(minimumSizeHint()) ); clearWState( WState_Polished ); }
/* * Destroys the object and frees any allocated resources */ LoadBase::~LoadBase() { // no need to delete child widgets, Qt does it all for us }
/* * Sets the strings of the subwidgets using the current * language. */ void LoadBase::languageChange() { setCaption( tr( "Load data from file" ) ); groupB->setTitle( QString::null ); buttonLoadFile->setText( trUtf8( "\xd0\x97\xd0\xb0\xd0\xb3\xd1\x80\xd1\x83\xd0\xb7\xd0\xba\xd0\xb0" ) ); buttonCancel->setText( tr( "&Cancel" ) ); buttonCancel->setAccel( QKeySequence( QString::null ) ); }
Моя ашка, с наследником. #ifndef BEGFORM_H #define BEGFORM_H
#include <qvariant.h> #include <qsplitter.h> #include <qlineedit.h> #include <qprogressbar.h> #include <qpushbutton.h> #include <qlayout.h> #include <qtooltip.h> #include <qwhatsthis.h> #include <qfiledialog.h>
#include "load.h"
class Load : public LoadBase { public: Load( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); char load_fl; public slots: void closeForm(); void loadFile(); };
Load::Load( QWidget* parent, const char* name, bool modal, WFlags fl ) : LoadBase ( parent, name, modal, fl ) { load_fl=0; connect( buttonLoadFile, SIGNAL(clicked()), this, SLOT(loadFile()) ); connect( buttonCancel, SIGNAL(clicked()), this, SLOT(closeForm()) ); };
void Load::loadFile() { if (load_fl==0) { QString fn = QFileDialog::getOpenFileName( QString::null, "*.dat", this ); if ( !fn.isEmpty() ) { File->setText(fn); buttonLoadFile->setText(QString::fromLocal8Bit("Прервать")); load_fl=1; // load( fn ); } } else { buttonLoadFile->setText(QString::fromLocal8Bit("Загрузка")); load_fl=0; } return; };
void Load::closeForm() { emit close(); return; }; #endif
ну и конечно main /**************************************************************************** ** $Id: qt/main.cpp 3.3.4 edited Jun 21 2004 $ ** ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. ** ** This file is part of an example program for Qt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/
#include <qapplication.h> #include <qtable.h> #include <qimage.h> #include <qfile.h> #include <qpixmap.h> #include <qstringlist.h> #include <qmessagebox.h> #include <qstring.h> #include <qprogressbar.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include "begform.h"
// The program starts here.
int main( int argc, char **argv ) { QApplication app( argc, argv ); Load MainW; MainW.show(); app.setMainWidget( &MainW );
return app.exec(); }
Таким образом работает. Так вот: jindos предложил внести в наследника макрос Q_OBJECT. Я ещё убрал определения виртуальных слотов в базовом классе. получаю: [dancv@dancvl load_data_from_file]$ make /usr/lib/qt-3.3/bin/uic load.ui -o .ui/load.h g++ -c -pipe -Wall -W -O2 -g -pipe -march=i386 -mcpu=i686 -DQT_NO_DEBUG -DQT_SHARED -DQT_THREAD_SUPPORT -I/usr/lib/qt-3.3/mkspecs/default -I. -I/usr/lib/qt-3.3/include -I.ui/ -I. -I.moc/ -o .obj/main.o main.cpp /usr/lib/qt-3.3/bin/uic load.ui -i load.h -o .ui/load.cpp g++ -c -pipe -Wall -W -O2 -g -pipe -march=i386 -mcpu=i686 -DQT_NO_DEBUG -DQT_SHARED -DQT_THREAD_SUPPORT -I/usr/lib/qt-3.3/mkspecs/default -I. -I/usr/lib/qt-3.3/include -I.ui/ -I. -I.moc/ -o .obj/load.o .ui/load.cpp /usr/lib/qt-3.3/bin/moc .ui/load.h -o .moc/moc_load.cpp g++ -c -pipe -Wall -W -O2 -g -pipe -march=i386 -mcpu=i686 -DQT_NO_DEBUG -DQT_SHARED -DQT_THREAD_SUPPORT -I/usr/lib/qt-3.3/mkspecs/default -I. -I/usr/lib/qt-3.3/include -I.ui/ -I. -I.moc/ -o .obj/moc_load.o .moc/moc_load.cpp g++ -o InfoBytes .obj/main.o .obj/load.o .obj/moc_load.o -L/usr/lib/qt-3.3/lib -L/usr/X11R6/lib -lqt-mt -lXext -lX11 -lm .obj/main.o(.text+0x3b): In function `Load::Load[not-in-charge](QWidget*, char const*, bool, unsigned)': /home/dancv/Project/cpp/load_data_from_file/begform.h:30: undefined reference to `vtable for Load' .obj/main.o(.text+0x47):/home/dancv/Project/cpp/load_data_from_file/begform.h:30: undefined reference to `vtable for Load' .obj/main.o(.text+0xf6): In function `Load::Load[in-charge](QWidget*, char const*, bool, unsigned)': /home/dancv/Project/cpp/load_data_from_file/begform.h:30: undefined reference to `vtable for Load' .obj/main.o(.text+0x102):/home/dancv/Project/cpp/load_data_from_file/begform.h:30: undefined reference to `vtable for Load' .obj/main.o(.text+0x426): In function `main': /home/dancv/Project/cpp/load_data_from_file/main.cpp:34: undefined reference to `vtable for Load' .obj/main.o(.text+0x431):/home/dancv/Project/cpp/load_data_from_file/main.cpp:34: more undefined references to `vtable for Load' follow collect2: ld returned 1 exit status make: *** [InfoBytes] Ошибка 1
Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: jindos от Август 05, 2005, 12:27
Ты конечно извини, но я так и не увидел, где у тебя при компиляции создается moc-файл для begform.h... вижу только для load.h... Если ты Makefilе-ом компилишь, то пропиши там строку создания moc-файла для begform.h или создай вручную moc_begform.h и подключи его в begform.h...
Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: Deiv от Август 05, 2005, 13:36
Я бы с удовольствием, но к сожалению не знаю, как это сделать. Мок-файл для моего хидера, и мокфайл както подцепить к проекту.
Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: jindos от Август 05, 2005, 14:10
заходим в каталог, где лежит beginform.h делаем: /usr/lib/qt-3.3/bin/moc -o moc_beginform.h beginform.h судя по логам путь такой...
затем прописываешь у себя в beginform.h - #include "moc_beginform.h" и компилишь... и будет все ок...
Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: Deiv от Август 09, 2005, 06:46
Спасибо, наконец то разобрался.
Название: Чего гаду надо? connect: No such slot LoadBase::loadFile()
Отправлено: jindos от Август 09, 2005, 09:44
:D Рад за тебя)
|