【问题标题】:How to hide a temporary search bar?如何隐藏临时搜索栏?
【发布时间】:2016-10-31 04:04:17
【问题描述】:

我有一个包含浏览器的窗口。向上是一个工具栏。窗口底部是一个搜索栏。 搜索栏有一个关闭按钮 [x]。 当用户单击关闭按钮时,我希望栏消失。 我希望该栏仅在用户按 CTRL + F 时出现。我尝试使用 .hide() 命令连接关闭按钮,但应用程序崩溃。我需要帮助。

.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;
};

【问题讨论】:

    标签: c++ qt qwidget


    【解决方案1】:

    啊,局部变量隐藏成员的经典案例。关于这个,关于 SO 有很多相同的问题。这是错误的:

    QWidget *bottom = new QWidget;
    

    你想要:

    bottom = new QWidget;
    

    您总是会遇到这些问题,因为您动态分配所有小部件 - 这是完全没有必要的。

    建议:

    1. 按值保存子小部件和布局,不要动态分配它们。

    2. 不要将父级传递给由布局管理的小部件。每个布局的小部件都将自动成为父级。

    3. 不要重复调用setLayoutQLayout 将要放置其子级的小部件作为构造函数参数。

    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"
    

    【讨论】:

      猜你喜欢
      • 2020-04-11
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      • 2019-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多