2015-12-15 49 views
1

我有一個小的彈出窗口小部件的集合,出現在不同的地方,但每次只有一個。對於簡單的功能,新的顯示和刪除到隱藏是可以的,並且可以像它應該的那樣工作,但是當他們開始處理他們自己的數據時,我可以看到內存泄漏。爲什麼延遲加載的QWidget會顯示,但存儲的不是?

因此,因爲我只需要每種類型中的一種,所以我認爲我會在父構造函數中創建所有元素,並根據需要顯示並隱藏它們。據我所知,這應該工作,但popup - > show()不顯示。該示例所基於的複雜應用程序顯示彈出窗口確實存在於正確的位置,並且可以與用戶進行交互......但不可見。

這裏的懶惰版本顯示:

#ifndef MAIN_H 
#define MAIN_H 

#include <QtWidgets> 

class Popup : public QLabel 
{ 
    Q_OBJECT 
public: 
    explicit Popup(int x, int y, int width, int height, QWidget* parent = 0); 
}; 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 
public: 
    MainWindow(QWidget* parent = 0); 
    ~MainWindow() {} 
    void mousePressEvent(QMouseEvent* ev); 
private: 
    Popup* popup; 
}; 

#endif // MAIN_H 

/*************** 
*** main.cpp *** 
***************/ 
#include "main.h" 
#include <QApplication> 

int main(int argc, char* argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
    return a.exec(); 
} 



MainWindow::MainWindow(QWidget* parent) 
    : QMainWindow(parent) 
{ 
    popup = 0; 

    QWidget* cWidget = new QWidget(this); 
    cWidget->setStyleSheet("background-color: lightgray"); 
    setCentralWidget(cWidget); 

    showMaximized(); 
} 

void MainWindow::mousePressEvent(QMouseEvent* ev) 
{ 
    if(popup != 0) 
    { 
     if(!popup->geometry().contains(ev->x(), ev->y())) 
     { 
      delete popup; 
      popup = 0; 
     } 
    } 
    else 
    { 
     popup = new Popup(ev->x(), ev->y(), 100, 100, this); 
     popup->show(); 
    } 
    ev->accept(); 
} 



Popup::Popup(int x, int y, int width, int height, QWidget* parent) : 
    QLabel(parent) 
{ 
    setStyleSheet("background-color: black"); 
    setGeometry(
       x - (width/2), // Left 
       y - (height/2), // Top 
       width ,    // Width 
       height    // Height 
       ); 
} 

而這裏的預創建的版本,這並不表明:

#ifndef MAIN_H 
#define MAIN_H 

#include <QtWidgets> 

class Popup : public QLabel 
{ 
    Q_OBJECT 
public: 
    explicit Popup(QWidget* parent = 0); 
    void setup(int x, int y, int width, int height); 
}; 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 
public: 
    MainWindow(QWidget* parent = 0); 
    ~MainWindow() {} 
    void mousePressEvent(QMouseEvent* ev); 
private: 
    Popup* popup; 
}; 

#endif // MAIN_H 

/*************** 
*** main.cpp *** 
***************/ 
#include "main.h" 
#include <QApplication> 

int main(int argc, char* argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
    return a.exec(); 
} 



MainWindow::MainWindow(QWidget* parent) 
    : QMainWindow(parent) 
{ 
    popup = new Popup(this); 

    QWidget* cWidget = new QWidget(this); 
    cWidget->setStyleSheet("background-color: lightgray"); 
    setCentralWidget(cWidget); 

    showMaximized(); 
} 

void MainWindow::mousePressEvent(QMouseEvent* ev) 
{ 
    if(popup->isVisible()) 
    { 
     if(!popup->geometry().contains(ev->x(), ev->y())) 
     { 
      popup->hide(); 
     } 
    } 
    else 
    { 
     popup->setup(ev->x(), ev->y(), 100, 100); 
     popup->show(); 
    } 
    ev->accept(); 
} 



Popup::Popup(QWidget* parent) : 
    QLabel(parent) 
{ 
    setStyleSheet("background-color: black"); 
} 

void Popup::setup(int x, int y, int width, int height) 
{ 
    setGeometry(
       x - (width/2), // Left 
       y - (height/2), // Top 
       width ,    // Width 
       height    // Height 
       ); 
} 

我缺少什麼?

回答

0

馬丁提到的Z-順序,我還沒有與之建立聯繫,促使更多的谷歌搜索,很快就發現他QWidget :: raise()方法。現在它按我想要的方式工作。

實例化的順序確實有效,但如果您動態創建更多的小部件,則不會。彈出窗口仍然會出現在動態小部件下。我確信有一種方法可以使它工作(這個我的第一個使用Qt的項目,所以儘管我盡了最大的努力,但我完全期望在幾年後稱其爲「醜陋」),但窗口標誌打破了彈出窗口和應用程序寫入方式之間的耦合。如果我已經開始使用窗口標誌,我可能會讓它工作得很好,甚至更好,但我沒有。

這裏是我現在正在做的,是作品:

#ifndef MAIN_H 
#define MAIN_H 

#include <QtWidgets> 

class Popup : public QLabel 
{ 
    Q_OBJECT 
public: 
    explicit Popup(QWidget* parent = 0); 
    void setup(int x, int y, int width, int height); 
}; 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 
public: 
    MainWindow(QWidget* parent = 0); 
    ~MainWindow() {} 
    void mousePressEvent(QMouseEvent* ev); 
private: 
    Popup* popup; 
}; 

#endif // MAIN_H 

/*************** 
*** main.cpp *** 
***************/ 
#include "main.h" 
#include <QApplication> 

int main(int argc, char* argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 
    return a.exec(); 
} 



MainWindow::MainWindow(QWidget* parent) 
    : QMainWindow(parent) 
{ 
    popup = new Popup(this); 

    QWidget* cWidget = new QWidget(this); 
    cWidget->setStyleSheet("background-color: lightgray"); 
    setCentralWidget(cWidget); 

    showMaximized(); 
} 

void MainWindow::mousePressEvent(QMouseEvent* ev) 
{ 
    if(popup->isVisible()) 
    { 
     if(!popup->geometry().contains(ev->x(), ev->y())) 
     { 
      popup->hide(); 
     } 
    } 
    else 
    { 
     popup->setup(ev->x(), ev->y(), 100, 100); 
     popup->raise();  /*** THIS IS WHAT I WAS MISSING!!! ***/ 
     popup->show(); 
    } 
    ev->accept(); 
} 



Popup::Popup(QWidget* parent) : 
    QLabel(parent) 
{ 
    setStyleSheet("background-color: black"); 
} 

void Popup::setup(int x, int y, int width, int height) 
{ 
    setGeometry(
       x - (width/2), // Left 
       y - (height/2), // Top 
       width ,    // Width 
       height    // Height 
       ); 
} 
1

您從未爲您的popup小部件設置窗口標誌(例如Qt :: Popup)。
它實際上是MainWindow w的子部件,應該顯示在某處。

在Qt中,沒有佈局的QWidgets簡單疊加在一起。外觀的z順序依賴於實例的順序。這就是爲什麼懶惰的QLabel可見,而另一個不可見。

務實它很可能是不夠cWidget後實例彈出:

MainWindow::MainWindow(QWidget* parent) 
    : QMainWindow(parent) 
{ 
    // popup = new Popup(this); // not here 

    QWidget* cWidget = new QWidget(this); 
    cWidget->setStyleSheet("background-color: lightgray"); 
    setCentralWidget(cWidget); 

    popup = new Popup(this); // but here (untested, but should work) 

    showMaximized(); 
} 

爲此在Qt的方式,你應該避免堆積的小部件,而是讓你popup一個真正的彈出式的外觀:

popup->setWindowFlags(Qt::Popup); // this lets popup have its own window 
+0

@馬丁感謝您的幫助。正如我的回答中所提到的,我最終使用了不同的解決方案,但是你讓我開始朝這個方向發展。 +1。 – AaronD

相關問題