2013-02-26 8 views
5

Poszukuję miłej metody adresowania aplikacji Qt do Qt/Necessitas (Android).Qt/Necessitas - uzasadniona wymiana/skóra QFileDialog?

Niektóre z widgetów QtGUI są absolutnie okropne - niestety, w tym QFileDialog.

Czy znasz jakieś zamiany o odpowiednim wyglądzie i charakterze? Czy tworzenie QFileDialog jest użyteczne w dowolnym miejscu blisko wysokiego priorytetu dla programistów Necessitas?

#include <QApplication> 

#include <QFileDialog> 

int main(int argc, char* argv[]) { 
    QApplication a(argc, argv); 

    QString fileName = QFileDialog::getOpenFileName(NULL, 
     QObject::tr("Open Image"), "/home/jana", QObject::tr("Image Files (*.png *.jpg *.bmp)")); 

    a.exec(); 
} 

QFileDialog

+0

Co masz na myśli - okropne? Ten jest absolutnie zgrabny! – mlvljr

Odpowiedz

1

Można łatwo zbudować własny plik dialog zarówno z QtWidgets lub QML, za pomocą QFileSystemModel klasę out-of-the-box.

Jeśli chodzi o to, czy jest to priorytet, czy nie, w tym momencie wydaje się, że Necessitas zostaną wchłonięte przez wysiłki Digii na rzecz wsparcia Androida. Wątpię, aby doszło do znaczących wysiłków w celu odpowiedniego stylu QtWidgets, ponieważ moduł jest oznaczony jako ZROBIONY, a cały nacisk na interfejs użytkownika jest w QML. Więc nie będę wstrzymywał oddechu, gdybym był tobą. Ponadto widżety Qt są całkowicie nieprzyjemne na platformach innych niż komputery stacjonarne.

3

Android nie ma własnego, macierzystego okna dialogowego pliku. Możemy użyć QtAndroidExtras powołać zewnętrznej aplikacji, która jest w stanie odebrać plik:

chosing external application

pisałem opakowanie, które mogłyby być wykorzystane do tego. Oto pełny kod:

androidfiledialog.h

#ifndef ANDROIDFILEDIALOG_H 
#define ANDROIDFILEDIALOG_H 

#include <QObject> 
#include <QAndroidJniObject> 
#include <QtAndroid> 
#include <QAndroidActivityResultReceiver> 

class AndroidFileDialog : public QObject 
{ 
    Q_OBJECT 

public: 
    explicit AndroidFileDialog(QObject *parent = 0); 
    virtual ~AndroidFileDialog(); 
    bool provideExistingFileName(); 

private: 
    class ResultReceiver : public QAndroidActivityResultReceiver { 
     AndroidFileDialog *_dialog; 
    public: 
     ResultReceiver(AndroidFileDialog *dialog); 
     virtual ~ResultReceiver(); 
     void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data); 
     QString uriToPath(QAndroidJniObject uri); 
    }; 

    static const int EXISTING_FILE_NAME_REQUEST = 1; 
    ResultReceiver *receiver; 
    void emitExistingFileNameReady(QString result); 

signals: 
    void existingFileNameReady(QString result); 
}; 

#endif // ANDROIDFILEDIALOG_H 

androidfiledialog.cpp

#include "androidfiledialog.h" 

AndroidFileDialog::ResultReceiver::ResultReceiver(AndroidFileDialog *dialog) : _dialog(dialog) {} 
AndroidFileDialog::ResultReceiver::~ResultReceiver() {} 

void AndroidFileDialog::ResultReceiver::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) 
{ 
    jint RESULT_OK = QAndroidJniObject::getStaticField<jint>("android/app/Activity", "RESULT_OK"); 
    if (receiverRequestCode == EXISTING_FILE_NAME_REQUEST && resultCode == RESULT_OK) { 
     QAndroidJniObject uri = data.callObjectMethod("getData", "()Landroid/net/Uri;"); 
     QString path = uriToPath(uri); 
     _dialog->emitExistingFileNameReady(path); 
    } else { 
     _dialog->emitExistingFileNameReady(QString()); 
    } 
} 

QString AndroidFileDialog::ResultReceiver::uriToPath(QAndroidJniObject uri) 
{ 
    if (uri.toString().startsWith("file:", Qt::CaseInsensitive)) { 
     return uri.callObjectMethod("getPath", "()Ljava/lang/String;").toString(); 
    } else { 
     QAndroidJniObject contentResolver = QtAndroid::androidActivity().callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;"); 
     QAndroidJniObject cursor = contentResolver.callObjectMethod("query", "(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;", uri.object<jobject>(), 0, 0, 0, 0); 
     QAndroidJniObject DATA = QAndroidJniObject::fromString("_data"); 
     jint columnIndex = cursor.callMethod<jint>("getColumnIndexOrThrow", "(Ljava/lang/String;)I", DATA.object<jstring>()); 
     cursor.callMethod<jboolean>("moveToFirst", "()Z"); 
     QAndroidJniObject result = cursor.callObjectMethod("getString", "(I)Ljava/lang/String;", columnIndex); 
     return result.isValid() ? result.toString() : QString(); 
    } 
} 

AndroidFileDialog::AndroidFileDialog(QObject *parent) : QObject(parent) 
{ 
    receiver = new ResultReceiver(this); 
} 

AndroidFileDialog::~AndroidFileDialog() 
{ 
    delete receiver; 
} 

bool AndroidFileDialog::provideExistingFileName() 
{ 
    QAndroidJniObject ACTION_GET_CONTENT = QAndroidJniObject::fromString("android.intent.action.GET_CONTENT"); 
    QAndroidJniObject intent("android/content/Intent"); 
    if (ACTION_GET_CONTENT.isValid() && intent.isValid()) { 
     intent.callObjectMethod("setAction", "(Ljava/lang/String;)Landroid/content/Intent;", ACTION_GET_CONTENT.object<jstring>()); 
     intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QAndroidJniObject::fromString("file/*").object<jstring>()); 
     QtAndroid::startActivity(intent.object<jobject>(), EXISTING_FILE_NAME_REQUEST, receiver); 
     return true; 
    } else { 
     return false; 
    } 
} 

void AndroidFileDialog::emitExistingFileNameReady(QString result) 
{ 
    emit existingFileNameReady(result); 
} 

Trzeba dodać do pliku * .pro:

QT += androidextras 

użyciu przykład:

AndroidFileDialog *fileDialog = new AndroidFileDialog(); 
connect(fileDialog, SIGNAL(existingFileNameReady(QString)), this, SLOT(openFileNameReady(QString))); 
bool success = fileDialog->provideExistingFileName(); 
if (!success) { 
    qDebug() << "Problem with JNI or sth like that..."; 
    disconnect(fileDialog, SIGNAL(existingFileNameReady(QString)), this, SLOT(openFileNameReady(QString))); 
    //or just delete fileDialog instead of disconnect 
} 

realizacja gniazdo:

void MyClass::openFileNameReady(QString fileName) 
{ 
    if (!fileName.isNull()) { 
     qDebug() << "FileName: " << fileName; 
    } else { 
     qDebug() << "User did not choose file"; 
    } 
} 

Proszę potwierdzić to rozwiązanie działa prawidłowo na urządzeniu.

Powiązane problemy