понедельник, 31 января 2011 г.

Qt. Установка собственного курсора в приложение

        В некоторых программах смена курсора в приложении весьма необходима. Возьмём к примеру тот же Paint или Photoshop - довольно непривычно рисовать изображения с помощью одной стрелки. В Qt есть удобный инструмент работы с курсорами, но тоже как и во всех языках не без ньюансов.

        Первый раз я начал загружать курсор в формате Cur. Довольно простой распространённый формат в интернете. Но после долгих поисков, осуществить это я не смог. Оказалось, что Qt не поддерживает формат Cur, они просто отказались от него.

        С одной стороны непонятно, зачем просто выбрасывать его. Но с другой - зачем он нужен, если существует PNG? PNG поддерживает палитру гораздо побогаче, чем Cur, пусть даже занимая немного больше места.

        Подключение курсора к приложению:

        Подключить курсор очень легко. Курсор объявляется с помощью класса QCursor. Я определял курсор как закрытый член класса, поэтому делал его как указатель:

        QCursor* myCursor;

        Дальше берём PNG картинку, которая будет нашим курсором и связываем её в таком виде:

        myCursor = new QCursor(QPixmap("cursor/myCursor.png"), hotX, hotY);

        Картинка загружается как объект QPixmap. Что такое hotX и hotY? Это точка типа int на курсоре, к которой привязывается место клика мышки. Если hotX равно -1, то по координате Х будет взята середина изображения, если hotY равно -1, то по координате Y будет взята середина изображения. Таким образом при значениях -1,-1 местом клика будет центр курсора.

        Чтобы отобразить наш курсор нужно вызвать функцию setCursor. Например, если мы создали виджет с именем wgt, то установка курсора в нём будет выглядеть так:

        wgt.setCursor(*myCursor);

        Если же не создавать указатель на QCursor, как я делал это, то можно выполнить всё одной функцией:

        wgt.setCursor(QCursor(QPixmap("cursor/myCursor.png", hotX, hotY));

        Как видно оба способа довольно просты и понятны. Преимущество PNG курсоров проявляется оссобенно в том, что их легче найти в сети, или же сделать самому.

суббота, 29 января 2011 г.

Qt. QNetworkAccessManager и http(https)

Qt предоставляет очень мощные средства для работы с сетью.  Одним из основных инструментов является класс QNetworkAccessManager. Он позволяет отправлять запросы на сайты и получать ответы с них. Рассмотрим основные элементы для его реализации:

        Используя протокол http:

QNetworkAccessManager* m_manager;
QNetworkReply* m_reply;
QNetworkRequest m_request;
QUrl m_url;
QByteArray m_options;

QNetworkAccessManager – основное звено.  QNetworkRequest запрос к сайту. Он содержит адресс сайта, а также передаваемые для него параметры. QUrl – адрес сайта, m_options – строка с параметрами запроса. QNetworkReply  -  класс для хранения ответа с сервером.
Далее посылаем запрос на сайт и считываем ответ в m_reply:

m_url = "http://www.yoursite.com/script.php";
m_options = "param1=1&param2=2";
m_request.setUrl(m_url);
m_reply = m_manager->post(m_request, m_options);

connect(m_reply, SIGNAL(finished()), this, SLOT(slotFinished()));
connect(m_reply, SIGNAL(readyRead()), this, SLOT(slotRead()));

В данном случае мы выполняем запрос с помощью метода Post, но также можно посылать запрос с методом Get. Отличие лишь будет в том, что адрес сайта и параметры нужно обьеденить в одну строку:

m_reply = m_manager->post("http://www.yoursite.com/script.php? param1=1&param2=2");


        При обращении к серверу сайта, QNetworkReply сгенерирует 2 сигнала – finished() и readyRead(). Первый говорит о том что все операции завершены, и объект класса QNetworkReply уже не будет изменён(после этого сигнала рекомендуется удалять ответ m_reply: m_reply->deleteLater()), а второй говорит о том, что данные считаны ими можно оперировать. Присоединяем эти сигналы к нашим слотам и производим считывание данных.

QByteArray htmlPage = m_reply->readAll();

Функция readAll()  возвращает результат запроса в виде QByteArray. После этого можно записывать данные в файл, либо оперировать ими в программе.

Используя протокол https:

При использовании протокола https программа не сильно изменяется. В адресе сайта просто вместо http пишется https. Но появляются некоторые трудности.
Первая из них, это игнорирование ssl ошибок при соединении.  Её легко решить так: 

connect(m_reply, SIGNAL(sslErrors(QList<QSslError>)), m_reply, SLOT(ignoreSslErrors()));

А вторая, это отсутствие алгоритмов шифрования в Qt для соединения с сервером. Возникают такие ошибки при соединении:

QSslSocket: cannot call unresolved function SSLv3_client_method
QSslSocket: cannot call unresolved function SSL_CTX_new
QSslSocket: cannot call unresolved function SSL_library_init
QSslSocket: cannot call unresolved function ERR_get_error
QSslSocket: cannot call unresolved function ERR_error_string


Если видите эти строки, вам нужен OpenSsl. Его можно достать на официальном сайте. Я писал на ОС Windows, так что последние версии сборок можно достать здесь .

После подключения OpenSsl к Qt, проблемы больше не возникнут. Программа обратиться к сайту и получит ответ от него.