我试图接受OSX Dock上的文件删除,或者双击并打开该程序的“已注册”文件扩展名,但是基本上没有什么成功,这基本上是一件简单的事情。我已经对堆栈溢出以及Internet上的其他地方进行了广泛的研究,但是没有找到解决方案。
程序是使用Mac OSX 10.11.6的Qt 5.3用C ++编写的。
在主程序代码(Test.cpp)中,我定义了一个事件过滤器,其中触发了QFileOpenEvent事件,但该事件未传递给MainWindow。但是,拖放事件已正确传递。
在MainWindow.cpp中,我定义了另一个事件过滤器。将文件拖到MainWindow上时,它可以正确打开我的文件,但是将文件拖到Dock或从Finder双击时,从Test.cpp不会收到文件打开事件。
我对这种机制不完全了解,因此将不胜感激。我肯定在这里做错了。
要遵循的代码: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>
作为第二个(不那么重要的问题),是否可以通过Test.pro在CFBundleDocumentTypes部分中添加qmake?