2016-06-28 89 views
2

我有一個包含瀏覽器的窗口。向上是一個工具欄。在窗口的底部是一個搜索欄。 搜索欄有一個關閉按鈕[x]。 當用戶點擊關閉按鈕時,我希望欄消失。 我希望欄只出現在用戶按CTRL + F時。我試圖用.hide()命令連接關閉的butoon,但應用程序崩潰。我需要幫助。如何隱藏臨時搜索欄?

enter image description here

的.cpp

DocumentationWin::DocumentationWin (QWidget * parent){ 
    docs = new QTextBrowser(this); 

    //Prepare toolbar 
    toolbar = new QToolBar(this); 
    //add stuff to toolbar 


    //Prepare footer bar 
    searchlabel = new QLabel(tr("Find in page:"),this); 
    resultslabel = new QLabel("",this); 
    searchinput = new QLineEdit(); 

    findprev = new QToolButton(this); 
    findprev->setArrowType(Qt::UpArrow); 
    connect(findprev, SIGNAL(clicked()), this, SLOT (clickFindPrev())); 
    findnext = new QToolButton(this); 
    findnext->setArrowType(Qt::DownArrow); 
    connect(findnext, SIGNAL(clicked()), this, SLOT (clickFindNext())); 

    QStyle *style = qApp->style(); 
    QIcon closeIcon = style->standardIcon(QStyle::SP_TitleBarCloseButton); 
    QPushButton *closeButton = new QPushButton(this); 
    closeButton->setIcon(closeIcon); 
    closeButton->setFlat(true); 
    connect(closeButton, SIGNAL(clicked()), this, SLOT (clickCloseFind())); 
    QWidget *bottom = new QWidget; 
    QHBoxLayout *footer = new QHBoxLayout(); 
    casecheckbox = new QCheckBox(tr("Case sensitive"),this); 

    footer->setContentsMargins(5,5,5,5); 
    footer->addWidget(searchlabel); 
    footer->addSpacing(3); 
    footer->addWidget(searchinput); 
    footer->addWidget(findprev); 
    footer->addWidget(findnext); 
    footer->addSpacing(10); 
    footer->addWidget(casecheckbox); 
    footer->addSpacing(10); 
    footer->addWidget(resultslabel); 
    footer->addStretch(1); 
    footer->addWidget(closeButton); 
    bottom->setLayout(footer); 


    //Prepare main layout 
    layout = new QVBoxLayout; 
    layout->setContentsMargins(0,0,0,0); 
    layout->setSpacing(0); 
    layout->addWidget(toolbar); 
    layout->addWidget(docs); 
    layout->addWidget(bottom); 

    this->setLayout(layout); 
    this->show(); 
} 


void DocumentationWin::clickCloseFind(){ 
    bottom->hide(); 
} 

.H

class DocumentationWin : public QDialog 
{ 
    Q_OBJECT 
    public: 
    DocumentationWin(QWidget * parent); 

    protected: 
    virtual void keyPressEvent(QKeyEvent *); 

    private slots: 
    void clickCloseFind(); 

    private: 
    QVBoxLayout* layout; 
    QToolBar* toolbar; 
    QTextBrowser* docs; 
    QBoxLayout* footer; 
    QLabel *searchlabel; 
    QLabel *resultslabel; 
    QLineEdit *searchinput; 
    QToolButton *findprev; 
    QToolButton *findnext; 
    QCheckBox *casecheckbox; 
    QWidget *bottom; 
    QPushButton *closeButton; 
}; 

回答

4

啊,局部變量隱藏成員的經典案例。關於這個,關於SO的問題已經有很多相同的問題。這是錯誤的:

QWidget *bottom = new QWidget; 

你想:

bottom = new QWidget; 

你會碰到這些問題總是因爲你動態地分配所有的部件 - 這是完全不必要的。

建議:

  1. 按值將孩子抱部件和佈局,沒有動態地分配他們。

  2. 不要將父項傳遞給由佈局管理的小部件。每個佈置的小部件都將自動進行父元素。

  3. 請勿多餘撥打setLayout。 A QLayout需要小部件將其子作爲構造函數參數。

  4. QWidget::hide()是一個插槽。

  5. 許多小部件將文本作爲構造函數參數。

  6. 如果你沒有任何參數傳遞給構造在new表達式,可以刪除括號(但是我們儘量避免這些反正):

    searchinput = new QLineEdit; // not QLineEdit(); 
    
  7. 窗口小部件不應該通常在施工時自行建造show()。沒有Qt部件可以做到這一點。這取決於小部件的用戶做到這一點。

  8. C++使用構造語法重載方法調用語法。爲了區分這兩者,優先於使用()的舊語法的統一初始化(Type{arg0, arg1, ...})。

下面是當您使用C++ 11時代碼的外觀。這可以用Qt 4或Qt 5進行編譯。但是,如果不針對Qt 4,則應該使用新的連接語法。你可以看到,沒有一個明確的動態分配 - 當使用的類型是理智的時候,這就是C++ 11代碼的外觀。

// https://github.com/KubaO/stackoverflown/tree/master/questions/find-hide-38082794 
#include <QtGui> 
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) 
#include <QtWidgets> 
#endif 

class DocumentationWin : public QDialog 
{ 
    Q_OBJECT 
public: 
    explicit DocumentationWin(QWidget * parent = 0); 
private: 
    QVBoxLayout layout{this}; 
    QToolBar toolbar; 
    QTextBrowser docs; 
    QWidget bottom; 
    QHBoxLayout footer{&bottom}; 
    QLabel searchlabel{tr("Find in page:")}; 
    QLabel resultslabel; 
    QLineEdit searchinput; 
    QToolButton findprev; 
    QToolButton findnext; 
    QCheckBox casecheckbox{tr("Case sensitive")}; 
    QPushButton closeButton; 

    Q_SLOT void onFindPrev() {} 
    Q_SLOT void onFindNext() {} 
}; 

DocumentationWin::DocumentationWin(QWidget * parent) : QDialog(parent) { 
    findprev.setArrowType(Qt::UpArrow); 
    connect(&findprev, SIGNAL(clicked()), this, SLOT(onFindPrev())); 
    findnext.setArrowType(Qt::DownArrow); 
    connect(&findnext, SIGNAL(clicked()), this, SLOT(onFindNext())); 

    auto style = qApp->style(); 
    auto closeIcon = style->standardIcon(QStyle::SP_TitleBarCloseButton); 
    closeButton.setIcon(closeIcon); 
    closeButton.setFlat(true); 
    connect(&closeButton, SIGNAL(clicked(bool)), &bottom, SLOT(hide())); 

    footer.setContentsMargins(5,5,5,5); 
    footer.addWidget(&searchlabel); 
    footer.addSpacing(3); 
    footer.addWidget(&searchinput); 
    footer.addWidget(&findprev); 
    footer.addWidget(&findnext); 
    footer.addSpacing(10); 
    footer.addWidget(&casecheckbox); 
    footer.addSpacing(10); 
    footer.addWidget(&resultslabel); 
    footer.addStretch(1); 
    footer.addWidget(&closeButton); 

    layout.setContentsMargins(0,0,0,0); 
    layout.setSpacing(0); 
    layout.addWidget(&toolbar); 
    layout.addWidget(&docs); 
    layout.addWidget(&bottom); 
} 

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    DocumentationWin win; 
    win.show(); 
    return app.exec(); 
} 

#include "main.moc"