×

Discussion Board

Results 1 to 5 of 5
  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    18

    Question Using CommonDialog as a UI for work in C++

    I'm writing an ePub reader for Symbian, using QML and C++. My current task is building a library of books. To do this, I'm using C++ to recurse though the directory structure, searching for epub files, the file paths of which are added to a QStringList. The list of epubs is then parsed for metadata and added to an SQL database(when I've written the code to do that). As this process takes some time, I'm using a CommonDialog which is connected to signals in the C++ code to display informative feedback to the user, including how many books have been found, and how many have been successfully added to the library. The C++ function is started from the Component.onCompleted() function of the dialog. I'm using a CommonDialog because I want to conform to the standard look and feel, and the C++ because I'm using the QuaZip file to handle the epub files (which are basically zip archives).

    The problem I'm having is that the CommonDialog is not displayed while the C++ function is running. It only appears once the C++ has finished. Once it does appear, it looks correct, which tells me the QML is listening to the signals emitted from the C++, but the C++ is interfering with the updating of the Dialog.

    My initial thoughts are that I should use QThread to put the file searching in a separate thread. Would this be the best way to go about it?

    Some code:
    The dialog:
    Code:
    CommonDialog {
        id: window
        property alias topText: topTextLabel.text
        property alias bottomText: bottomTextLabel.text
        property alias indeterminate: searchProgress.indeterminate
        property alias minimumValue: searchProgress.minimumValue
        property alias maximumValue: searchProgress.maximumValue
        property alias value: searchProgress.value
    
        Connections {
            target: Library
    
            onBookFound: {
                var books = (numberOfBooks === 1)? " book":" books"
                topText = "Found " + numberOfBooks + books
                bottomText = bookFile
            }
    
            onBookSearchFinished: {
                titleText = "Adding books to library"
                topText = "Book 0 of " + numberFound
                indeterminate = false
                minimumValue = 0
                maximumValue = numberFound
            }
    
            onParsingBookIndex: {
                value = (index + 1)
                topText = "Book " + (index + 1) + " of " + maximumValue
            }
            onParseBookMessage: {
                bottomText = message
            }
    
        }
    
    
        titleText: "Searching for books"
        buttonTexts:["Cancel"]
        content: Column {
            anchors.fill: parent
    
            Label {
                id: topTextLabel
                anchors.left: parent.left
                anchors.leftMargin: platformStyle.paddingMedium
                anchors.right: parent.right
                anchors.rightMargin: platformStyle.paddingMedium
            }
    
            ProgressBar {
                id: searchProgress
                anchors.left: parent.left
                anchors.leftMargin: platformStyle.paddingMedium
                anchors.right: parent.right
                anchors.rightMargin: platformStyle.paddingMedium
            }
    
            Label {
                id: bottomTextLabel
                anchors.left: parent.left
                anchors.leftMargin: platformStyle.paddingMedium
                anchors.right: parent.right
                anchors.rightMargin: platformStyle.paddingMedium
            }
        }
    
        Component.onCompleted: {
            topText = "Found 0 books"
            indeterminate = true
            Library.searchForBooks()
        }
    }
    The C++ function which does the work.
    Code:
    void Library::searchForBooks()
    {
        QSystemStorageInfo storage;
        QStringList driveList = storage.logicalDrives();
        int booksAdded = 0;
        
    
        // bookList is a QStringList
        bookList.clear();    
        emit bookSearchStarted();
        
        
        
        // Loop through all drives, searching for .epub files.
        foreach (QString drive, driveList)
        {
            //qDebug() << "Checking drive " << drive;
            QSystemStorageInfo::DriveType type = storage.typeForDrive(drive);
            if (type == QSystemStorageInfo::InternalDrive ||
                    type == QSystemStorageInfo::InternalFlashDrive ||
                    type == QSystemStorageInfo::RemovableDrive)
            {
                // listBooks recursively searches through a QDir, 
                // finding EPUB files which are added to bookList.
                listBooks(QDir(drive + ":/"));
            }
        }
        emit bookSearchFinished(bookList.count());
    
    
        // Iterate through bookList parsing the books.
        for (int index = 0; index < bookList.count(); index++)
        {
            QString book = bookList[index];
            emit parsingBookIndex(index);
            // parseBook() returns true if the book has been 
            // successfully added to the library
            if (parseBook(book))
                booksAdded++;
        }
        emit bookParseFinished(booksAdded);
    }

  2. #2
    Regular Contributor
    Join Date
    Mar 2012
    Posts
    144

    Re: Using CommonDialog as a UI for work in C++

    this is ok. Component.onComplited calls at last point of component creation just before show it
    you have to call your c++ method right after calling open() for your dialog

  3. #3
    Registered User
    Join Date
    Jan 2011
    Posts
    18

    Re: Using CommonDialog as a UI for work in C++

    Quote Originally Posted by vladestCh View Post
    this is ok. Component.onComplited calls at last point of component creation just before show it
    you have to call your c++ method right after calling open() for your dialog
    I originally called the C++ method as you say, just after opening the dialog, and had the same problem, which is why I moved it to Component.onCompleted(). Are you saying putting the C++ method in a separate QThread is the way to go?

  4. #4
    Regular Contributor
    Join Date
    Mar 2012
    Posts
    144

    Re: Using CommonDialog as a UI for work in C++

    well, this is one possible solution
    another is some kind of hack, but you can call processEvent() in your c++ method to make UI responsible

  5. #5
    Registered User
    Join Date
    Jan 2011
    Posts
    18

    Thumbs up Re: Using CommonDialog as a UI for work in C++

    Adding a QCoreApplication::processEvents() call in each of the for or foreach loops has done the trick, and made the UI responsive.

    Thanks for your help!

Similar Threads

  1. Replies: 3
    Last Post: 2012-06-13, 12:17
  2. QML CommonDialog, onButtonClicked
    By akinorta in forum [Archived] Qt Quick
    Replies: 1
    Last Post: 2012-04-13, 13:26
  3. Replies: 1
    Last Post: 2010-12-17, 13:31
  4. Replies: 4
    Last Post: 2010-12-06, 11:32

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×