Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: staks от Январь 27, 2007, 19:25



Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: staks от Январь 27, 2007, 19:25
Я тока учусь пока, поэтому вопрос простой для многих; проблема уже обсуждалась на форуме, но то ли я не вкурил, то ли чаво еще :) ...

Кароче:
main.cpp

Код:
#include "myForm.h"
void  main()
{
        QApplication a( argc, argv );
myForm *mf = new myForm();
mf->show();
        return a.exec();
}

myform.h
Код:
#include "Form.h"
#include <qsocket.h>
#include <qlineedit.h>
class MainForm;

class myForm: public MainForm {
Q_OBJECT
public:
    myForm(QWidget *parent = 0, const char *name = 0);
protected slots:
    void ConnectToServer();
private:
QSocket *sock;
MainForm *form;
};

#endif



Form.h
Код:
#ifndef MAINFORM_H
#define MAINFORM_H

#include <qvariant.h>
#include <qwidget.h>

class QVBoxLayout;
class QHBoxLayout;
class QGridLayout;
class QSpacerItem;
class QPushButton;
class QTextEdit;
class QGroupBox;
class QLabel;
class QLineEdit;

class MainForm : public QWidget
{
    Q_OBJECT

public:
    MainForm( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
    ~MainForm();

    QPushButton* pbSend;
    QTextEdit* teMessage;
    QPushButton* pbClose;
    QGroupBox* gbConnectionSettings;
    QLabel* tlHost;
    QLineEdit* leHost;
    QLabel* tlPort;
    QLineEdit* lePort;
    QPushButton* pbConnect;

protected:

protected slots:
    virtual void languageChange();

    virtual void ConnectToServer();


};

#endif // MAINFORM_H


//----------------------------------------------------------------
при попытке обращения к любому объекту из <public MainForm> из методов myForm, выскакивает сегфолт;
как правильно обратиться к значению,например, leHost->text() из,например, myForm::ConnectToServer()?


Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: Dendy от Январь 27, 2007, 21:09
Еммм... А сами елементьІ созданьІ хоть бьІть в конструкторе али где ещё перед обращением к ним? За программиста их никто создавать не будет, всё руками или через дизайнер.

Небольшая ошибка в коде. У Вас два раза обьявлен слот ConnectToServer(). В базовом классе он сделан виртуальньІм для того, чтобьІ вьІзьІвалось тело слота порождённого класса. Только вот ВСЕ слотьІ наследуются и так из базового класса, поетому второй раз обьявлять его как слот в myForm не стоит, так как прекомпилер может сгенерить две разньІе точки вхождения. Просто уберите из myForm обявление его как protected slots:.


Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: staks от Январь 27, 2007, 21:25
(1) сами элементы создаются в конструкторе MainForm

а вот тут уточню дурацкий вапрос: а при выполнении конструктора myForm вроде должен выполняться конструктор его родителя (MainForm)?

в общем описал ConnectToServer() как просто public, попробовал обратиться к elHost->text(), но при сборке ругается на:

myform.cpp: In member function `virtual void myForm::ConnectToServer()':
myform.cpp:35: error: `elHost' was not declared in this scope


Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: Dendy от Январь 27, 2007, 22:54
Матчасть, матчасть... Сегфолт Ваш скорее всего от обращения к неинициализированньІм указателям. myform.cpp:35: error: `elHost' was not declared in this scope : в заголовочнике обьявлен как leHost. Вобщем, хороший редактор кода с отладчиком Вам в помощь. KDevelop, Eclipse, Code::Blocks, QDevelop, gdb.


Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: staks от Январь 27, 2007, 23:00
про матчасть - согласен, хотя в приведенном примере ошибка именно орфографическая

в обчем никак не могу втыкнуть:

Код:
#include <ostream.h>

class A
{
public:
        int x1;
        int *x2;
        A()
        {
                x1=5;
                int *x2 = new int;
                cout<<"A constructor\n";
        }
        ~A(){}
};

class B:public A
{
public:
        B(){cout<<"B constructor\n";}
        ~B(){}
        int getInt()
        {
                *x2=3;
                //return x1;
                return *x2;
        }
};

int main(int argc, char ** argv)
{
        B b;
        B *newB = new B();

        cout << newB->getInt()<<"\n";
        //cout << b.x1<< "\n";
        //cout << b.getInt()<<"\n";
        return 0;
}



а это вывод её:

A constructor
B constructor
A constructor
B constructor
Segmentation fault


объясните непонятливому, почему при обращении к методу класса через указатель выскакивает сегфолт?


ПЫСЫ: закоментаренный кусок работает на ура


Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: Dendy от Январь 27, 2007, 23:10
Потому что x2 не инициализарована. А проинициализирована совершенно другая переменная x2, временно созданная в конструкторе с таким же именем. Типичная ошибка. Приоритет естественно у последней переменной в области видимости. Как раз для таких случаев следует организовьІвать стиль именования переменньІх членов так, чтобьІ невооруженньІм глазом можно бьІло отличить к используешь ли переменную класса или временную переменную в стеке. Я, к примеру, использую популярньІй стиль Александреску, с подчерком в конце:

Код:
class A
{
public:
  A();

  int * x2_;
};

A::A()
{
  int * x2 = new int; // ERROR : x2 != x2_
}


Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: staks от Январь 27, 2007, 23:41
ok

тогда как обратиться к a из моего getInt()  к переменной из класса A, объявленной как public int *x2;
?


Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: Dendy от Январь 28, 2007, 01:31
Правильно:

Код:
        A() 
        {
                x1=5;
                x2 = new int;
                cout<<"A constructor\n";
        }


Думаю, что учить здесь С++ - тратить общее наше время. Есть замечательньІе книги: Шмидт, Страуструп.


Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: Steven_Orko от Январь 28, 2007, 01:34
Цитата: "staks"

тогда как обратиться к a из моего getInt()  к переменной из класса A, объявленной как public int *x2;
?


Код:

#include <ostream.h>

class A
{
public:
        int x1;
        int *m_pix2;
        A()
        {
                x1=5;
               *m_pix2 = new int;
                cout<<"A constructor\n";
        }
        ~A(){}
};

class B:public A
{
public:
        B(){cout<<"B constructor\n";}
        ~B(){}
int getInt(void)
        {
                *m_pix2=3;
                return *m_pix2;
        }
int main(int argc, char ** argv)
{
        B b;
        B *newB = new B();

        cout << newB->getInt()<<"\n";
        return 0;
}


Код:
int B::getInt(void) 
        {
                *A::m_pix2=3;
                return *A::m_pix2;
        }


Ты наследуешь эту переменную в паблик класса B, значит обращайся к ней так, как будто она есть часть класса B.

P.S. Последний вариант - извращение в данном контексте...


Название: Доступ к элементам, созданным KDevel:Designer
Отправлено: staks от Январь 28, 2007, 01:42
спасибо dendy, так все ок

теперь вкурил в чем разница между int  *x2=new int; и x2=new int;