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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: У родителя сделать меню checked  (Прочитано 4165 раз)
Alex_C
Гость
« : Апрель 19, 2012, 09:23 »

Основная форма в приложении. Из нее открываются другие окна. Индикацией, что данное окно уже открыто служит установленная галочка в меню основного окна и/или нажатая кнопка на основном окне.
В окне предка делал так:
Код:
void AbstractLogWindow::showEvent(QShowEvent *event)
{
    if(parent())
    {
        QPushButton *p = qFindChild<QPushButton *>(parent(), "m_" + m_WinName + "Button");
        if(p != 0)
        {
            p->setCheckable(true);
            p->setChecked(true);
        }
       
        QAction *m = qFindChild<QAction *>(parent(), "m_" + m_WinName + "Menu");
        if(m != 0)
        {
            m->setCheckable(true);
            m->setChecked(true);
        }
    }
}

Где WinName  - это как раз название класса окна - предка.
Однако, qFindChild в окне родителе меню QAction с таким именем "m_" + m_WinName + "Menu" не находит, хотя оно точно есть.

Вод код конструктора родителя:
Код:
MainForm::MainForm(QWidget *parent) :
    QWidget(parent)
{
    m_MenuBar = new QMenuBar(this);
    //**************************************************************************
    m_FileMenu = new QMenu(tr("&File"));
    m_FileMenu->addAction(tr("&New"),
                          this,
                          SLOT(newMenu()),
                          Qt::CTRL + Qt::Key_N);
    m_FileMenu->addSeparator();
    m_FileMenu->addAction(tr("E&xit"),
                          this,
                          SLOT(close()),
                          Qt::CTRL + Qt::Key_X);
    //**************************************************************************
    m_WindowMenu = new QMenu(tr("&Windows"));
    m_AzimuthWindowMenu = m_WindowMenu->addAction(tr("Azimuth map"),
                          this,
                          SLOT(showAzimuthMap()));
    m_AzimuthWindowMenu->setCheckable(true);

    m_CalculatorWindowMenu = m_WindowMenu->addAction(tr("Calculator"),
                          this,
                          SLOT(showCalculator()));
    //**************************************************************************
    m_MenuBar->addMenu(m_FileMenu);
    m_MenuBar->addMenu(m_WindowMenu);
}

Вот это меню m_CalculatorWindowMenu и не находится.
Записан
Alex_C
Гость
« Ответ #1 : Апрель 19, 2012, 10:14 »

Да и еще хотел бы уточнить такой момент: в конструкторе создается меню, тулбар:
Код:
QAction* pact = m_pmnuWindows->addAction("Cascade", m_pws, SLOT(cascade())); 

Переменная pact - в данном случае локальная. И время жизни ее - только в пределах этой ф-ции. Правильно ли я понимаю, что в ф-йии addAction происходит копирование объекта типа QAction - ну иначе бы этот пункт меню бы уничтожился вместе с pact?
Второе - за пределами конструктора как то можно обратиться к этому пункту меню - сделать его checked? Или для этого переменную pact нужно объявлять глобальной?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #2 : Апрель 19, 2012, 10:22 »

Правильно ли я понимаю, что в ф-йии addAction происходит копирование объекта типа QAction - ну иначе бы этот пункт меню бы уничтожился вместе с pact?
Нет не правильно, т.к. pact - это не копия, а адрес созданного в addAction объекта.

Цитировать
Второе - за пределами конструктора как то можно обратиться к этому пункту меню - сделать его checked? Или для этого переменную pact нужно объявлять глобальной?
Почему обязательно глобальной? Сделай её членом класса и сделай метод её получения.

Цитировать
QAction *m = qFindChild<QAction *>(parent(), "m_" + m_WinName + "Menu");
Чтобы искать по имени, надо это имя задать через QObject::setObjectName().
« Последнее редактирование: Апрель 19, 2012, 10:25 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Alex_C
Гость
« Ответ #3 : Апрель 19, 2012, 15:55 »

Спасибо за ответы.
Пункты 1 и 2 - нет вопросов.
А вот пункт 3 так и не заработал, хотя тоже спасибо - нашел в документации про setObjectName.

Делал так. В конструкторе главного окна:
Код:
    m_WindowMenu = new QMenu(tr("&Windows"));

    m_CalculatorWindowMenu = m_WindowMenu->addAction(tr("Calculator"),
                          this,
                          SLOT(showCalculator()));
    m_CalculatorWindowMenu->setObjectName("CalculatorWindowMenu");

при открытии окна CalculatorWindow
Код:
void AbstractLogWindow::showEvent(QShowEvent *event)
{
    if(parent())
    {
        QAction *m = parentWidget()->findChild<QAction *>(m_WinName + "Menu");

        //QAction *m = qFindChild<QAction *>(parent(), m_WinName + "Menu");
        if(m != 0)
            m->setChecked(true);
    }
}

Ни первый, ни второй вариант с findChild почему то не прошли..
Записан
Alex_C
Гость
« Ответ #4 : Апрель 19, 2012, 16:11 »

Ага! Кажется подразобрался в чем причина  - при проверке
Код:
void AbstractLogWindow::showEvent(QShowEvent *event)
{
    if(parent())
    {
        foreach(const QObject *obj, parent()->children()) {
          qDebug() << obj;
        }
    }
}

Выяснилось, что
Код:
MainForm::MainForm(QWidget *parent) :
    QWidget(parent)
{
    m_CalculatorWindowMenu = m_WindowMenu->addAction(tr("Calculator"),
                          this,
                          SLOT(showCalculator()));
    m_CalculatorWindowMenu->setObjectName("CalculatorWindowMenu");

m_CalculatorWindowMenu в children не содержится. Пока не понял, почему...

Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



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

QObject::children() возвращает ссылку на список непосредственных детей без "внуков" и "правнуков".

Цитировать
m_WindowMenu = new QMenu(tr("&Windows"));
И кстати, как ты можешь что-то найти, если ты создаёшь меню вообще без родителя.
« Последнее редактирование: Апрель 19, 2012, 16:20 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Alex_C
Гость
« Ответ #6 : Апрель 19, 2012, 16:19 »

Да, наследником является QMenuBar.
A QAction получается уже наследник QMenuBar. Сейчас попробую до него добраться )))
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Апрель 19, 2012, 16:23 »

Да, наследником является QMenuBar.
A QAction получается уже наследник QMenuBar. Сейчас попробую до него добраться )))
QMenuBar::addMenu( QMenu* menu ) не устанавливает родителя для menu.
Т.е. у тебя нарушена иерархия объектов, поэтому ничего не находится.
« Последнее редактирование: Апрель 19, 2012, 16:26 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Alex_C
Гость
« Ответ #8 : Апрель 19, 2012, 16:42 »

Вот я чую, что само меню неправильно как то задаю, хотя вроде как все по книге делаю.
Работать то оно как и написано, работает, но вот что я не пойму - при addMenu я добавляю пункты меню верхнего уровня. Для добавления подменю в документации написано addAction... Но они не являются предками меню... Вариант конечно делать их public в классе и к ним напрямую обращаться...
Записан
Alex_C
Гость
« Ответ #9 : Апрель 19, 2012, 17:07 »

В общем еще раз перечитал главу книги про меню, и понял, что надо делать не так - надо как раз передавать ссылку на QAction - потому как это может использоваться не только в меню, но и в ToolBar.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Апрель 19, 2012, 17:45 »

Вот я чую, что само меню неправильно как то задаю, хотя вроде как все по книге делаю.
Работать то оно как и написано, работает, но вот что я не пойму - при addMenu я добавляю пункты меню верхнего уровня. Для добавления подменю в документации написано addAction... Но они не являются предками меню... Вариант конечно делать их public в классе и к ним напрямую обращаться...
В духе Qt испустить сигнал, а поймавший слот займется установкой галочки
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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