zoukankan      html  css  js  c++  java
  • Qt学习之对话框与主窗口的创建

    Qt中的信号与槽机制

    qt中槽和普通的C++成员函数几乎是一样的--可以是虚函数,可以被重载,可以是共有的,保护的或者私有的。
    槽可以和信号连接在一起,在这种情况下,每当发射这个信号的信号,就会自动调用这个槽
    connect语句:connect(sende, SIGNAL(signal), receiver, SLOT(slot)
    这里的sender和receiver是指向QObject的指针,signal和slot是不带参数的函数名,实际上SIGNAL和SLOT宏会把他们的参数转换成相应的字符串
    注意:
    一个信号可以连接多个槽
    connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));
    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(updateStatusBarIndicator(int)));
    多个信号可以链接同一个槽
    connect(lcd, SIGNAL(overflow)), this, SLOT(handleMathError()));
    connect(calculator, SIGNAL(divisionByZero)), this, SLOT(handleMathError()));
    一个信号可以与另外一个信号相连接
    connect(lineEdit, SIGNAL(textChanged(const QString&)), this, SIGNAL(updateRecord(const QString&)));

    Qt的元对象系统机制

    元对象系统机制工作原理:
    1. Q_OBJECT宏声明了在每一个QObject子类必须实现一些内省函数:metaObject(), tr(), qt_metacall(),以及其他一些函数
    2. Qt的moc工具生成了用于由Q_OBJECT声明的所有函数和信号的实现
    3. 向connect()和disconnect()这样的QObject的成员函数使用这些内省函数来完成他们的工作

    用C++代码实现简单对话框

    头文件:findDialog.h
    #ifndef FINDDIALOG_H
    #define FINDDIALOG_H
    
    #include <QLabel>
    #include <QDialog>
    
    class QCheckBox;
    //class QLabel;
    class QLineEdit;
    class QPushButton;
    
    class FindDialog : public QDialog
    {
        Q_OBJECT
    public:
        //construct function
        FindDialog(QWidget *parent = 0);
    
    signals:
        void findNext(const QString &str, Qt::CaseSensitivity cs);
        void findPrevious(const QString &str, Qt::CaseSensitivity cs);
    private slots:
        void findCliked();
        void enabledFindButton(const QString &text);
    
    private:
        QLabel *label;
        QCheckBox *caseCheckBox;
        QCheckBox *backwardCheckBox;
        QPushButton *findButton;
        QPushButton *closeButton;
        QLineEdit *lineEdit;
    };
    
    实现文件findDialog.cpp
    #include <QtGui>
    #include <QHBoxLayout>
    #include <QVBoxLayout>
    #include <QCheckBox>
    #include <QLineEdit>
    #include <QPushButton>
    #include <QMessageBox>
    
    #include "finddialog.h"
    
    FindDialog::FindDialog(QWidget *parent)
        :QDialog(parent)
    {
        label = new QLabel(tr("Find &what:"));
        lineEdit = new QLineEdit;
        label->setBuddy(lineEdit);
    
        caseCheckBox = new QCheckBox(tr("Match &case"));
        backwardCheckBox = new QCheckBox(tr("Search &backword"));
    
        findButton = new QPushButton(tr("&Find"));
        findButton->setDefault(true);
        findButton->setEnabled(false);
    
        closeButton = new QPushButton(tr("&Clase"));
    
    
        //链接信号与槽
        connect(lineEdit, SIGNAL(textChanged(const QString)),
                this, SLOT(enabledFindButton(const QString&)));
    
        connect(findButton, SIGNAL(clicked()),
                this, SLOT(findCliked()));
        connect(closeButton, SIGNAL(clicked()),
                this, SLOT(close()));
    
        //set layout,水平布局管理器
        QHBoxLayout *topLeftLayout = new QHBoxLayout;
        topLeftLayout->addWidget(label);
        topLeftLayout->addWidget(lineEdit);
        //垂直布局管理器
        QVBoxLayout *leftLayout = new QVBoxLayout;
        leftLayout->addLayout(topLeftLayout);
        leftLayout->addWidget(caseCheckBox);
        leftLayout->addWidget(backwardCheckBox);
    
        QVBoxLayout *rightLayout = new QVBoxLayout;
        rightLayout->addWidget(findButton);
        rightLayout->addWidget(closeButton);
        //Adds a stretchable space (a QSpacerItem) with zero minimum size
        //and stretch factor stretch to the end of this box layout.
        rightLayout->addStretch();
    
        QHBoxLayout *mainLayout = new QHBoxLayout;
        mainLayout->addLayout(leftLayout);
        mainLayout->addLayout(rightLayout);
        //set the dialog's main layout
        setLayout(mainLayout);   //设置主对话框的布局
    
        setWindowTitle("Find");    //设置对话框的标题
        setFixedHeight(sizeHint().height());
    }
    //实现槽
    void FindDialog::findCliked()
    {
        QMessageBox msgBox;
        msgBox.setText(tr("find successfully!"));
        msgBox.exec();
        QString text = lineEdit->text();
        Qt::CaseSensitivity cs  =
                caseCheckBox->isChecked() ? Qt::CaseSensitive
                                         : Qt::CaseInsensitive;
    
        if(backwardCheckBox->isChecked()) {
            emit findPrevious(text, cs);
    
        }else {
            emit findNext(text, cs);
        }
    }
    
    void FindDialog::enabledFindButton(const QString &text)
    {
        findButton->setEnabled(!text.isEmpty());
    }
    

    创建主窗口

    主窗口是构建应用程序用户界面的框架,其中包括菜单,工具栏以及应用程序所需的对话框。那么该如何实现这些功能呢?

    子类化QMainWindow(继承MainWindow)

    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow();
    
    protected:
        void closeEvent(QCloseEvent *event);
    
    private slots:
        void newFile();
        void open();
        bool save();
        bool saveAs();
        void find();
        void goToCell();
        void sort();
        void about();
        void openRecentFile();
        void updateStatusBar();
        void spreadsheetModified();
    
    ......
    };
    实现代码
    MainWindow::MainWindow()
    {
        spreadsheet = new Spreadsheet;
        setCentralWidget(spreadsheet);
    
        createActions();   //创建各个动作
        createMenus();   //创建菜单
        createContextMenu();  //创建内容菜单
        createToolBars();  //创建工具栏
        createStatusBar();  //创建状态栏
    
        readSettings();   //读取配置
    
        findDialog = 0;
    
        setWindowIcon(QIcon(":/images/icon.png"));
        setCurrentFile("");
    }
    
    void MainWindow::closeEvent(QCloseEvent *event)
    {
        if (okToContinue()) {
            writeSettings();
            event->accept();
        } else {
            event->ignore();
        }
    }
    
    ......

    图形用户界面(GUI)应用程序通常会使用图片,在Qt使用图片的方法
    1. 把图片保存到文件中,并且在运行时载入他们
    2. 把XPM文件包含在源代码中
    3. 使用Qt的资源机制 (RESOURCE = app_name.qrc)
    app_name.qrc:
    <RCC>
    <qresource>
        <file>images/icon.png</file>
        <file>images/new.png</file>
        <file>images/open.png</file>
        <file>images/save.png</file>
        <file>images/cut.png</file>
        <file>images/copy.png</file>
        <file>images/paste.png</file>
        <file>images/find.png</file>
        <file>images/gotocell.png</file>
    </qresource>
    </RCC>
    

    创建菜单和工具栏

    Qt通过"动作"的概念简化了有关菜单和工具栏的编程。一个Action可以添加到任意数量的菜单和工具栏上的像。实现步骤:
    1. 创建并且设置动作
    2. 创建菜单栏并且把动作添加的菜单上
    3. 创建工具栏并且把动作添加到工具栏
    void MainWindow::createActions()
    {
        newAction = new QAction(tr("&New"), this);  //实现创建新文件的动作
        newAction->setIcon(QIcon(":/images/new.png"));
        newAction->setShortcut(QKeySequence::New);
        newAction->setStatusTip(tr("Create a new spreadsheet file"));
        connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
    
        openAction = new QAction(tr("&Open..."), this); //实现打开文件的动作
        openAction->setIcon(QIcon(":/images/open.png"));
        openAction->setShortcut(QKeySequence::Open);
        openAction->setStatusTip(tr("Open an existing spreadsheet file"));
        connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
    .........

    创建菜单
    void MainWindow::createMenus()
    {
        fileMenu = menuBar()->addMenu(tr("&File"));
        fileMenu->addAction(newAction);
        fileMenu->addAction(openAction);
        fileMenu->addAction(saveAction);
        fileMenu->addAction(saveAsAction);
        separatorAction = fileMenu->addSeparator();
        for (int i = 0; i < MaxRecentFiles; ++i)
            fileMenu->addAction(recentFileActions[i]);
        fileMenu->addSeparator();
        fileMenu->addAction(exitAction);
    
        editMenu = menuBar()->addMenu(tr("&Edit"));
        editMenu->addAction(cutAction);
        editMenu->addAction(copyAction);
        editMenu->addAction(pasteAction);
        editMenu->addAction(deleteAction);
    .............
    设置上下文菜单和工具栏
    void MainWindow::createContextMenu()
    {
        spreadsheet->addAction(cutAction);
        spreadsheet->addAction(copyAction);
        spreadsheet->addAction(pasteAction);
        spreadsheet->setContextMenuPolicy(Qt::ActionsContextMenu);
    }
    
    void MainWindow::createToolBars()
    {
        fileToolBar = addToolBar(tr("&File"));
        fileToolBar->addAction(newAction);
        fileToolBar->addAction(openAction);
        fileToolBar->addAction(saveAction);
    
        editToolBar = addToolBar(tr("&Edit"));
        editToolBar->addAction(cutAction);
        editToolBar->addAction(copyAction);
        editToolBar->addAction(pasteAction);
        editToolBar->addSeparator();
        editToolBar->addAction(findAction);
        editToolBar->addAction(goToCellAction);
    }
    

    设置状态栏

    void MainWindow::createStatusBar()
    {
        locationLabel = new QLabel(" W999 ");
        locationLabel->setAlignment(Qt::AlignHCenter);
        locationLabel->setMinimumSize(locationLabel->sizeHint());
    
        formulaLabel = new QLabel;
        formulaLabel->setIndent(3);
    
        statusBar()->addWidget(locationLabel);
        statusBar()->addWidget(formulaLabel, 1);
    
        connect(spreadsheet, SIGNAL(currentCellChanged(int, int, int, int)),
                this, SLOT(updateStatusBar()));
        connect(spreadsheet, SIGNAL(modified()),
                this, SLOT(spreadsheetModified()));
    
        updateStatusBar();
    }

    附上以上实现的简单图形界面程序(Spreadsheet)



  • 相关阅读:
    【板子】博弈论
    【洛谷】P1229快速幂
    【洛谷】P1349广义斐波那契
    2018.11.15 Nginx服务器的使用
    2018.11.14 hibernate中的查询优化---关联级别查询
    2018.11.13 Hibernate 中数据库查询中的Criteria查询实例
    2018.11.12 Spring事务的实现和原理
    2018.11.11 Java的 三大框架:Struts+Hibernate+Spring
    2018.11.10 Mac设置Eclipse的 .m2文件夹是否可见操作&&Mac系统显示当前文件夹的路径设置
    2018.11.9 Dubbo入门学习
  • 原文地址:https://www.cnblogs.com/pangblog/p/3239069.html
Copyright © 2011-2022 走看看