Qt4: лучший способ получить доступ к родительскому классу (1 уровень вверх, 2 уровня вверх ....) - PullRequest
1 голос
/ 25 марта 2011

Мне интересно, как получить доступ к родительскому классу в моем приложении Qt. Допустим, мой проект имеет следующую структуру:

mainWindow: MainWindow
    tabWidget: QTabWidget
        tab1: MySubClass1
        tab2: MySubClass2
            tabWidget: QTabWidget
                xtab1: MySubSubClass1
                xtab2: MySubSubClass2

Это немного упрощено. Я хочу получить доступ к объекту mainWindows из одной из функций слота xtab2.

(1) Какой метод будет лучшим? Я пытался передать указатель на mainWindow вдоль дерева, но я получаю ошибки времени выполнения.

(2) Стоит ли включать mainwindow.h в файл xtab.h или в файл xtab.cpp?

Спасибо за помощь:)

Ответы [ 5 ]

3 голосов
/ 25 марта 2011

Если вам действительно нужно главное окно, лучше всего передать указатель MainWindow.Недостаток статического метода заключается в том, что он перестает работать с более чем одним главным окном.

Я бы предложил избегать доступа к главному окну из содержащихся в нем виджетов и использовать вместо этого сигналы.Например:

class MainWindow {
    public:
        explicit MainWindow( QWidget* parent=0 ) {
            tab = new TabWidget;
            ...
            MySubSubClass1* ssw1 = new MySubSubClass;
            connect( ssw1, SIGNAL(textChanged(QString)), this, SLOT(page1TextChanged(QString));
            tab->addWidget( ssw1 );
        }

   private Q_SLOTS:
         void page1TextChanged( const QString& ) {
             //do something...
         }  
};

MySubSubClass1 затем испускает textChanged (), addresseeChanged () (например, в адресной книге) или любой уровень абстракции или детализации, который имеет смысл на более высоком уровне.Таким образом, MySubSubClass является универсальным и вообще не должен знать о MainWindow.Это может быть повторно использовано в любом другом контексте.Если MySubSubClass содержит другие виджеты, он может снова подключиться к их сигналам.

2 голосов
/ 25 марта 2011

Вы можете создать статический метод и объект внутри MainWindow, который будет возвращать объект mainwindow.

Примерно так:

private:
     static MainWindow* _windowInstance

public:
     static MainWindow* windowInstance()
     {
          return _windowInstance;
     }

В большинстве случаев это кажется самым простым решением. Теперь вам просто нужно включить mainwindow.h всякий раз, когда вам нужен доступ к этому объекту.

И не забудьте инициализировать _windowInstance в конструкторе, как это;

_windowInstance = this;
1 голос
/ 28 марта 2011

Существует множество различных решений этой проблемы, из которых вы выбрали ответ, с точки зрения ориентации объекта и инкапсуляции, один из худших. Некоторые мысли

  • Инкапсуляция: если вы обнаружите, что вам необходимо обеспечить доступ на большие расстояния (по длинной цепочке контейнеров или подклассов), вы можете захотеть взглянуть на функциональность, которую вы пытаетесь распространить. Я мог бы сказать, что он должен быть инкапсулирован в отдельный класс, который может передаваться легче, чем там, где он в настоящее время находится (главное окно в вашем случае).

  • Абстракция: Если вам не требуется доступ к функциональности QMainWindow, не передавайте указатель на ваш класс MainWindow, создайте интерфейс для нужной вам функциональности, пусть ваш MainWindow реализует этот интерфейс и передать и объект типа интерфейса вместо вашего типа MainWindow.

  • Сигналы и слоты: как заметил Фрэнк, реализуйте соответствующую функциональность, используя механизм сигнализации Qt, это превращает соединение между вызывающим и вызываемым в динамическое, снова отделяя его от фактического класса MainWindow

  • QApplication: если вам абсолютно необходимо, чтобы глобальная информация ограничивала точку входа, у вас уже есть один единственный объект QApplication, сделайте его сопровождающим всех других объектов, которые должны быть доступны глобально, создайте свое собственное QApplication класс и поддерживать глобальные ссылки там. Ваш класс QApplication может затем создать или уничтожить необходимые глобальные объекты.

Получив больше информации о том, что вам нужно сделать с экземпляром MainWindow или о чем нужно сообщить, вы также получите лучшие ответы

1 голос
/ 25 марта 2011

Под родительским классом я предполагаю, что вы имеете в виду родительский виджет?

Если вы хотите найти виджет верхнего уровня, QWidget :: window () укажет вам на него.Используйте dynamic_cast или qobject_cast, чтобы превратить его в объект MainWindow.

Если вы хотите подняться на какой-нибудь произвольный уровень, используйте paerntWidget().

0 голосов
/ 25 марта 2011
QWidget* parent = this ;
while (parent -> parentWidget()) parent = parent -> parentWidget() ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...