Я пытаюсь принять удаление файла в OSX Dock, или программа дважды щелкает и открывает «зарегистрированное» расширение файла, но не увенчалась успехом в том, что в принципе должно быть простым делом.Я много исследовал переполнение стека и другие места в Интернете, но не нашел решения.
Программа написана на C ++ с использованием Qt 5.3 для Mac OSX 10.11.6.
В основной программекод (Test.cpp), я определил фильтр событий, где событие QFileOpenEvent срабатывает, но событие не передается в MainWindow.Тем не менее, события перетаскивания передаются правильно.
В MainWindow.cpp я определил еще один фильтр событий.Он правильно открывает мой файл, когда он перетаскивается в собственно MainWindow, но никогда не получает событие открытия файла из Test.cpp, когда файл перетаскивается в Dock или дважды щелкается из Finder.
Я неЯ не полностью понимаю этот механизм, поэтому любая помощь будет принята с благодарностью.Я, должно быть, делаю что-то в корне неправильно.
Код, которому нужно следовать: Test.cpp, MainWindow.cpp, Info.plist (где, я считаю, я правильно зарегистрировал расширение моего типа файлов.
int main (int argc, char *argv[])
{
QApplication qappl (argc, argv);
QDesktopWidget qdesk;
QRect qrect;
MainWindow qwin;
Test *poEventFilter = new Test;
qappl.installEventFilter((QObject *)poEventFilter);
qwin.show();
qwin.setWindowOpacity(0.0);
qrect = qdesk.availableGeometry(-1);
qwin.move((qrect.width() - qwin.width()) / 2.0, (qrect.height() - qwin.height()) / 2.0);
qwin.setWindowOpacity(1.0);
return qappl.exec();
}
Test::Test (void)
{
QApplication::setOrganizationName("XYZ");
QApplication::setApplicationName("Test");
QApplication::setApplicationVersion("v1.0.0");
return;
}
Test::~Test (void)
{
return;
}
void Test::dragEnterEvent (QDragEnterEvent *pqevent)
{
if (pqevent->mimeData()->hasUrls())
pqevent->acceptProposedAction();
return;
}
void Test::dragMoveEvent (QDragMoveEvent *pqevent)
{
if (pqevent->mimeData()->hasUrls())
pqevent->acceptProposedAction();
return;
}
void Test::dropEvent (QDropEvent *pqevent)
{
if (pqevent->mimeData()->hasUrls())
pqevent->acceptProposedAction();
return;
}
bool Test::eventFilter (QObject *pqobj, QEvent *pqevent)
{
if (pqevent->type() == QEvent::FileOpen)
{
QFileOpenEvent *pqopenEvent = static_cast<QFileOpenEvent *>(pqevent);
qDebug() << "Test FileOpen:" << pqopenEvent->file();
}
else
if (pqevent->type() == QEvent::DragEnter)
qDebug() << "Test DragEnter";
else
if (pqevent->type() == QEvent::DragMove)
qDebug() << "Test DragMove";
else
if (pqevent->type() == QEvent::Drop)
qDebug() << "Test Drop";
return QObject::eventFilter(pqobj, pqevent);
}
Вот MainWindow.cpp, где определен другой фильтр событий.
MainWindow::MainWindow (QWidget *pqwgtParent) :
QMainWindow(pqwgtParent),
gpUi(new Ui::MainWindow)
{
this->setAcceptDrops(true);
this->installEventFilter(this);
gpUi->setupUi(this);
createMenus();
createToolBars();
createStatusBar();
connectWidgets();
setValidators();
initWindow();
}
void MainWindow::dragEnterEvent (QDragEnterEvent *pqevent)
{
if (pqevent->mimeData()->hasUrls())
pqevent->acceptProposedAction();
return;
}
void MainWindow::dragMoveEvent (QDragMoveEvent *pqevent)
{
if (pqevent->mimeData()->hasUrls())
pqevent->acceptProposedAction();
return;
}
void MainWindow::dropEvent (QDropEvent *pqevent)
{
if (pqevent->mimeData()->hasUrls())
pqevent->acceptProposedAction();
return;
}
bool MainWindow::eventFilter (QObject *pqobj, QEvent *pqevent)
{
QList<QUrl> qurlList;
QObject *pqobj_;
QString qstFileSpec;
int i;
pqobj_ = pqobj; // Satisfy the compiler
if (pqevent->type() == QEvent::DragEnter)
{
qout << "MainWindow DragEnter Event" << endl;
pqevent->accept();
}
else
if (pqevent->type() == QEvent::DragMove)
{
qout << "MainWindow DragMove Event" << endl;
pqevent->accept();
}
else
if (pqevent->type() == QEvent::Drop)
{
qout << "MainWindow Drop Event" << endl;
pqevent->accept();
const QMimeData *pqmimeData = static_cast<QDropEvent *>(pqevent)->mimeData();
if (pqmimeData->hasUrls())
{
qurlList = pqmimeData->urls();
for (i = 0; i < qurlList.size(); i++)
{
qstFileSpec = qurlList.at(i).toLocalFile();
if (qstFileSpec.endsWith(".xyz"))
{
qout << "MainWindow FileSpec: " << qstFileSpec << endl;
doOpenTestFile(qstFileSpec);
}
}
}
}
else
if (pqevent->type() == QEvent::FileOpen)
{
qout << "MainWindow FileOpen Event" << endl;
pqevent->accept();
QFileOpenEvent *pqopenEvent = static_cast<QFileOpenEvent *>(pqevent);
qstFileSpec = pqopenEvent->file();
qout << "MainWindow FileSpec: " << qstFileSpec << endl;
doOpenTestFile(qstFileSpec);
}
else
return(false);
return(false);
}
Наконец, вот Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleIconFile</key>
<string>Test.icns</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>Test</string>
<key>CFBundleIdentifier</key>
<string>ninjei.xyz.Test</string>
<key>NOTE</key>
<string>This file was generated by Qt/QMake.</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Test</string>
<key>CFBundleTypeExtensions</key>
<array>
<string>xyz</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>Test.icns</string>
<key>CFBundleTypeName</key>
<string>Test file</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSTypeIsPackage</key>
<false />
<key>NSPersistentStoreTypeKey</key>
<string>Binary</string>
</dict>
</array>
</dict>
</plist>
В качестве второго (гораздо менее важного) вопроса,есть ли способ добавить qmake в часть CFBundleDocumentTypes через Test.pro?