Qt的介绍以及安装这里就记录了,先说一下QtGUI的基础“信号(SIGNAL)与槽(SLOT)”。
其实信号与槽的概念很好理解,跟MFC的消息与响应机制类似,只不过MFC的消息响应机制的实现是利用回调函数,而Qt更加的简单。如下就可以将一个信号与一个槽绑定,槽其实就是个响应函数:connect(delButton, SIGNAL(clicked()), this, SLOT(on_del_button()));
所谓的信号,就是用户对窗口的一种操作,比如点击左键,双击左键,点击右键,双击右键,点下按钮等等,不同的控件对应不同的一些信号。一个控件有哪些信号和槽,可以查阅Qt4.1帮助文档。
关于信号与槽的关系,我们举个例子:
吴三桂杀了朱国治举兵造反,消息很快传遍天下,耿精忠,尚可喜收到信号,也做出反应跟着反了,康熙收到了吴三桂造反的消息,甚是气愤,于是乎派兵镇压,王辅臣也收到了吴三桂的造反的消息,但是王辅臣不做任何反应,不管他将来怎么打算,但是他当时是没有反应的。
康熙,吴三桂,耿精忠,尚可喜,王辅臣都是我们窗体上的控件,吴三桂造反这个行为就产生了一个信号,这个信号天下皆知,康熙,耿精忠,尚可喜等收到信号都做出了响应的动作(槽),王辅臣静观其变,不做任何反应。
1,一个信号可以对应N个槽(N>=0)
2,N个信号绑定一个槽(N>=0)
connect(delButton, SIGNAL(clicked()), this, SLOT(on_del_button()));
格式如上,第一个参数是按钮控件的对象名,第二个参数就是这个按钮控件能产生的一种信号,第三个参数是需要作出响应的控件,这里用this表示当前窗口,第四个参数就是槽了,其实就是自己定义实现的一个函数。
基本的信号与槽了解之后,我们使用一些常用控件,如QPushButton,QLabel,QLineEdit,QTreeWidget等来实现如下程序:
上面程序中包含了QTreeWidget控件的常用操作,比如增加根节点,增加节点,给一个节点增加子节点,删除节点,节点上移,节点下移,修改节点的名字(操作顺序与图中的按钮顺序一致),一下是源码:
//window.h
#ifndef __WINDOW_H__
#define __WINDOW_H__
#include <QDialog>
#include <QMainWindow>
#include <QLineEdit>
#include <QString>
#include <QLayout>
#include <QLabel>
#include <QPoint>
#include <QMenu>
#include <QCursor>
#include <QIcon>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QPushButton>
class Window : public QMainWindow
{
Q_OBJECT
public:
Window(QWidget *parent = NULL);
private:
void AddTreeNode(QTreeWidgetItem * item,const QString str1);
void AddTreeRoot(const QString str);
QTreeWidget *tree;
QLineEdit *line;
private slots:
/*增加树的根节点*/
void on_add_class_button();
/*给当前结点增加兄弟节点*/
void on_add_val_button();
/*给当前结点增加子节点*/
void on_add_child_button();
/*删除节点*/
void on_del_button();
/*节点上移*/
void on_up_button();
/*节点下移*/
void on_down_button();
/*显示右键菜单栏*/
void showRightMenu();
/*点击节点时,将节点的名称显示在LineEdit控件中*/
void clicked ( const QModelIndex & index);
/*根据LineEdit中输入的值,改变当前Item的name*/
void changeTreeItemName();
};
#endif
//window.cpp
#include "window.h"
Window::Window(QWidget *parent):QMainWindow(parent)
{
tree = new QTreeWidget;
tree->setContextMenuPolicy(Qt::CustomContextMenu);
tree->setColumnCount(1);
tree->setHeaderLabel("Name");
QTreeWidgetItem *initRoot = new QTreeWidgetItem(QStringList("Frame"));
tree->addTopLevelItem(initRoot);
QTreeWidgetItem *child = new QTreeWidgetItem(QStringList("NewVal"));
child->setText(0,QString("Val"));
initRoot->addChild(child);
QHBoxLayout *leftLayout = new QHBoxLayout;
leftLayout->addWidget(tree);
QVBoxLayout *rightLayout = new QVBoxLayout;
QPushButton* addClassButton = new QPushButton(/*tr("add_class")*/);
addClassButton->setIcon(QIcon(tr("./images/add.png")));
QPushButton* addValButton = new QPushButton(tr("add_val"));
QPushButton* delButton = new QPushButton(/*tr("del")*/);
delButton->setIcon(QIcon(tr("./images/delete.png")));
QPushButton* upButton = new QPushButton();
upButton->setIcon(QIcon(tr("./images/up.png")));
QPushButton* downButton = new QPushButton();
downButton->setIcon(QIcon(tr("./images/down.png")));
QPushButton* addChild = new QPushButton(tr("add child"));
rightLayout->addWidget(addClassButton);
rightLayout->addWidget(addValButton);
rightLayout->addWidget(addChild);
rightLayout->addWidget(delButton);
rightLayout->addWidget(upButton);
rightLayout->addWidget(downButton);
QHBoxLayout *rightdownLayout = new QHBoxLayout;
QLabel* lab = new QLabel("select");
line = new QLineEdit;
rightdownLayout->addWidget(lab);
rightdownLayout->addWidget(line);
rightLayout->addLayout(rightdownLayout);
rightLayout->addStretch();
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout);
mainLayout->setStretch(0, 3);
mainLayout->setStretch(1, 1);
QWidget *mainWidget = new QWidget;
mainWidget->setLayout(mainLayout);
setCentralWidget(mainWidget);
connect(tree, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showRightMenu()));
connect(addClassButton, SIGNAL(clicked()), this, SLOT(on_add_class_button()));
connect(addChild, SIGNAL(clicked()), this, SLOT(on_add_child_button()));
connect(addValButton, SIGNAL(clicked()), this, SLOT(on_add_val_button()));
connect(delButton, SIGNAL(clicked()), this, SLOT(on_del_button()));
connect(upButton, SIGNAL(clicked()), this, SLOT(on_up_button()));
connect(downButton, SIGNAL(clicked()), this, SLOT(on_down_button()));
connect(tree, SIGNAL(clicked ( const QModelIndex &)), this, SLOT(clicked ( const QModelIndex &)));
connect(line, SIGNAL(textChanged(const QString&)), this, SLOT(changeTreeItemName()));
}
/******************************************private******************************************/
void Window::AddTreeNode(QTreeWidgetItem * item,const QString str1)
{
if (item->parent() != NULL)
{
QStringList fonts;
fonts<<str1<<str1;
QTreeWidgetItem* newitem = new QTreeWidgetItem(fonts);
item->parent()->addChild(newitem);
}
}
void Window::AddTreeRoot(const QString str)
{
QStringList fonts;
fonts<<str<<str;
QTreeWidgetItem *note1 = new QTreeWidgetItem(fonts);
tree->addTopLevelItem(note1);
}
/******************************************SLOTS******************************************/
/*增加树的根节点*/
void Window::on_add_class_button()
{
QTreeWidgetItem *Root = new QTreeWidgetItem(QStringList("DataFrame"));
tree->addTopLevelItem(Root);
QTreeWidgetItem *child = new QTreeWidgetItem(QStringList("NewVal"));
Root->addChild(child);
}
/*给当前结点增加兄弟节点*/
void Window::on_add_val_button()
{
QTreeWidgetItem * item= tree->currentItem();
if (item == NULL || item->parent() == NULL) {
return;
}
else
{
QTreeWidgetItem* child = new QTreeWidgetItem(QStringList("NewVal"));
item->parent()->addChild(child);
}
}
/*给当前结点增加子节点*/
void Window::on_add_child_button()
{
if (NULL != tree->currentItem())
{
QTreeWidgetItem* newItem = new QTreeWidgetItem(QStringList("NewVal"));
tree->currentItem()->addChild(newItem);
}
}
/*删除节点*/
void Window::on_del_button()
{
QTreeWidgetItem * currentItem = tree->currentItem();
if(currentItem==NULL)
{
return;
}
//Èç¹ûûÓи¸½Úµã¾ÍÖ±½Óɾ³ý
if(currentItem->parent()==NULL)
{
delete tree->takeTopLevelItem(tree->currentIndex().row());
}
else
{
//Èç¹ûÓи¸½Úµã¾ÍÒªÓø¸½ÚµãµÄtakeChildɾ³ý½Úµã
delete currentItem->parent()->takeChild(tree->currentIndex().row());
}
}
/*节点上移*/
void Window::on_up_button()
{
if (tree->currentItem() == NULL)
{
return;
}
QTreeWidgetItem* parent = tree->currentItem()->parent();
QTreeWidgetItem* curItem = tree->currentItem();
if (parent == NULL || parent->indexOfChild(curItem) <= 0)
{
return;
}
int curIndex = parent->indexOfChild(curItem);
QList<QTreeWidgetItem*> oldChildren = parent->takeChildren();
QList<QTreeWidgetItem*> newChildren;
for (int i = 0; i < curIndex - 1; ++i)
{
newChildren.append(oldChildren.at(i));
}
newChildren.append(oldChildren.at(curIndex));
newChildren.append(oldChildren.at(curIndex-1));
for (int i = curIndex + 1; i < oldChildren.size(); ++i)
{
newChildren.append(oldChildren.at(i));
}
parent->addChildren(newChildren);
tree->setCurrentItem(parent->child(curIndex - 1));
}
/*节点下移*/
void Window::on_down_button()
{
if (tree->currentItem() == NULL)
{
return;
}
QTreeWidgetItem* parent = tree->currentItem()->parent();
QTreeWidgetItem* curItem = tree->currentItem();
if (parent == NULL || parent->indexOfChild(curItem) == parent->childCount() - 1)
{
return;
}
int curIndex = parent->indexOfChild(curItem);
QList<QTreeWidgetItem*> oldChildren = parent->takeChildren();
QList<QTreeWidgetItem*> newChildren;
for (int i = 0; i < curIndex; ++i)
{
newChildren.append(oldChildren.at(i));
}
newChildren.append(oldChildren.at(curIndex+1));
newChildren.append(oldChildren.at(curIndex));
for (int i = curIndex + 1; i < oldChildren.size(); ++i)
{
newChildren.append(oldChildren.at(i));
}
parent->addChildren(newChildren);
tree->setCurrentItem(parent->child(curIndex + 1));
}
/*显示右键菜单栏*/
void Window::showRightMenu()
{
QMenu* menu = new QMenu(tree);
QAction* addAction = new QAction(tr("New"), this);
QAction* delAction = new QAction(tr("Del"), this);
QAction* modifyAction = new QAction(tr("Modify"), this);
menu->addAction(addAction);
menu->addAction(delAction);
menu->addAction(modifyAction);
menu->exec(QCursor::pos());
}
/*点击节点时,将节点的名称显示在LineEdit控件中*/
void Window::clicked ( const QModelIndex & index)
{
if (tree->currentItem() == NULL)
{
return;
}
if (tree->currentItem()->parent() == NULL)
{
line->setText( tree->currentItem()->text(0) );
return;
}
line->setText( tree->currentItem()->text(0) );
}
/*根据LineEdit中输入的值,改变当前Item的name*/
void Window::changeTreeItemName()
{
if (tree->currentItem() == NULL)
{
return;
}
tree->currentItem()->setText(0,line->text());
}
//main.cpp
#include <QApplication>
#include <QDialog>
#include "window.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window *mainWindow = new Window;
mainWindow->resize(300, 160);
mainWindow->setWindowTitle(QWidget::tr("Qt Test"));
mainWindow->show();
return a.exec();
}
代码中使用了图标,添加方法是在源文件目录下新建images文件夹,随便放几张图片,名称改为代码中的名称即可。
Ubuntu下编译命令:
qmake –project
qmake XXX.pro
make