无法接受OSX Dock上的文件删除,或双击文件并使其在程序中打开

时间:2019-02-03 10:21:41

标签: c++ macos qt

我试图接受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?

0 个答案:

没有答案