Russian Qt Forum

Qt => Model-View (MV) => Тема начата: stima от Октябрь 25, 2011, 14:09



Название: ListViwe и ItemDelegat
Отправлено: stima от Октябрь 25, 2011, 14:09
Здравствуйте)

Даже не знаю с чего начать. Пишу десктоп приложения для api Vkontakte. Сначала о том как я это себе представляю:
1. Показуется виджет Login унаследованный от QWebView с страницей логина получаю token.
2. В классе Controller посылаю запрос, получаю ответ, парсю.

Тут есть некоторая проблемка:
когда запрос получен я с Login посылаю сигнал connected(token), который соединен с Controllr'ом и запускает запрос через QNetworkManagera, и хочу закрыть Login, но проблема в том, что если зразу после высылки сигнала сделать close() то сигнал "недоходит" до Controllera, если же не закрывать, то там происходит переадрисация на ненужную страницу.

3. Отобразить полученные данные.
Тут и заключается мое не понимание, а как именно:
Я думал так. Когда Controller обработал данные он высылает данные главному Gui ( у меня сейчас это класс унаследованный от QWidget ). В этом классе происходит динамическое создание виджетов ( класса FriendInfoWdg унаследованного от QWidget ) и они помещаются в QVBoxLayout, который в последствии становиться layout'ом главного виджета. Но есть некоторые проблемки:
1. Нету скрола ( т.е. главный виджет просто растягивается на максимум )
2. Если начать добавлять много виджетов, то происходит зависание приложения.

Почитав про ListView я подумал, можно ли, сделать свои Item'ы? Что для этого нужно ( про наследования от ItemDelegata я читал,  но не совсем понятно как там разместить нужные мне QLabel)? Может есть метод проще?


Название: Re: ListViwe и ItemDelegat
Отправлено: stima от Октябрь 25, 2011, 15:40
Решил добавить код

main.cpp
Код:
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Login login;
    Controller controller;
    FriendsView friendsView;

    login.show();

    QObject::connect(&login, SIGNAL(connected(QString)), &controller, SLOT(sendRequest(const QString&)));
    QObject::connect(&controller, SIGNAL(parseDone(QLinkedList<FriendInfo*>)), &friendsView, SLOT(getFrindsList(const QLinkedList<FriendInfo*>&)));

    return a.exec();
}

login.h
Код:
#ifndef LOGIN_H
#define LOGIN_H

#include <QWebView>

class Login : public QWebView
{
    Q_OBJECT

private:
    QString appId;
    QString display;
    QString scope;
    QString redirectUri;
    QString responseType;

    void initialize();
    void createUrl();

private slots:
    void urlChanged(QUrl);

signals:
    void connected(QString);

public:
    Login(QWidget *parent = 0);
};

#endif // LOGINWDG_H

login.cpp
Код:
#include <QDebug>
#include "Login.h"

Login::Login(QWidget *parent) :  QWebView(parent)
{
    initialize();
    createUrl();

    connect(this, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl)));
}

void Login::initialize() {
    appId = "********";
    display = "popup";
    scope =  "friends";
    redirectUri = "http://api.vkontakte.ru/blank.html";
    responseType = "token";
}

void Login::createUrl() {
    QUrl url("http://api.vkontakte.ru/oauth/authorize");
    url.addQueryItem("client_id", appId);
    url.addQueryItem("display", display);
    url.addQueryItem("scope", scope);
    url.addQueryItem("redirect_uri", redirectUri);
    url.addQueryItem("response_type", responseType);

    load(url);
}

void Login::urlChanged(QUrl url) {
    url = url.toString().replace("#","?");

    if ( url.queryItemValue("error_description") == "User denied your request" ) close();
    if ( !url.hasQueryItem("access_token") ) return;

    QString token = url.queryItemValue("access_token");
    qDebug() << "token sended";
    emit connected(token);
}

controller.h
Код:
#ifndef CONTROLLER_H
#define CONTROLLER_H

#include <QThread>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QLinkedList>

#include "FriendInfo.h"

class Controller : public QThread {
    Q_OBJECT

private:
    QString token;

    QNetworkAccessManager *manager;
    QLinkedList<FriendInfo*> friendsList;

    void parseReply(const QByteArray& reply);

private slots:
    void requestFinished(QNetworkReply* reply);

protected:
    virtual void run();

public:
    Controller(QObject * parent = 0);

public slots:
    void sendRequest(const QString&);

signals:
    void parseDone(QLinkedList<FriendInfo*>);
};

#endif // CONTROLLER_H

controller.cpp
Код:
#include <QtXml>
#include "Controller.h"

Controller::Controller(QObject * parent) : QThread(parent) {

}

void Controller::run() {
    manager = new QNetworkAccessManager(this);
    manager->moveToThread(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));

    QNetworkRequest request;
    QUrl url;

    url.setUrl("https://api.vkontakte.ru/method/friends.get.xml");
    url.addQueryItem("fields", "online, photo");
    url.addQueryItem("access_token", token);

    request.setUrl(url);
    manager->get(request);

    exec();
}

void Controller::sendRequest(const QString& token) {
    this->token = token;
    moveToThread(this);

    qDebug() << "token added";
    this->start();
}

void Controller::requestFinished(QNetworkReply* reply) {
    parseReply(reply->readAll());
}

void Controller::parseReply(const QByteArray &reply) {
    QDomDocument domDoc;
    domDoc.setContent(reply);

    QDomElement repsonse = domDoc.firstChildElement();
    QDomNode user = repsonse.firstChildElement();

    for ( ; !user.isNull(); ) {
        QDomElement field = user.firstChildElement("first_name");
        QString firstName = field.text();

        field = field.nextSiblingElement("last_name");
        QString lastName = field.text();

        field = field.nextSiblingElement("online");
        int online = field.text().toInt();

        field = field.nextSiblingElement("photo");
        QUrl photoUrl = field.text();

        if ( online ) {
            friendsList.prepend(new FriendInfo(firstName, lastName, online, photoUrl));
        } else {
            friendsList.append(new FriendInfo(firstName, lastName, online, photoUrl));
        }

        user = user.nextSibling();
    }

    emit parseDone(friendsList);
}

Буду рад за любые подсказки