Russian Qt Forum

Компиляторы и платформы => Mac OS X => Тема начата: Igors от Декабрь 30, 2014, 10:18



Название: NSWindow -> QWidget
Отправлено: Igors от Декабрь 30, 2014, 10:18
Добрый день

Как найти QWidget имея NSWindow?  QWidget::find(WId) принимает NSView - но это не NSWindow

Спасибо


Название: Re: NSWindow -> QWidget
Отправлено: Пантер от Декабрь 30, 2014, 10:31
А разве Кьют свои виджеты сам не отрисовывает под макосью? Под виндой, допустим, вся отрисовка идет внутри и винда ни о каких элементах не знает.


Название: Re: NSWindow -> QWidget
Отправлено: Igors от Декабрь 30, 2014, 10:45
А разве Кьют свои виджеты сам не отрисовывает под макосью?
Мне надо пробежаться по top-level окнам в Z-order, а в Qt этого так и нет (буду рад ошибиться). Пришлось нырять в нативняк, там можно получить массив NSWindow * (типа HWND) - а дальше?

Под виндой, допустим, вся отрисовка идет внутри и винда ни о каких элементах не знает.
В пятерке это уже не так. Контролы могут иметь HWND.  напр если позвать winId() или использовать OpenGL. Когда/зачем они создаются - не вникал, но точно есть - Spy их видит


Название: Re: NSWindow -> QWidget
Отправлено: navrocky от Декабрь 30, 2014, 11:39
Под виндой, допустим, вся отрисовка идет внутри и винда ни о каких элементах не знает.
В пятерке это уже не так. Контролы могут иметь HWND.  напр если позвать winId() или использовать OpenGL. Когда/зачем они создаются - не вникал, но точно есть - Spy их видит
[/quote]
Так было всегда, не только в пятерке.


Название: Re: NSWindow -> QWidget
Отправлено: RSATom от Декабрь 30, 2014, 11:49
Если Qt не создал HWND для виджета по некоторым своим внутренним причинам (например Widget является окном верхнего уровня) - то HWND принудительно создается как раз при вызове winId()

upd1: но это само собой касается Windows, Mac OS X так глубоко пока еще не ковырял. Но думаю там ситуация та же.


Название: Re: NSWindow -> QWidget
Отправлено: kambala от Декабрь 30, 2014, 12:19
NSWindow — наследник NSView


Название: Re: NSWindow -> QWidget
Отправлено: Igors от Декабрь 30, 2014, 12:40
Так было всегда, не только в пятерке.
Довольно громогласное заявление :) На OSX подтверждаю - и в четверке каждый контрол имел нативное представление (хотя рисовался средствами Qt). На Вындоуз я долго верил в легенду "HWND только для top окон". Впрочем это уже неважно.

NSWindow — наследник NSView
И что, как выцарапать из него QWidget? Придумал так: пробегаю по topLevelWindows, по каждому беру winId() и от нее NSWindow [view window]. Потом ищу это в массиве полученном через NSWondowList. Как-то коряво, но др мыслей нет, буду делать пример


Название: Re: NSWindow -> QWidget
Отправлено: kambala от Декабрь 30, 2014, 13:04
NSWindow — наследник NSView
И что, как выцарапать из него QWidget? Придумал так: пробегаю по topLevelWindows, по каждому беру winId() и от нее NSWindow [view window]. Потом ищу это в массиве полученном через NSWondowList. Как-то коряво, но др мыслей нет, буду делать пример
а, так QWidget::find(window) не прокатывало? как-то странно.

QWindowList QGuiApplication::​topLevelWindows()/allWindows() — не то? (qt 5)


Название: Re: NSWindow -> QWidget
Отправлено: Igors от Декабрь 30, 2014, 13:27
а, так QWidget::find(window) не прокатывало? как-то странно.
нет, наверное NSView идет агрегатом

QWindowList QGuiApplication::​topLevelWindows()/allWindows() — не то? (qt 5)
Он не сортируется (ни по Z, никак) - это давно больное место

Так работает
Код
C++ (Qt)
QVector <QWidget *> GetMacZOrderWinList( void )
{
QVector <QWidget *> dst;
NSInteger windowCount;
NSCountWindows(&windowCount);
if (windowCount <= 0) return dst;
 
QWidgetList lst = QApplication::topLevelWidgets();
QHash<NSWindow *, QWidget *> hash;
for (int i = 0; i < lst.size(); ++i) {
QWidget * widget = lst[i];
NSView * view = (NSView *) widget->winId();
if (!view) continue;
NSWindow * nsWin = [view window];
if (nsWin)
hash[nsWin] = widget;
}
 
QVector <NSInteger> src(windowCount);
NSWindowList(windowCount, &src[0]);
for (int i = 0; i < windowCount; ++i) {
        NSWindow * window = [NSApp windowWithWindowNumber:src[i]];
       if (!window) continue;
//       QWidget * w = QWidget::find((WId) window); // returns 0
QWidget * widget = hash.value(window);
if (widget) dst.push_back(widget);
}
 
return dst;
}
Но лучше бы без велосипедов (здесь :))


Название: Re: NSWindow -> QWidget
Отправлено: Авварон от Декабрь 31, 2014, 17:14
я делал это так - ловил событие activate у окна и клал в начало списка окон, удаляя из середины/конца. делается кроссплатформенно


Название: Re: NSWindow -> QWidget
Отправлено: Igors от Декабрь 31, 2014, 18:15
я делал это так - ловил событие activate у окна и клал в начало списка окон, удаляя из середины/конца. делается кроссплатформенно
То надо "самому отслеживать" - и хз что с палетками, тулзами и "посторонними" окнами


Название: Re: NSWindow -> QWidget
Отправлено: Авварон от Декабрь 31, 2014, 21:10
Ну я делал для конкретного типа окон. Собственно, варианта 2 - либо нам нужны окна определенного типа, либо все "топлевел" (за исключением туловых, попапов, меню и прочего хлама). Хлам отсеивается при помощи флагов (Qt::WindowFlags).


Название: Re: NSWindow -> QWidget
Отправлено: navrocky от Январь 01, 2015, 14:34
Так было всегда, не только в пятерке.
Довольно громогласное заявление :)
Ну да, это же была одна из ключевых фич четверки, что по умолчанию виджеты были не native и это было реализован под всеми платформами. В Qt1-3 виджеты имели под собой нативные окна.

Хотя да, "так было всегда" я погорячился )