0

Qt でプログラムを書いています。終了 | のダイアログ ボックスを表示したいと思います。コードのどこかでエラーがスローされるたびに、選択を再開します。

私がしたことはクラッシュを引き起こし、なぜそれが起こるのか本当に理解できません.何が起こっているのかを理解するのを手伝ってくれることを望んでいました.

これが私のmain.cpp:

#include "my_application.hpp"

int main(int argc, char *argv[])
{
    std::cout << std::endl;

    My_Application app(argc, argv);

    return app.exec();
}

そして、ここにありますmy_application:hpp

#ifndef MY_APPLICATION_HPP
#define MY_APPLICATION_HPP

#include <QApplication>

class Window;

class My_Application : public QApplication
{
public:
    My_Application(int& argc, char ** argv);
    virtual ~My_Application();

    virtual bool notify(QObject * receiver, QEvent * event);

private:
    Window *window_;

    void exit();
    void restart();
};

#endif // MY_APPLICATION_HPP

最後に、次のmy_application.cppとおりです。

#include "my_application.hpp"
#include "window.hpp"

#include <QMessageBox>

My_Application::My_Application(int& argc, char ** argv) : QApplication(argc, argv)
{
    window_ = new Window;
    window_->setAttribute(Qt::WA_DeleteOnClose, false);
    window_->show();
}

My_Application::~My_Application()
{
    delete window_;
}

bool My_Application::notify(QObject * receiver, QEvent * event)
{
    try
    {
        return QApplication::notify(receiver, event);
    }
    catch(QString error_message)
    {
        window_->setEnabled(false);

        QMessageBox message_box;
        message_box.setWindowTitle("Error");
        message_box.setIcon(QMessageBox::Critical);
        message_box.setText("The program caught an unexpected error:");
        message_box.setInformativeText("What do you want to do? <br>");

        QPushButton *restart_button = message_box.addButton(tr("Restart"), QMessageBox::RejectRole);
        QPushButton *exit_button = message_box.addButton(tr("Exit"), QMessageBox::RejectRole);

        message_box.setDefaultButton(restart_button);

        message_box.exec();

        if ((QPushButton *) message_box.clickedButton() == exit_button)
        {
            exit();
        }
        else if ((QPushButton *) message_box.clickedButton() == restart_button)
        {
            restart();
        }

    }
    return false;
}


void My_Application::exit()
{
    window_->close();
    //delete window_;

    return;
}

void My_Application::restart()
{
    window_->close();
    //delete window_;

    window_ = new Window;
    window_->show();
    return;
}

この行window_->setAttribute(Qt::WA_DeleteOnClose, false);は、window_(私のメインウィンドウ)が閉じられても削除されないことを意味することに注意してください。

上記のコードは機能しますが、私の知る限り、メモリ リークがあります。 and の行のコメントを解除する必要//delete window_;My_Application::exit()ありMy_Application::restart()ます。しかし、それを行うと、再起動をクリックするとプログラムがクラッシュします(または終了しますが、誰が気にしますか)。

(これが有用かどうかはわかりません。実際には誤解を招く可能性がありますが、デバッガーが教えてくれることは次のとおりです。QWidgetPrivate::PaintOnScreen() const関数によって呼び出される関数によって呼び出されるセグメンテーション違反が発生します...によって呼び出されますMy_Application::notify()

いくつかの s を実行すると、プログラムが関数全体を実行し、実際にはクラッシュする前に関数std::cout全体を実行していることに気付きます。restart()notify()

なぜクラッシュするのかわかりません。あなたの洞察を前もってありがとう!

アップデート:

  1. 私はそれMy_Application::notify()が非常に頻繁に呼び出されていることに気付きました。たとえば、エラー ダイアログ ボックスが開いている間や、再起動関数の実行中に何度も呼び出されます。
  2. クラッシュは実際にはサブ関数で発生しQApplication::notify(receiver, event)ます。これは、以前の発言に照らして驚くべきことではありません (レシーバーはおそらく削除されています)。
  3. My_Application::notify()しかし、関数が実行中に何かをすることを禁止したとしても、restart()クラッシュします ( My_Application::notify()15 回のように何度も呼び出した後、それは奇妙ではありません)?

どのように進めればよいですか?たぶん、(質問をもう少し適切にするために) 私のクラスMy_Applicationには「復元」機能もあると言うべきでしょう。その再起動機能があれば、あまり気にしませんが、その復元機能が欲しいです。また、「delete window_」コメントを付けてコードを保持すると、問題はメモリリークだけでなく、明らかにクラッシュすることもあります。これを解決する方法がきっとあるはずです!しかし、私は無知です、私は本当に助けていただければ幸いです!前もって感謝します。

4

1 に答える 1

0

を使用しwindow_->deleteLater()ます。

イベント キューにウィンドウのイベントがまだあるときに、ウィンドウを削除しています。上記の出力では、ペイント コマンドを削除した後に配信しようとしたようです。 deleteLater()削除コマンドをキューに入れるため、削除の前に「通常の」イベントが配信されます。

また、明確にするために、すべてのイベントが通過しますQApplication::notify(..)。これが、頻繁に呼び出される理由であり、Qt での例外処理の中心点である理由です。

于 2012-10-07T08:26:10.870 に答える