Russian Qt Forum
Ноябрь 23, 2024, 18:20 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Чего гаду надо? connect: No such slot LoadBase::loadFile()  (Прочитано 20922 раз)
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, но кояк мне не по глазам.
Записан
Deiv
Гость
« Ответ #1 : Август 05, 2005, 07:47 »

Вот интересно:
Добавил в базовый класс
Код:

public slots:
    virtual void loadFile();

виртуальное определение слота.
Теперь всё подхватилось.
Это что получается дамы и господа, при наследовании нельзя добавлять свои собственные слоты? Если можно, то как это делать?
Записан
Admin
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1988



Просмотр профиля
« Ответ #2 : Август 05, 2005, 08:34 »

ты еще #include "load.h" не прислал
возможно было в нем
Записан
jindos
Гость
« Ответ #3 : Август 05, 2005, 08:38 »

Да все очень просто.... У тебя же в классе наследнике даже нету определения макроса Q_OBJECT... Поэтому moc и не прописал в moc-файле твой слот loadFile... А когда ты сделал это в базовом классе, где прописан Q_OBJECT, то естественно он его там и нашел... Добавь в определении наследника Q_OBJECT и будет все ок!...
Удачи!

Да и еще описание наследника запихни все-таки в ашку, ведь именно по ней мок делает мок-файлы...
Записан
Deiv
Гость
« Ответ #4 : Август 05, 2005, 11:54 »

Ну ладно, уговорили  Веселый
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
Записан
jindos
Гость
« Ответ #5 : Август 05, 2005, 12:27 »

Ты конечно извини, но я так и не увидел, где у тебя при компиляции создается moc-файл для begform.h... вижу только для load.h... Если ты Makefilе-ом компилишь, то пропиши там строку создания moc-файла для begform.h или создай вручную moc_begform.h и подключи его в begform.h...
Записан
Deiv
Гость
« Ответ #6 : Август 05, 2005, 13:36 »

Я бы с удовольствием, но к сожалению не знаю, как это сделать.
Мок-файл для моего хидера, и мокфайл както подцепить к проекту.
Записан
jindos
Гость
« Ответ #7 : Август 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"
и компилишь... и будет все ок...
Записан
Deiv
Гость
« Ответ #8 : Август 09, 2005, 06:46 »

Спасибо, наконец то разобрался.
Записан
jindos
Гость
« Ответ #9 : Август 09, 2005, 09:44 »

Веселый Рад за тебя)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.131 секунд. Запросов: 22.