Qt4 Menubar and Toolbar

在这篇文章中,基本实现了Menubar和Toolbar的功能,但还很不成熟,需要以后修正,仅为以后参考。

另外,所创建的工程简单照搬了Qt Demos中browser的搜索框,以添加一个简单功能。

1、在browser工程中提取相关的搜索框信息,并作细微修改

searchlineedit.h

#ifndef SEARCHLINEEDIT_H
#define SEARCHLINEEDIT_H

#include <QtGui/QWidget>
#include <QtGui/QStyleOptionFrame>
#include <QLabel>
#include <QLineEdit>
#include <QLinearGradient>

QT_BEGIN_NAMESPACE
class QLineEdit;
QT_END_NAMESPACE

class ExLineEdit : public QWidget
{
    Q_OBJECT

public:
    ExLineEdit(QWidget *parent = 0);

    inline QLineEdit *lineEdit() const { return m_lineEdit; }

    void setLeftWidget(QWidget *widget);
    QWidget *leftWidget() const;

    QSize sizeHint() const;

    QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
protected:
    void focusInEvent(QFocusEvent *event);
    void focusOutEvent(QFocusEvent *event);
    void keyPressEvent(QKeyEvent *event);
    void paintEvent(QPaintEvent *event);
    void resizeEvent(QResizeEvent *event);
    void inputMethodEvent(QInputMethodEvent *e);
    bool event(QEvent *event);

protected:
    void updateGeometries();
    void initStyleOption(QStyleOptionFrameV2 *option) const;

    QWidget *m_leftWidget;
    QLineEdit *m_lineEdit;
};

class SearchLineEdit : public ExLineEdit
{
    Q_OBJECT

signals:
    void search(const QString text);

public:
    SearchLineEdit(QWidget *parent = 0);

protected:
    void paintEvent(QPaintEvent *event);

private slots:
    void textChanged();

private:
    QLinearGradient generateGradient(const QColor &color) const;
    QLabel *m_iconLabel;
    QColor m_defaultBaseColor;
};

#endif // SEARCHLINEEDIT_H

searchlineedit.cpp

#include "searchlineedit.h"
#include <QtCore/QEvent>
#include <QApplication>
#include <QCompleter>
#include <QFocusEvent>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPainter>
#include <QStyle>
#include <QStyleOptionFrameV2>
#include <QDebug>

ExLineEdit::ExLineEdit(QWidget *parent)
    : QWidget(parent)
    , m_leftWidget(0)
    , m_lineEdit(new QLineEdit(this))
{
    setFocusPolicy(m_lineEdit->focusPolicy());
    setAttribute(Qt::WA_InputMethodEnabled);
    setSizePolicy(m_lineEdit->sizePolicy());
    setBackgroundRole(m_lineEdit->backgroundRole());
    setMouseTracking(true);
    setAcceptDrops(true);
    setAttribute(Qt::WA_MacShowFocusRect, true);
    QPalette p = m_lineEdit->palette();
    setPalette(p);

    // line edit
    m_lineEdit->setFrame(false);
    m_lineEdit->setFocusProxy(this);
    m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
    QPalette clearPalette = m_lineEdit->palette();
    clearPalette.setBrush(QPalette::Base, QBrush(Qt::transparent));
    m_lineEdit->setPalette(clearPalette);
}

void ExLineEdit::setLeftWidget(QWidget *widget)
{
    m_leftWidget = widget;
}

QWidget *ExLineEdit::leftWidget() const
{
    return m_leftWidget;
}

void ExLineEdit::resizeEvent(QResizeEvent *event)
{
    Q_ASSERT(m_leftWidget);
    updateGeometries();
    QWidget::resizeEvent(event);
}

void ExLineEdit::updateGeometries()
{
    QStyleOptionFrameV2 panel;
    initStyleOption(&panel);
    QRect rect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);

    int height = rect.height();
    int width = rect.width();

    int m_leftWidgetHeight = m_leftWidget->height();
    m_leftWidget->setGeometry(rect.x() + 2,          rect.y() + (height - m_leftWidgetHeight)/2,
                              m_leftWidget->width(), m_leftWidget->height());

    int clearButtonWidth = this->height();
    m_lineEdit->setGeometry(m_leftWidget->x() + m_leftWidget->width(),        0,
                            width - clearButtonWidth - m_leftWidget->width(), this->height());
}

void ExLineEdit::initStyleOption(QStyleOptionFrameV2 *option) const
{
    option->initFrom(this);
    option->rect = contentsRect();
    option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this);
    option->midLineWidth = 0;
    option->state |= QStyle::State_Sunken;
    if (m_lineEdit->isReadOnly())
        option->state |= QStyle::State_ReadOnly;
#ifdef QT_KEYPAD_NAVIGATION
    if (hasEditFocus())
        option->state |= QStyle::State_HasEditFocus;
#endif
    option->features = QStyleOptionFrameV2::None;
}

QSize ExLineEdit::sizeHint() const
{
    m_lineEdit->setFrame(true);
    QSize size = m_lineEdit->sizeHint();
    m_lineEdit->setFrame(false);
    return size;
}

void ExLineEdit::focusInEvent(QFocusEvent *event)
{
    m_lineEdit->event(event);
    QWidget::focusInEvent(event);
}

void ExLineEdit::focusOutEvent(QFocusEvent *event)
{
    m_lineEdit->event(event);

    if (m_lineEdit->completer()) {
        connect(m_lineEdit->completer(), SIGNAL(activated(QString)),
                         m_lineEdit, SLOT(setText(QString)));
        connect(m_lineEdit->completer(), SIGNAL(highlighted(QString)),
                         m_lineEdit, SLOT(_q_completionHighlighted(QString)));
    }
    QWidget::focusOutEvent(event);
}

void ExLineEdit::keyPressEvent(QKeyEvent *event)
{
    m_lineEdit->event(event);
}

bool ExLineEdit::event(QEvent *event)
{
    if (event->type() == QEvent::ShortcutOverride)
        return m_lineEdit->event(event);
    return QWidget::event(event);
}

void ExLineEdit::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    QStyleOptionFrameV2 panel;
    initStyleOption(&panel);
    style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
}

QVariant ExLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
{
    return m_lineEdit->inputMethodQuery(property);
}

void ExLineEdit::inputMethodEvent(QInputMethodEvent *e)
{
    m_lineEdit->event(e);
}

SearchLineEdit::SearchLineEdit(QWidget *parent)
    : ExLineEdit(parent)
    , m_iconLabel(new QLabel(this))
{
    // icon
    m_iconLabel->resize(16, 16);
    m_iconLabel->setPixmap(QPixmap(":/search16"));
    setLeftWidget(m_iconLabel);
    m_defaultBaseColor = palette().color(QPalette::Base);

    connect(m_lineEdit, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
}

QLinearGradient SearchLineEdit::generateGradient(const QColor &color) const
{
    QLinearGradient gradient(0, 0, 0, height());
    gradient.setColorAt(0, m_defaultBaseColor);
    gradient.setColorAt(0.15, color.lighter(120));
    gradient.setColorAt(0.5, color);
    gradient.setColorAt(0.85, color.lighter(120));
    gradient.setColorAt(1, m_defaultBaseColor);
    return gradient;
}

void SearchLineEdit::paintEvent(QPaintEvent *event)
{
    QPalette p = palette();
    if (!m_lineEdit->text().isEmpty())
    {
        QColor lightYellow(248, 248, 210);
        p.setBrush(QPalette::Base, generateGradient(lightYellow));
    }
    else
    {
        p.setBrush(QPalette::Base, m_defaultBaseColor);
    }
    setPalette(p);
    ExLineEdit::paintEvent(event);
}

void SearchLineEdit::textChanged()
{
    QString text = m_lineEdit->text();
    emit search(text);
}

2、创建主窗口,并在其中实现menubar、toolbar和searchlineedit

mymainmenuwindow.h

#ifndef MYMAINMENUWINDOW_H
#define MYMAINMENUWINDOW_H

#include <QWidget>
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QToolBar>
#include <QToolButton>
#include <QPixmap>
#include <QTextEdit>
#include "searchlineedit.h"

class MyMainMenuWindow : public QWidget
{
    Q_OBJECT
public:
    explicit MyMainMenuWindow(QWidget *parent = 0);

private:
    QMenuBar *menubar;

    QMenu *fileMenu;
    QAction *actionNew;
    QAction *actionOpen;
    QAction *actionSave;
    QAction *actionQuit;

    QMenu *editMenu;
    QAction *actionUndo;
    QAction *actionRedo;
    QAction *actionCut;
    QAction *actionCopy;
    QAction *actionPaste;
    QAction *actionSelectAll;

    QMenu *optionMenu;
    QAction *actionPreference;

    QMenu *helpMenu;
    QAction *actionContents;
    QAction *actionAbout;


    QToolBar *toolBar;
    QToolButton *toolBtnOpen, *toolBtnSave, *toolBtnPrint;
    QPixmap openIcon, saveIcon, printIcon;
    QTextEdit *textEdit;

    SearchLineEdit *searchLineEdit;
    
signals:
    
public slots:
    void fileOpen();
    void fileSave();
    void filePrint();
    void search();
};

#endif // MYMAINMENUWINDOW_H

mymainmenuwindow.cpp

#include "mymainmenuwindow.h"
#include <QApplication>
#include <QFileDialog>
#include <QMessageBox>
#include <QPrintDialog>
#include <QColor>

MyMainMenuWindow::MyMainMenuWindow(QWidget *parent) :
    QWidget(parent)
{
    setGeometry(100,100,400,150);

    // menubar
    menubar = new QMenuBar(this);
    menubar->setGeometry(0,0,200,20);

    // file menu
    fileMenu = menubar->addMenu("File");
    actionNew = fileMenu->addAction("New");
    actionOpen = fileMenu->addAction("Open");
    actionSave = fileMenu->addAction("Save");
    actionQuit = fileMenu->addAction("Quit", qApp, SLOT(quit()));

    // edit menu
    editMenu = menubar->addMenu("Edit");
    actionUndo = editMenu->addAction("Undo");
    actionRedo = editMenu->addAction("Redo");
    editMenu->addSeparator();
    actionCut = editMenu->addAction("Cut");
    actionCopy = editMenu->addAction("Copy");
    actionPaste = editMenu->addAction("Paste");
    editMenu->addSeparator();
    actionSelectAll = editMenu->addAction("Select All");

    // option menu
    optionMenu = menubar->addMenu("Option");
    actionPreference = optionMenu->addAction("Preference");

    // help menu
    helpMenu = menubar->addMenu("Help");
    actionContents = helpMenu->addAction("Contents");
    helpMenu->addSeparator();
    actionAbout = helpMenu->addAction("About");

    // load icons for toolbbuttons
    openIcon = QPixmap(":/fileopen");   //打开文件图标
    saveIcon = QPixmap(":/filesave");   //保存文件图标
    printIcon = QPixmap(":/fileprint"); //打印文件图标

    // toolbar
    toolBar = new QToolBar(this);
    toolBar->setMovable(true);
    toolBar->setGeometry(0,20,400,30);

    // toolbutton open
    toolBtnOpen = new QToolButton(toolBar);
    toolBtnOpen->setIcon(openIcon);
    toolBtnOpen->setToolTip("Open File");
    toolBtnOpen->setGeometry(0,0,30,30);

    // toolbutton save
    toolBtnSave = new QToolButton(toolBar);
    toolBtnSave->setIcon(saveIcon);
    toolBtnSave->setToolTip("Save File");
    toolBtnSave->setGeometry(30,0,30,30);

    // toolbutton print
    toolBtnPrint = new QToolButton(toolBar);
    toolBtnPrint->setIcon(printIcon);
    toolBtnPrint->setToolTip("Print File");
    toolBtnPrint->setGeometry(60,0,30,30);

    // search line dit
    searchLineEdit = new SearchLineEdit(this);
    searchLineEdit->setGeometry(10,60,380,20);

    // textedit
    textEdit = new QTextEdit(this);
    textEdit->setGeometry(10,90,380,50);
    textEdit->setTextColor(QColor(Qt::blue));
    textEdit->setText("This is a menu and toolbar demo.");
    textEdit->setTextColor(QColor(Qt::red));
    textEdit->append("This is a menu and toolbar demo.");

    // 信号与槽
    connect(toolBtnOpen, SIGNAL(clicked()), this, SLOT(fileOpen()));
    connect(toolBtnSave, SIGNAL(clicked()), this, SLOT(fileSave()));
    connect(toolBtnPrint, SIGNAL(clicked()), this, SLOT(filePrint()));
    connect(searchLineEdit, SIGNAL(search(QString)), this, SLOT(search()));
}

void MyMainMenuWindow::fileOpen()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("文件选择"));
    if (!fileName.isEmpty())
    {
        QMessageBox::about(this, "文件路径", fileName);
    }
}

void MyMainMenuWindow::fileSave()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("文件保存"));
    if (!fileName.isEmpty())
    {
        QMessageBox::about(this, "文件路径", fileName);
    }
}

void MyMainMenuWindow::filePrint()
{
    QPrintDialog printDialog(this);
    if (printDialog.exec() == QDialog::Accepted)
    {
        // print ...
    }
}

void MyMainMenuWindow::search()
{
    QString searchText = searchLineEdit->lineEdit()->text();
    QMessageBox::about(this, "Search Text", searchText);
}


3、在主函数main中显示上面创建的窗口

#include <QApplication>
#include <QTextCodec>
#include "mymainmenuwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("System"));  //消除乱码

    MyMainMenuWindow menuWindow;
    menuWindow.show();

    return a.exec();
}

运行程序效果如下:

Qt4 Menubar and Toolbar_第1张图片


你可能感兴趣的:(toolbar,QT4,MenuBar,SearchLineEdit)