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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Нативный QFileDialog  (Прочитано 4571 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Апрель 08, 2021, 11:55 »

Добрый день

1) Заголовок/title пуст (хотя текст даю)

2) Имя файла должно быть selected но без extension (т.е. "Gro3" выбрано ".prj" нет)

Как порешать? OSX 10.14, Qt 5.12

Спасибо
« Последнее редактирование: Апрель 08, 2021, 12:03 от Igors » Записан
tux
Крякер
****
Offline Offline

Сообщений: 399



Просмотр профиля
« Ответ #1 : Апрель 08, 2021, 12:10 »

Покажите сам код. Экстрасенсы на каникулах.
Записан

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

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Апрель 08, 2021, 12:39 »

Покажите сам код. Экстрасенсы на каникулах.
Кода море  Улыбающийся
Код
C++ (Qt)
QString name = QFileDialog::getSaveFileName(0, "Create Project File", "/Users/igor/Documents/Gro3.prj");
Записан
tux
Крякер
****
Offline Offline

Сообщений: 399



Просмотр профиля
« Ответ #3 : Апрель 08, 2021, 18:28 »

А если написать как-то так:
Код:
    QFileDialog *dlg = new QFileDialog();
    dlg->setWindowTitle("Create Project File");
    dlg->selectFile("/Users/igor/Documents/Gro3.prj");
    int res = dlg->exec();
    if(res == QFileDialog::Accepted)
    {
        QString name = dlg->selectedFiles().at(0);
    }
Просто посмотреть.
Записан

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

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Апрель 09, 2021, 09:33 »

А если написать как-то так:
Пробовал и так - тот же эффект. Для QFileDialog вызов setWindowTitle заливает новое имя в "options", как и конструктор или статик. Само же нативное окно создается в начале exec вызовом NSSavePanel (Objective С). Вчера остаток дня пытался как-то "подлезть" к этому "хендлу", но все мэртво private  Плачущий Видимо придется писать нативный код вместо QFileDialog, др пути не видно
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4724



Просмотр профиля WWW
« Ответ #5 : Апрель 09, 2021, 10:14 »

добраться до уже открытой панели можно через небольшой хак:
Код
C++ (Qt)
   connect(b, &QPushButton::clicked, [this]{
       macosHack();
       QString name = QFileDialog::getSaveFileName(0, "Create Project File", "/Gro3.prj");
   });
 
// в .mm файле
#include <dispatch/dispatch.h>
#import <AppKit/AppKit.h>
 
void Widget::macosHack()
{
   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
                      auto savePanel = static_cast<NSSavePanel *>(NSApp.keyWindow);
                  });
}
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Апрель 09, 2021, 11:23 »

добраться до уже открытой панели можно через небольшой хак:
Вот это подход! Правильно ли я понял что по сути мне нужно (NSApp.keyWindow) когда оно станет активной? И все эти dispatch'и - те же игры с таймером? Тогда может  "попробывать" QPlatformSurfaceEvent (которое приходит но имеет только факт создания) ?

И заодно: как убедиться что keyWindow - действительно экземпляр NSSavePanel (аналог dynamic_cast на Objective)?

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

Сообщений: 4724



Просмотр профиля WWW
« Ответ #7 : Апрель 09, 2021, 11:28 »

добраться до уже открытой панели можно через небольшой хак:
Вот это подход! Правильно ли я понял что по сути мне нужно (NSApp.keyWindow) когда оно станет активной? И все эти dispatch'и - те же игры с таймером? Тогда может  "попробывать" QPlatformSurfaceEvent (которое приходит но имеет только факт создания) ?

И заодно: как убедиться что keyWindow - действительно экземпляр NSSavePanel (аналог dynamic_cast на Objective)?

Спасибо
все верно. скорее всего где-то должен быть нативный notification о появлении нового окна (глубоко не копал) — это будет самый лучший подход (во всяком случае в iOS такое есть, и notification несет в себе хэндл окна).

про QPlatformSurfaceEvent ничего не могу сказать.

проверить класс:
Код
Objective-C
/*BOOL*/ bool isSavePanel = [NSApp.keyWindow isKindOfClass:[NSSavePanel class]];
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Апрель 10, 2021, 09:44 »

Получить NSSavePanel до отрисовки не удалось, реализовал полностью нативный вариант. То конечно громко сказано, скопировал Qt код и вставил свой сетуп (перед примечаниями)
Код
C++ (Qt)
QString CocoaFileSave( const QString & iPrompt, const QString & thePath )
{
   NSSavePanel * savePanel = [NSSavePanel savePanel];
 
   QFileInfo info(thePath);
 
   [savePanel setDirectoryURL: [NSURL fileURLWithPath:info.absolutePath().toNSString()]];
   [savePanel setNameFieldStringValue:info.fileName().toNSString()];
 
   [savePanel setAllowsOtherFileTypes:YES];
   [savePanel setExtensionHidden:NO];
   [savePanel setCanCreateDirectories:YES];
   [savePanel setNameFieldLabel:iPrompt.toNSString()];
   [savePanel setShowsTagField:NO];
   [savePanel setAccessoryView:nil];
 
   // Call processEvents in case the event dispatcher has been interrupted, and needs to do
   // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
   // close down during the cleanup.
   qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
 
   // Make sure we don't interrupt the runModal call below.
   clearCurrentThreadCocoaEventDispatcherInterruptFlag();
 
   auto result = [savePanel runModal];
 
   QAbstractEventDispatcher::instance()->interrupt();
   if (result != NSModalResponseOK) return QString();
 
   return QString::fromNSString([[savePanel URL] path]).normalized(QString::NormalizationForm_C);
}
 
С памятью надеюсь что ихний сборщик мусора уберет. Работает (аттач), правда текст в title так и не появился, эта пропердь не работает. Насколько я понял, начиная с какой-то версии OSX это убрали. Взамен можно написать текст вверху в области клиента. Ну меня больше устроил prompt слева от имени файла. А selection само рассосвлось, я ничего не делал.

Мелкая проблемка возникает с ф-цией "clear..". В оригинале это статик метод QCocoaEventDispatcher, но так не линкует. Конечно я подкинул libqcocoa.dylib (диспатчер точно там), но линкер его не видит - и все тут! Пришлось скопировать метод к себе и там порезать один qobject_cast (по тем же причинам). Конечно любопытно что за бяка, но тратить еще неск дней на это не могу.
« Последнее редактирование: Апрель 10, 2021, 09:46 от Igors » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4724



Просмотр профиля WWW
« Ответ #9 : Апрель 10, 2021, 11:30 »

Цитировать
С памятью надеюсь что ихний сборщик мусора уберет
лучше не надеяться, а самому об этом позаботиться:
Код
Objective-C
@autoreleasepool {
// код
}
или
Код
Objective-C
auto pool = [NSAutoreleasePool new];
// код
[pool release];
return some_cpp_object;
 
нужный вариант зависит от испольвания ARC.
Цитировать
В оригинале это статик метод QCocoaEventDispatcher, но так не линкует. Конечно я подкинул libqcocoa.dylib (диспатчер точно там), но линкер его не видит - и все тут!
если символ не объявлен экспортируемым и/или либа собрана с symbols hidden by default, то линкер не увидит этот метод.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Апрель 10, 2021, 11:47 »

нужный вариант зависит от испольвания ARC.
Ладно, откроем ихний букварь
Цитировать
Important

If you use Automatic Reference Counting (ARC), you cannot use autorelease pools directly. Instead, you use @autoreleasepool blocks. For example, in place of:
А я и не знаю что я юзаю, тупенько переписал  Улыбающийся Кто удалит savePanel и неск NSString?

если символ не объявлен экспортируемым и/или либа собрана с symbols hidden by default, то линкер не увидит этот метод.
То ясно, но почему из QFileDialog все линкуется ?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4724



Просмотр профиля WWW
« Ответ #11 : Апрель 10, 2021, 14:27 »

А я и не знаю что я юзаю, тупенько переписал  Улыбающийся Кто удалит savePanel и неск NSString?
проверить очень просто: компилятор пропустит лишь один из двух вариантов Улыбающийся или поискать во флажках компилятора -fobjc-arc (в проекте Xcode там также есть отдельная настройка).

когда нативного кода немало, то лучше все-таки включать ARC, чтоб память руками не чистить (не вызывать release/autorelease руками).
То ясно, но почему из QFileDialog все линкуется ?
без подглядывания в правила сборки Qt не скажешь
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Апрель 10, 2021, 16:08 »

проверить очень просто: компилятор пропустит лишь один из двух вариантов Улыбающийся или поискать во флажках компилятора -fobjc-arc (в проекте Xcode там также есть отдельная настройка).
У меня off, Немного почитал про освобождение, пока не очень понял. Ну ладно, а попастись на готовом (в лучших традициях форума)
Код:
QMacAutoReleasePool pool; // добавить первой строкой
?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4724



Просмотр профиля WWW
« Ответ #13 : Апрель 10, 2021, 20:02 »

да, так тоже должно сработать
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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