如何隐藏临时搜索栏?

问题描述:

我有一个包含浏览器的窗口。向上是一个工具栏。在窗口的底部是一个搜索栏。 搜索栏有一个关闭按钮[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; 
}; 

啊,局部变量隐藏成员的经典案例。关于这个,关于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/*n/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"