Modern masaüstü uygulamalarının hemen hemen tamamı bulut servisleri, uzaktan veri tabanları veya IoT cihazlarıyla iletişim kurmak için web API’lerinden faydalanır. Qt ekosisteminde HTTP/HTTPS protokolleri üzerinden ağ istekleri gerçekleştirmek için kullanılan temel sınıf Qt REST API QNetworkAccessManager bileşenidir.
QNetworkAccessManager, arka planda tamamen asenkron (bloke etmeyen) bir mimariyle çalışır. Yani bir web isteği gönderdiğinizde, yanıt gelene kadar uygulamanızın arayüzü asla kilitlenmez.
Bu rehberde, projenize Network modülünü dahil etmeyi, GET ve POST istekleri göndermeyi, HTTP başlıkları (headers) eklemeyi ve gelen JSON verilerini Qt’nin dahili sınıflarıyla ayrıştırmayı eksiksiz kod bloklarıyla öğreniyoruz.
Proje Yapılandırması (CMake ve QMake)
Ağ sınıflarını kullanabilmek için projenize Network modülünü eklemeniz gerekir:
Modern CMake (CMakeLists.txt):
find_package(Qt6 COMPONENTS Core Gui Widgets Network REQUIRED)
target_link_libraries(BenimUygulamam PRIVATE Qt6::Widgets Qt6::Network)
Klasik QMake (.pro):
QT += core gui widgets network
Qt Network Mimarisi: 3 Temel Sınıf
Qt’de ağ iletişimi üç temel sınıfın işbirliğiyle gerçekleşir:
QNetworkAccessManager: İstekleri koordine eden, soketleri yöneten ve kuyruğa alan merkezi yöneticidir. Uygulama genelinde genellikle tek bir örneği (singleton veya ana pencere üyesi) tutulur.QNetworkRequest: Gönderilecek isteğin URL adresini, HTTP başlıklarını (User-Agent, Authorization vb.) ve SSL yapılandırmasını tutar.QNetworkReply: İstek gönderildikten sonra dönen yanıtı, HTTP durum kodunu (200 OK, 404 vb.) ve veri akışını temsil edenQIODevicetürevidir.
1. HTTP GET İsteği Atmak ve JSON Ayrıştırmak
Sunucudan veri çekmek için manager->get() fonksiyonu kullanılır. Yanıt hazır olduğunda tetiklenen finished sinyali dinlenir:
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
class ApiIstemcisi : public QObject {
Q_OBJECT
public:
explicit ApiIstemcisi(QObject *parent = nullptr) : QObject(parent) {
m_manager = new QNetworkAccessManager(this);
}
void havaDurumuGetir(const QString &sehir) {
QUrl url(QString("https://api.example.com/v1/weather?city=%1").arg(sehir));
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::UserAgentHeader, "QtWeatherClient/1.0");
QNetworkReply *reply = m_manager->get(request);
// Yanit tamamlandiginda calisacak lambda
connect(reply, &QNetworkReply::finished, this, [reply]() {
// 1. Ag hatasi kontrolu
if (reply->error() != QNetworkReply::NoError) {
qDebug() << "Ag Hatasi:" << reply->errorString();
reply->deleteLater();
return;
}
// 2. HTTP Durum Kodu kontrolu (orn: 200)
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug() << "HTTP Durum Kodu:" << statusCode;
// 3. Ham veriyi okuma ve JSON parse etme
QByteArray yanitVerisi = reply->readAll();
QJsonDocument jsonDoc = QJsonDocument::fromJson(yanitVerisi);
if (!jsonDoc.isNull() && jsonDoc.isObject()) {
QJsonObject kokNesne = jsonDoc.object();
double sicaklik = kokNesne["temperature"].toDouble();
QString durum = kokNesne["description"].toString();
qDebug() << "Sicaklik:" << sicaklik << "°C | Durum:" << durum;
}
// 4. Bellek Temizligi (Cok Onemli!)
reply->deleteLater();
});
}
private:
QNetworkAccessManager *m_manager;
};
2. HTTP POST İsteği ile JSON Göndermek
Sunucuya yeni bir kayıt eklemek veya kullanıcı doğrulaması yapmak için manager->post() kullanılır:
void yeniKullaniciGonder(const QString &kullaniciAdi, const QString &eposta) {
QUrl url("https://api.example.com/v1/users");
QNetworkRequest request(url);
// Header ayarlari
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setRawHeader("Authorization", "Bearer gizli_jwt_token_bilgisi");
// JSON Veri paketini hazirlama
QJsonObject jsonGovde;
jsonGovde["username"] = kullaniciAdi;
jsonGovde["email"] = eposta;
QJsonDocument jsonDoc(jsonGovde);
QByteArray gonderilecekVeri = jsonDoc.toJson();
QNetworkReply *reply = m_manager->post(request, gonderilecekVeri);
connect(reply, &QNetworkReply::finished, this, [reply]() {
if (reply->error() == QNetworkReply::NoError) {
qDebug() << "Kullanici basariyla kaydedildi!" << reply->readAll();
} else {
qDebug() << "Kayit basarisiz! Hata Kodu:" << reply->errorString();
}
reply->deleteLater();
});
}
HTTP Metotları ve QNetworkAccessManager Karşılıkları
REST API mimarisinde kullanılan standart HTTP metotları şu şekildedir:
| HTTP Metodu | Qt Karşılığı | Kullanım Amacı |
|---|---|---|
| GET | manager->get(request) | Sunucudan veri okumak |
| POST | manager->post(request, data) | Sunucuya yeni kayıt eklemek |
| PUT | manager->put(request, data) | Mevcut bir kaydı güncellemek |
| DELETE | manager->deleteResource(request) | Kaydı sunucudan silmek |
| Özel Metotlar | manager->sendCustomRequest(request, "PATCH", data) | PATCH vb. özel fiiller |
Ağ Programlamada 3 Altın Kural
reply->deleteLater()Kullanmayı Unutmayın: GelenQNetworkReplynesnesifinishedsinyali sonrasında otomatik silinmez. Bellek sızıntısını önlemek için slot içinde daimareply->deleteLater()çağrılmalıdır.- Tek Bir Manager Örneği Kullanın: Her istek için
new QNetworkAccessManageroluşturmayın. Tek bir yönetici, TCP bağlantılarını önbelleğe alıp (keep-alive) yeniden kullanarak uygulamanızı çok daha hızlı hale getirir. - Zaman Aşımı (Timeout) Tanımlayın: Qt 5.15 ve Qt 6 ile birlikte gelen
request.setTransferTimeout(5000)özelliğiyle yanıt vermeyen sunucular için milisaniye cinsinden otomatik zaman aşımı belirleyebilirsiniz.
Uygulamanızın gelen verileri güvenle işleyip arayüze aktarması için sitemizdeki Signals ve Slots Mekanizması rehberimizden yararlanabilirsiniz.
Daha ayrıntılı SSL/TLS sertifika yönetimi, çerezler (cookies) ve proxy ayarları için resmi Qt QNetworkAccessManager Sınıf Dokümantasyonu sayfasını inceleyebilirsiniz.