Qt - Uygulama Sistem Tepsisinde İken Kapanıyor

Başlatan uçbirim2002, 10 Mart 2017 - 15:31:04

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

uçbirim2002

Her saniye işleyen bir timer'ım var. Belirli kriterler sağlandığı zaman QMessageBox::show ile bir mesaj kutusu gösteriyor. Bu işlemi yaparken ana pencere gizlenmiş vaziyette ve sistem tepsisinde uygulamanın ikonu mevcut. Mesaj kutusunda "Tamam"a tıkladığım zaman uygulama kapanıyor.


Bu sorunu nasıl çözebilirim?
Hello!

Limonata

[mention=619921]@uçbirim2002[/mention], Selamün Aleyküm;
Verdiğiniz bilgiler eksik. Tahmin ediyorum: QTimer::singleShot(600000, &app, SLOT(quit())); benzeri, slot'da quit olan bir kod kullandınız mı?

uçbirim2002

Alıntı yapılan: Limonata - 10 Mart 2017 - 16:05:37
[mention=619921]@uçbirim2002[/mention], Selamün Aleyküm;
Verdiğiniz bilgiler eksik. Tahmin ediyorum: QTimer::singleShot(600000, &app, SLOT(quit())); benzeri, slot'da quit olan bir kod kullandınız mı?

Aleyküm selam

MainWindow'un kurucusunda (yine MainWindow'un üyesi olan) timer nesnesini:

// Create and connect timer...
    this->timer = new QTimer(this);

    QObject::connect(this->timer, SIGNAL(timeout()), SLOT(timer_timeout())); // timer_timeout MainWindow'a ait...
    this->timer->start(1000);


şeklinde ilklendiriyorum. Asıl kontrol işlemlerini yapan fonksiyonu da timer_timeout() metodunda çağırıyorum.
Hello!

Limonata

[mention=619934]@uçbirim2002[/mention]
Ne yazıkki bu kod ile birşey anlayamayız. timer_timeout fonksiyonunun içerisinde ne var? Hatta MessageBox'ta OK'e tıklayınca bir işlem yaptırıyor musunuz?

uçbirim2002

timer_timeout()
void MainWindow::timer_timeout()
{
    update_remaining_time();
}


update_remaining_time()
void MainWindow::update_remaining_time()
{
    QTime now = QTime::currentTime();
    QTime cur_time = *get_now_time();

    int secs_to = now.secsTo(cur_time);
    QTime diffrence = QTime(0, 0, 0).addSecs(secs_to);

    this->time_remaining = diffrence;

    ui->lbl_remainingtime->setText(diffrence.toString("hh:mm:ss"));

    this->check_time(); // Bu da kontrol işlemini yapan fonksiyon. Koşullar gerçekleşince show_message() fonksiyonunu çağırıyor
    color_cur_time_label();
}


show_message()
void MainWindow::show_message(int index) // Prototip: void show_message(int index=-1);
{
    if(index < 0)
        index = rand() % this->messages.length();

    QMessageBox::information(this, trUtf8("Mesaj"), this->messages[index], trUtf8("Tamam"));
}


Bu arada yeni bir şey farkettim. Mesaj kutusu göründüğü zaman, Tamam'a basmadan önce MainWindow gizli ise, uygulama kapanıyor. Görünür ise çalışmaya devam ediyor.
Hello!

uçbirim2002

Hello!

Amenofis

İyi de çok eksik bilgi veriyorsun.

Normal şekilde mi kapanıyor yoksa çöküyor mu? Çıkışta segfault yazıyorsa çöküyordur. Çökmüyorsa main den hangi kodla çıkıyor? 0 (sıfır) değilse yanlış bir kullanım sonucu qt kendisi sonlandırıyordur. Bu durumda hata mesajı da verir zaten. timer_timeout() un içini boş bırakınca da aynı şey mi oluyor? Aynı şey oluyorsa sorun daha dışarıdadır, aksi halde fonksiyondadır.

uçbirim2002

Uygulama çökmüyor zaten tuhaf olanda bu. Ne mesaj basıyor ne hata veriyor. Çıkış kodunuda kontrol ettim 0.

Alıntı yapılan: Amenofis - 14 Mart 2017 - 20:35:14
timer_timeout() un içini boş bırakınca da aynı şey mi oluyor? Aynı şey oluyorsa sorun daha dışarıdadır, aksi halde fonksiyondadır.

Fonksiyonları sırayla inceledim. Herşey QMessageBox::show'dan sonra bitiyor. Bir de şunu denedim: QMessageBox içerisinde 'OK' tuşuna basılmasını bekliyor bu da timer da sorunmu çıkarıyor deyip mesaj kutusunu göstermeden önce timer'ı durdurdum, sonra başlattım, yinede işe yaramadı.
Hello!

guestwho

Çıkışta hata kodu döndürmüyorsa "closeEvent" diye bir fonksiyon oluşturup, bu kapanma olayının görmezden gelinmesi için şu tarz bir "event handler" yazıp denesene:

void Window::closeEvent(QCloseEvent *event)
{
    if (trayIcon->isVisible()) {
        QMessageBox::information(this, tr("Systray"),
                                 tr("The program will keep running in the "
                                    "system tray. To terminate the program, "
                                    "choose <b>Quit</b> in the context menu "
                                    "of the system tray entry."));
        hide();
        event->ignore();
    }
}


"QCloseEvent" nesnesine referans ile "event->ignore();" metodu çağırıldığında bu kapanma olayının etkisiz hale gelmesi gerek. Kod örneğini direkt Qt 'nin dökümantasyonundan aldım.

http://doc.qt.io/qt-4.8/qt-desktop-systray-example.html
You want weapons? We're in a library. Books are the best weapon in the world. This room's the greatest arsenal we could have. Arm yourself!

uçbirim2002

closeEvent mevcut:

void MainWindow::closeEvent(QCloseEvent *event)
{
    if(!this->is_to_tray()) // Sistem tepsisine gitmiyorsa
    {
        event->accept(); // Kapat
    }
    else
    {
        event->ignore();
        this->setVisible(!this->isVisible());

        if(this->isVisible())
            this->activateWindow(); // Pencereye focus yap
        else
            this->hide();
    }
}
Hello!

guestwho

#10
Peki burada "else" bloğunun içerisine giriliyor mu kontrol eder misin ? Bana direkt "if" bloğunun içerisinde "event->accept()" metodu çağırılıyor gibi geldi. Zaten böyleyse kapanma olayını kabul etmiş oluyorsun. "else" bloğunun içerisine giriliyor mu anlamak için "event->ignore();" dan önce ekrana bir şeyler basmayı denesene.
You want weapons? We're in a library. Books are the best weapon in the world. This room's the greatest arsenal we could have. Arm yourself!

uçbirim2002

Mesajı gösterdikten sonra veya önce closeEvent çalışmıyor. Ne 'if' bloğuna, nede 'else' bloğuna giriyor.
Hello!

uçbirim2002

Hello!

guestwho

Peki "MainWindow" nesnesi ile "QMainWindow" nesnesi arasında kalıtım ilişkisi var mı ? Eğer yazdığın kod özel değilse burada paylaşabilir misin ? Hem daha tecrübeli C++ 'cılar da yardımcı olabilir.
You want weapons? We're in a library. Books are the best weapon in the world. This room's the greatest arsenal we could have. Arm yourself!

uçbirim2002

class MainWindow : public QMainWindow

Şeklinde kalıtım ilişkisi var.

Maalesef kod özel.
Hello!

uçbirim2002

Yeni bir şey farkettim. QMessageBox sınıfı yerine QDialog sınıfını miras alan kendi mesaj kutumu oluşturdum. Şu statik fonksiyon ile gösterdim:

void MessageDialog::ShowMessage(QWidget *parent, QString message, QString title)
{
    MessageDialog *dlg = new MessageDialog(parent, message, title);
    dlg->exec();
    delete dlg;
}


QMessageBox::information yerine bu fonksiyonu şu şekilde yerleştirdim:

MessageDialog::ShowMessage(this, this->messages[index], trUtf8("Mesaj"));

Ve sonuç aynı oldu. Yani pencere görünmüyorken (sistem tepsisinde iken) çıkan mesaj kutumu kapattım ve uygulamada kapandı. exec yerine show metodunu denedim ama olmadı.
Hello!

Limonata

[mention=625199]@uçbirim2002[/mention], Selamün Aleyküm;

Qt5 ile basit bir örnek yaptım:
https://app.box.com/s/n41psneo8zhrzbxry73avrpmnrfh1cy7
Kaynak kodlarını tam olarak bilmediğimiz için bu örneğe göre uyarlamalısın.