现在的位置: 首页 > 综合 > 正文

Qt学习之对话框与主窗口的创建

2013年10月03日 ⁄ 综合 ⁄ 共 6979字 ⁄ 字号 评论关闭

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)

抱歉!评论已关闭.