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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как найти через findChild() член класса по QObject-имени?  (Прочитано 5822 раз)
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« : Апрель 16, 2016, 11:35 »

У меня был класс с множеством объектов-кнопок. Эти объекты создавались динамически, то есть:

Код:
h-файл:

QToolButton *bold;
QToolButton *italic;
QToolButton *underline;

c++ файл:

QToolButton *bold=new QToolButton(this);
bold->setObjectName("editor_tb_bold");

QToolButton *italic=new QToolButton(this);
italic->setObjectName("editor_tb_italic");

QToolButton *underline=new QToolButton(this);
underline->setObjectName("editor_tb_underline");

Мне все твердят, что так делать ненада, нужно просто сделать кнопки членами класса, а не указатели на них. Я так и сделал:

Код:
h-файл:

QToolButton bold;
QToolButton italic;
QToolButton underline;

c++ файл:

bold.setObjectName("editor_tb_bold");

italic.setObjectName("editor_tb_italic");

underline.setObjectName("editor_tb_underline");

Кнопки нужно в рантайме повтыкать на панель инструментов в последовательности, настроенной пользователем. (Точнее, вставлять нужно не только кнопки, но и например выпадающие списки). Вставка происходит по имени вставляемого объекта.

Ранее, когда были указатели, метод вставки в панель инструментов выглядел так:

Код:
void EditorToolBar::insertButtonToToolsLine(QString toolName, QToolBar *line)
{
  if(toolName=="separator")
    line->addSeparator();
  else
  {
    QString name("editor_tb_"+toolName);
    QWidget *tool=this->findChild<QWidget *>(name);
    if(tool!=NULL)
    {
      tool->setVisible(true);
      line->addWidget(tool); // Инструмент добавляется на панель инструментов
 ...

Теперь, когда членами класса являются не указатели на виджеты, а сами виджеты, я не могу понять, как воспользоваться методом findChild().

В документации на этот метод ничего не сказано о том, что он не может работать с обычными объектами, а не с указателями:

Цитировать
T QObject::findChild(const QString & name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const

Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object. Omitting the name argument causes all object names to be matched. The search is performed recursively, unless options specifies the option FindDirectChildrenOnly.

If there is more than one child matching the search, the most direct ancestor is returned. If there are several direct ancestors, it is undefined which one will be returned. In that case, findChildren() should be used.

Я пробовал получить указатель на член класса так:

Код:
QWidget *tool=this->findChild<QWidget *>(name);
QWidget *tool=&( qobject_cast<QWidget>( this->findChild<QWidget>(name) ) );
QWidget *tool=&( qobject_cast<QWidget>( &(this->findChild<QObject>(name)) ) );
QWidget *tool=qobject_cast<QWidget *>( &(this->findChild<QObject>(name)) );

Как я только не пробовал - ничего не получается.

Вопрос. Как заполучить указатель на член класса по QObject-имени объекта?
Записан

Собираю информацию по крупицам
http://webhamster.ru
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Апрель 16, 2016, 11:59 »

Мне все твердят, что так делать ненада, нужно просто сделать кнопки членами класса, а не указатели на них. Я так и сделал:
Наоборот, совершенно (принципиально) неверно делать кнопки членами. Так Вы нарываетесь на проблемы с Qt parent-chilld, и без нужды будете ломать голову какое удаление состоится первым. Если хотите упорствовать, то обеспечьте родителя
Код
C++ (Qt)
EditorToolBar::EditorToolBar( void ) :
bold(this),
italic(this),
underline(this)
{
...
}
 
Без этого кнопари будут созданы как самостоятельные окна (parent = 0) и, конечно findChild их не найдет. И имена уж слишком ходовые, поменяйте напр на btnBold и.т.п.


Записан
PimenS
Крякер
****
Offline Offline

Сообщений: 371


Просмотр профиля
« Ответ #2 : Апрель 16, 2016, 12:05 »

У меня был класс с множеством объектов-кнопок. Эти объекты создавались динамически, то есть:

Код:
h-файл:

QToolButton *bold;
QToolButton *italic;
QToolButton *underline;

c++ файл:

QToolButton *bold=new QToolButton(this);
bold->setObjectName("editor_tb_bold");

QToolButton *italic=new QToolButton(this);
italic->setObjectName("editor_tb_italic");

QToolButton *underline=new QToolButton(this);
underline->setObjectName("editor_tb_underline");

Мне все твердят, что так делать ненада, нужно просто сделать кнопки членами класса, а не указатели на них. Я так и сделал:


Первый вариант самый правильный. И не надо никаких
Цитировать
нужно просто сделать кнопки членами класса, а не указатели на них

Правда не пойму зачем вы объявляете QToolButton, а потом делаете повторное объявление. Я бы сделал так:

Код:
h-файл:

QToolButton *bold;
QToolButton *italic;
QToolButton *underline;

c++ файл:

bold = new QToolButton(this);
bold->setObjectName("editor_tb_bold");

italic = new QToolButton(this);
italic->setObjectName("editor_tb_italic");

underline = new QToolButton(this);
underline->setObjectName("editor_tb_underline");
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #3 : Апрель 16, 2016, 20:04 »

Так Вы нарываетесь на проблемы с Qt parent-chilld
О, по-моему уже раз восьмой заходит тема... Улыбающийся
А расскажите нам пожалуйста о этих пробламах "с Qt parent-chilld".

и без нужды будете ломать голову какое удаление состоится первым.
А для чего ему ломать над этим голову? Улыбающийся
Когда там все очевидно. Улыбающийся

2 xintrea. Посмотрите на QAction.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #4 : Апрель 18, 2016, 14:44 »

Какая-то каша у обоих в головах.

Член класса - это НЕ объект в куче.

Когда используются указатели на кнопки, они могут быть как членами класса, так и не быть ими.
в первом примере у xintrea члены класса (судя по всему ни разу не инициализированный) и есть инициализированные локальные указатели.

А вот тут указатели являются членами класса и корректно инициализированы:
Код
C++ (Qt)
class SettingsDialog : public QDialog
{
QToolButton *bold;
QToolButton *italic;
QToolButton *underline;
}
 
Код
C++ (Qt)
SettingsDialog::SettingsDialog(...)
{
bold=new QToolButton(this); // не обявление новой локальной переменной, а использование ранее объявленного члена класса
bold->setObjectName("editor_tb_bold");
 
italic=new QToolButton(this);  // не обявление новой локальной переменной, а использование ранее объявленного члена класса
italic->setObjectName("editor_tb_italic");
 
underline=new QToolButton(this); // не обявление новой локальной переменной, а использование ранее объявленного члена класса
underline->setObjectName("editor_tb_underline");
}
 
Записан

Юра.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Апрель 18, 2016, 16:51 »

Какая-то каша у обоих в головах.

Член класса - это НЕ объект в куче.
А где же он если родитель в куче? Вероятно Вы хотели сказать что для виджета члена класса (не указателя) нельзя звать delete - с этим никто не спорит

А вот тут указатели являются членами класса и корректно инициализированы:
Во всяком случае более "академично" инициализировать члены в списке инициализации конструктора (а не в его теле)
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #6 : Апрель 19, 2016, 12:15 »

да, ошибся. Надо было написать "на стеке".

вторая попытка у xintrea свелась к тому, что создал члены класса на стеке, вместо того, чтобы избавиться от локальных переменных по имени совпадающих с членами класса.
Записан

Юра.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Апрель 19, 2016, 12:49 »

А вообще если собрались выдергивать объект по имени - зачем вообще член класса (хоть указатель хоть нет)? Ну и достаем его всякий раз по имени, это по крайней мере принципиально/идейно.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #8 : Апрель 19, 2016, 12:51 »

А вообще если собрались выдергивать объект по имени - зачем вообще член класса (хоть указатель хоть нет)? Ну и достаем его всякий раз по имени, это по крайней мере принципиально/идейно.
Для чего здесь виджеты совсем не понятно. Улыбающийся
QMap и QAction для этого использовать одно удовольствие.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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