Russian Qt Forum

Qt => Общие вопросы => Тема начата: Alchazar от Ноябрь 19, 2009, 15:48



Название: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Alchazar от Ноябрь 19, 2009, 15:48
В главном окне есть TreeWidget со списком, я сделал контекстное меню, в котором вызываю диалог. И в этом диалоге я хочу узнать, как называется тот элемент, с которого я вызвал меню...
Проблема в том, что у меня не получаетса из диалога (вторая форма) узнать название элемента  с основной формы.
я пробую делать так:
Код:
void F_addPc::add_pc_to_db()
{
    QString names = FMain::trWd_tree->currentItem()->text(0);
....
но получаю ошибку:
error: `QTreeWidget*Ui_FMain::trWd_tree' is inaccessible

.h
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QObject>
#include <QWidget>
#include "ui_server.h"
#include "ui_add_new_pc.h"

// Главная форма
class FMain : public QMainWindow, Ui::FMain
{
    Q_OBJECT

public:
    FMain(QMainWindow* p=0) : QMainWindow(p)
    {
        setupUi(this);
        connect(pushButton, SIGNAL(clicked()), this, SLOT(add_group_win()));
        connect(trWd_tree, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(menu_sub_group(const QPoint &)));
    }
private slots:
    void on_actionExit_triggered();
public slots:
    void add_group(QString gr_name);
    void add_group_win();
    void menu_sub_group(const QPoint &);
    void add_sub_group();
    static bool createConnection();
};

// Форма в которой я хочу узнать текст элемента
class F_addPc : public QWidget, private Ui::F_addPc
{
    Q_OBJECT

    public:
        F_addPc(QWidget *parent = 0)
        {
            setupUi(this);
            connect(buttonBox, SIGNAL(accepted()), this, SLOT(add_pc_to_db()));
            connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
        }
    public slots:
        void add_pc_to_db();
};


#endif // MAINWINDOW_H

.cpp
Код:
#include <QtCore>
#include "mainwindow.h"
#include "ui_server.h"
#include "ui_add_new_pc.h"
#include <qinputdialog.h>
#include <QtSql>
#include <QMessageBox>

// show popUp Menu in TreeView
void FMain::menu_sub_group(const QPoint &pos)
{
    QTreeWidgetItem *item = trWd_tree->itemAt(pos);
    if (!item)
        return;

    QString name = trWd_tree->currentItem()->text(0);

    QMenu menu(tr("Context menu"), this);
    // menu if right click Group
    if (!trWd_tree->currentItem()->parent())
    {
        menu.addAction(tr("Add PC to Group"), this, SLOT(add_sub_group()));
        menu.addAction(tr("Rename Group"), this, SLOT(add_sub_group()));
    }
    //menu if right click on PC name
    else
    {
        menu.addAction(tr("Move PC to another group"), this, SLOT(add_sub_group()));
        menu.addAction(tr("Delete PC"), this, SLOT(add_sub_group()));
    }

    menu.exec(trWd_tree->viewport()->mapToGlobal(pos));
}

void FMain::add_sub_group()
{
    // в этом месте всё работает, то есть names равен названию элемента   
    QString names = trWd_tree->currentItem()->text(0);

    // show Window to ad new PC
    F_addPc *nF_addPc = new F_addPc(this);
    nF_addPc->setAttribute(Qt::WA_DeleteOnClose);
    nF_addPc->show();
}

void F_addPc::add_pc_to_db()
{
    QString names = FMain::trWd_tree->currentItem()->text(0);
    QString pc_name, pc_ip, pc_comment, gr_name;
    int old_id;

    pc_name = le_pcName->text();
    pc_ip = le_ipAddr->text();
    pc_comment = le_comment->text();

    //gr_name = FMain::

    FMain::createConnection();

   
}



Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: spectre71 от Ноябрь 19, 2009, 16:13
FMain::trWd_tree->currentItem()->text(0);

1) FMain - у тебя тип,  а не объект;
должно быть например так.
FMain* MainWindow; // где-то
...
..
MainWindow->trWd_tree->currentItem()->text(0);

2) Далее: trWd_tree - должно быть в публичном доступе. Либо  в FMain - публичный метод для получения trWd_tree. Например:

class FMain : public QMainWindow, Ui::FMain
{
...
...
public:
  TreeWidget* get_trWd_tree(void) {return trWd_tree;}
};

...

MainWindow->get_trWd_tree()->currentItem()->text(0);


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Alchazar от Ноябрь 19, 2009, 16:27
Можно подробнее узнать что делает этот код?
Код:
TreeWidget* get_trWd_tree(void)
    {
        return trWd_tree;
    }
В QT и C++ я совсем зелёный(



Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Igors от Ноябрь 19, 2009, 16:34
Самое простое/естественное - снабдить дочернюю форму нужными данными в ее конструкторе, например

Код:
class F_addPc : public QWidget, private Ui::F_addPc
{
    Q_OBJECT

    public:
        F_addPc(const QString & parentName, QWidget *parent = 0) : QWidget(parent), mParentName(parentName)
        {
            setupUi(this);
            connect(buttonBox, SIGNAL(accepted()), this, SLOT(add_pc_to_db()));
            connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
        }
    public slots:
        void add_pc_to_db();
 
    QString mParentName;
};


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Igors от Ноябрь 19, 2009, 16:46
Можно подробнее узнать что делает этот код?
Код:
TreeWidget* get_trWd_tree(void)
    {
        return trWd_tree;
    }
В QT и C++ я совсем зелёный(
Такие ф-ции называются accessors, они разрешают др. классам пользоваться "внутренностями" данного класса. Можно сделать все данные всех классов public и тогда любой класс может использовать данные любого другого без всяких хитростей. Однако жизнь показала что такие программы хотя и начинают писаться очень резво но доделаны бывают очень редко  :)  Чем меньше классы знают друг о друге - тем лучше. А если уж надо воспользоваться - пишем такую ф-цию


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Alchazar от Ноябрь 19, 2009, 16:47
Igors, попробовал твой вариант,
компилятор ругается на QString mParentName;
Код:
 public slots:
        void add_pc_to_db();

    QString mParentName; //
};

Error: Not a signal or slot declaration

и ещё тут - F_addPc *nF_addPc = new F_addPc(this);

Код:
void FMain::add_sub_group()
{
    QString names = trWd_tree->currentItem()->text(0);

    // show Window to ad new PC
    F_addPc *nF_addPc = new F_addPc(this);
    //nF_addPc->gr_name = names;
    nF_addPc->setAttribute(Qt::WA_DeleteOnClose);
    nF_addPc->show();
}

error: no matching function for call to `F_addPc::F_addPc(FMain* const)'


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Igors от Ноябрь 19, 2009, 17:16
Ну синтаксис-то всегда отрихтовать нужно
1)
Код:
 public slots:
        void add_pc_to_db();

 private:
   QString mParentName;
};

2)
Код:
void FMain::add_sub_group()
{
    QString names = trWd_tree->currentItem()->text(0);

    // show Window to ad new PC
    F_addPc *nF_addPc = new F_addPc(names, this);

И еще: что у Вас за имена такие? Ну напр.  F_addPc - кто это такой? Без шансов догадаться да и сами забудете через месяц. Смотрите как в Qt: QString, currentItem - радует глаз.


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Alchazar от Ноябрь 19, 2009, 17:20
А может можно заранее передать название элемента куда нибуть (напр. глобальную в переменную), перед созданием новой формы? А потом получить эту переменную в новой форме?

Над названиями переменных ещё надо поработать)


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Igors от Ноябрь 19, 2009, 18:12
А может можно заранее передать название элемента куда нибуть (напр. глобальную в переменную), перед созданием новой формы? А потом получить эту переменную в новой форме?
Вполне разумный вариант но выигрыша в написании он не дает - эту глобальную надо где-то объявить да потом еще в хедере как extern. А по логике это заметно хуже: будет 2 формы одновременно - что тогда делать? Забыли зарядить переменную перед вызовом формы - компилятор здесь ничего не скажет.


Название: Re: Как узнать свойства (текст) элемента наход
Отправлено: Alchazar от Ноябрь 20, 2009, 10:50
Теперь всё компилируется и запускается, вот только не показывается вторая форма, а вместо этого все элементы второй формы появляются на основной форме.
(http://img266.imageshack.us/img266/5997/screenet.th.jpg) (http://img266.imageshack.us/i/screenet.jpg/)

Код:
class F_addPc : public QWidget, private Ui::F_addPc
{
    Q_OBJECT

    public:
        F_addPc(const QString & parentName, QWidget *parent = 0) : QWidget(parent), mParentName(parentName)
        {
            setupUi(this);
            connect(buttonBox, SIGNAL(accepted()), this, SLOT(add_pc_to_db()));
            connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
        }
    public slots:
        void add_pc_to_db();

    public:
        QString mParentName;
};


Название: Re: Как узнать свойства (текст) элемента наход
Отправлено: Igors от Ноябрь 20, 2009, 11:41
Теперь всё компилируется и запускается, вот только не показывается вторая форма, а вместо этого все элементы второй формы появляются на основной форме.
Может это крутой дизайн? :) LOL
Выкладывайте компилябельный проект, будем разбираться


Название: Re: Как узнать свойства (текст) элемента наход
Отправлено: Alchazar от Ноябрь 20, 2009, 12:01
положил зип тут http://www.sendspace.com/file/6xstcz (http://www.sendspace.com/file/6xstcz)

что-то мне подсказывает, что ошибка где-то тут:
Код:
void FMain::add_sub_group()
{
    QString names = trWd_tree->currentItem()->text(0);

    // show Window to ad new PC
    F_addPc *nF_addPc = new F_addPc(names, this);
    nF_addPc->setAttribute(Qt::WA_DeleteOnClose);
    nF_addPc->show();
}


Название: Re: Как узнать свойства (текст) элемента наход
Отправлено: Igors от Ноябрь 20, 2009, 15:48
положил зип тут http://www.sendspace.com/file/6xstcz (http://www.sendspace.com/file/6xstcz)
Смотрим add_new_pc.ui - Ваша форма просто QWidget, а это еще не диалог и не окно - это виджет который рисуется в окне parent, что он и делает. А почему раньше показывалось окно? Было написано

Код:
class F_addPc : public QWidget, private Ui::F_addPc
{
    Q_OBJECT

    public:
        F_addPc(QWidget *parent = 0)
        {
            setupUi(this);
...
Такой конструктор всегда будет ставить parent = 0, как его не вызывай - ведь конструктор QWidget не указан, значит по умолчанию вызывается QWidget(0). При parent = 0 Qt сделало окно - не знаю почему но разумно. Потом это было исправлено

Код:
 F_addPc(const QString & parentName, QWidget *parent = 0) : QWidget(parent), mParentName(parentName)
{
..
Теперь parent подается, но окна-то нет :) Решение: сделайте add_new_pc.ui  диалогом (изменить она не даст но можно создать новый диалог и скопировать все туда)


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Alchazar от Ноябрь 20, 2009, 15:52
Теперь понятно, а то я всё не понимал в чём разница между еджетом и диалогом.
Спасибо за помощь)


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Alchazar от Ноябрь 25, 2009, 16:35
Я окончательно запутался  :(

Переделал форму, сделал QDialog. Форма отображается, вроде всё хорошо, только я не поминаю почти ничего из того что у меня понаписано (
Можете кто нибуть обьяснить по буквам эту строчку?
Код
C++ (Qt)
FDialog(const QString &parentName, QDialog *parent = 0) : QDialog(parent), mParentName(parentName)

Где и как указать родителя?
Если я правильно понял, родитель указывается при создании диалога - FDialog *nFDialog = new FDialog(... или я вообще не туда забрёл?
Просветите пожалуйсто...


.h
Код
C++ (Qt)
class FDialog : public QDialog, private Ui::FDialog
{
   Q_OBJECT
 
   public:
       FDialog(const QString &parentName, QDialog *parent = 0) : QDialog(parent), mParentName(parentName)
       {
           setupUi(this);
           connect(editPc, SIGNAL(clicked()), this, SLOT(editPcData()));
           connect(editCancel, SIGNAL(clicked()), this, SLOT(close()));
       }
   public slots:
       void editPcData();
 
   public:
           QString mParentName;
};
.срр
Код
C++ (Qt)
void FMain::showEditWindow()
{
   QString names = FMain::trWd_tree->currentItem()->text(0);
   FDialog *nFDialog = new FDialog(names, 0);
   nFDialog->setModal(true);
   nFDialog->setAttribute(Qt::WA_DeleteOnClose);
   nFDialog->show();
}
 


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Igors от Ноябрь 25, 2009, 18:07
Можете кто нибуть обьяснить по буквам эту строчку?
Код:
FDialog(const QString &parentName, QDialog *parent = 0) : QDialog(parent), mParentName(parentName)

Это конструктор класса FDialog, принимает 2 аргумента. Первый - ссылка на строку, второй указатель на родителя. "= 0" означает что вызывающий может указать парента а может и нет, в этом случае парент полагается = 0.

Где и как указать родителя?
...
Код
C++ (Qt)
   QString names = FMain::trWd_tree->currentItem()->text(0);
   FDialog *nFDialog = new FDialog(names, 0);
}
 
Здесь
Код:
    FDialog *nFDialog = new FDialog(names, this);


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Alchazar от Ноябрь 25, 2009, 19:12
То есть родитель в данном примере - this. А this это, если я правильно понял - FDialog?
new FDialog(names, this);
Как тогда сделать родителем главную форму? И можно ли так делать?
И ещё вопрос, new FDialog(names, this) указываются два параметра. Как можно узнать значение первого параметра внутри диалога?


Название: Re: Как узнать свойства (текст) элемента находящегося в другом окне?
Отправлено: Igors от Ноябрь 25, 2009, 19:40
То есть родитель в данном примере - this. А this это, если я правильно понял - FDialog?
new FDialog(names, this);
Как тогда сделать родителем главную форму? И можно ли так делать?
И ещё вопрос, new FDialog(names, this) указываются два параметра. Как можно узнать значение первого параметра внутри диалога?

1) this - это указатель на сам объект внутри любой не-статической его ф-ции. Например

Код:
void FMain::showEditWindow()
{
    QString names = FMain::trWd_tree->currentItem()->text(0);
    FDialog *nFDialog = new FDialog(names, this);
Внутри showEditWindow - значит this указывает на главную форму которая имеет тип FMain. Внутри FDialog this будет указывать на объект типа  FDialog  - например nFDialog

2) parentName был подан в конструкторе и сохранен в члене класса mParentName - просто используйте mParentName в любой ф-ции FDialog