分类: LINUX
2010-07-07 13:23:49
前段时间在学习Qt,边学边做了个小的程序“河南师范大学宿舍报修系统”,现在终于有空总结一下。其中部分代码源自网络,因已忘记出处,在此一并指出,尊重原作者的相关权益。
开发环境采用Qt Creator 1.2.1,基于Qt 4.5.3。操作系统为Windows XP sp3。
QTextCodec::setCodecForTr(QTextCodec::codecForName("GB18030"));
templatestruct Singleton { struct object_creator { object_creator(){ Singleton ::instance(); } inline void do_nothing()const {} }; static object_creator create_object; public: typedef T object_type; static object_type& instance() { static object_type obj; create_object.do_nothing(); return obj; } }; template typename Singleton ::object_creator Singleton ::create_object;
使用方法:
QDevWing& devwing = Singleton::instance();
QObject::tr(QCryptographicHash::hash(str.toAscii(),QCryptographicHash::Md5).toHex());
1)首先需要修改项目文件(pro文件),添加或者修改以下语句:
QT += sql
2)引入以下头文件:
QtSql
3)使用QSqlDatabase类和QSqlQuery进行数据库操作
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); QString appDir(QApplication::applicationDirPath()); db.setDatabaseName(appDir.append("/").append(dbName)); //qDebug()<
利用Qt Designer设计好界面后,保存成ui文件,导入项目,编译,会自动生成“ui_文件名.h”文件。这样的界面的使用方法之一,即多重继承方式:
1)引入自动生成的这个头文件;
2)创建类,继承一个Qt的UI类以及这个生成的ui类:
class LoginDialog : public QDialog, public Ui::Dialog { Q_OBJECT public: LoginDialog(QDialog* = 0); public slots: virtual void accept(); };
3)在这个子类中就可以很方便的使用ui组件了:
首先,需要在构造函数中安装UI:
this->setupUi(this);
之后,可以使用开始以下的代码来访问ui组件:
this->edit_ID->setFocus();
1)在工程目录下创建RC文件,例如reportSystem.rc。内容是:
IDI_ICON1 ICON DISCARDABLE "reportSystem.ico"
其中的reportSystem.ico即为要设置的图标。
2)在pro文件中添加一行:
RC_FILE = reportSystem.rc
信号和槽机制:
1)自动绑定的信号和槽:
如有ui组件名为btn_finished,也即它是一个按钮,其单击信号自动绑定的槽为on_btn_finished_clicked(),即在对象名前加上on_,对象名后加上下划线和信号名。因此,如果想要为该按钮的单击事件添加处理代码,只需在该ui组件所在的类中声明并实现on_btn_finished_clicked()函数,声明需要写在private slots中。其它的组件和事件类似,如action组件actUserInfo的触发信号对应的槽为on_actUserInfo_triggered()。
2)手工绑定的信号和槽:
如果要绑定的槽的函数名不符号以上的要求,或者想自己创建槽,则需要手工绑定信号和槽。
首先,需要创建槽函数:在类的private slots声明区域中声明成员函数,如void registerUser(const QString&)。槽函数除了可以像一般的成员函数一样使用(此时返回值有用)外,还可以绑定某(些)信号,成为信号处理函数。某信号的槽必须与该信号拥有相同的参数签名。
其次,绑定信号和槽:如在类的构造函数中写上:
connect(this->l_register,SIGNAL(linkActivated(QString)),this,SLOT(registerUser(QString)));
connect函数是QObject类的成员函数,用于手工绑定信号和槽。第一个参数是触发信号的对象,第二个参数是信号类型,用宏SIGNAL()封装。第三个参数是槽对象,第四个参数是槽函数,用SLOT()宏封装。
Qt应用程序中的所有用户自定义UI类都需要继承自某一Qt预定义的UI类,同时需要在类声明中加上Q_OBJECT,占据一行,并且使用qmake,这样才能完整地拥有Qt的强大功能(元对象),如信号和槽机制,运行时类型信息和动态属性系统。
QSetting用于在系统中保存配置信息。不同的系统有不同的保存位置,如Windows中就保存在注册表中,Linux中则保存在配置文件中。比如:
1)创建对象,指定保存节点:QSettings settings(tr("devwing"),tr("reportSystem"));
2)设置值:settings.setValue("uID","1");
3)获取值:QString uStr = settings.value("uID","").toString();
以上的例子在windows xp中将在注册表的HKEY_CURRENT_USER\Software\下建立devwing\reportSystem项,并添加字符串项uID,值为"1"。
1)在MainWindow中加入私有成员QSystemTrayIcon* trayIcon;
2)在MainWindow的构造函数中加入以下代码以创建系统托盘:
QIcon icon(":/new/devwing/reportSystem.ico");//创建QIcon对象,参数是图标资源,值为项目的资源文件中图标的地址 trayIcon = new QSystemTrayIcon(this); trayIcon->setIcon(icon);//将创建的QIcon对象作为系统托盘图标 trayIcon->show();//显示托盘图标 QMenu *trayMenu = new QMenu(this);//创建菜单 trayMenu->addAction(ui->actReportAdd);//为托盘菜单添加菜单项 trayMenu->addSeparator();//为托盘菜单添加分隔符 trayIcon->setContextMenu(trayMenu);//将创建菜单作为系统托盘菜单 trayIcon->setToolTip(tr("河南师范大学宿舍报修系统"));//设置系统托盘提示 connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(onSystemTrayIconClicked(QSystemTrayIcon::ActivationReason)));//为系统托盘绑定单击信号的槽
3)在系统托盘显示气泡消息提示:
trayIcon->showMessage(tr("河南师范大学宿舍报修系统"), tr("最小化到这里"), QSystemTrayIcon::Information, 5000);
4)隐藏系统托盘图标:
trayIcon->hide();
QT扩展了C++,如果指针对象有父对象时,可以不用显式释放内存,在删除Q类(QObject继承类)指针或Q类对象在析构的时候,同时会删除或析构他的子对象。这里的父子关系不是指继承关系,而是指构造时在构造函数的参数中指定的父类,或通过setParent()函数指定的父类。我们需要显式释放的是那些没有父对象的孤立的指针。
1)设置字体:
QFont font; font.setPointSize(10); ui->statusBar->setFont(font);
2)显示消息:
ui->statusBar->showMessage(tr("准备就绪"));
3)清除消息:
ui->statusBar->clearMessage();
默认情况下,Qt应用程序在用户关闭最后一个窗口时就退出。这是由QApplication::quitOnLastWindowClosed属性决定的。通过QApplication::setQuitOnLastWindowClosed(false)可以阻止Qt应用程序的自动退出。这样可以配合系统托盘实现显示和隐藏程序窗口的功能。
默认情况下,MainWindow不居中显示。但它提供了move函数,可以达到相同的效果:
QDesktopWidget* desktop = QApplication::desktop(); move((desktop->width() - this->width())/2, (desktop->height() - this->height())/2);
QList模板类用于链表操作,它重载了<<等运算符,可以简化操作。QStringList继承自QList
QStringList head; head<QItemDelegate与重写QTableView编辑器
一般情况下,QTableView的编辑器是文本形式的,即当点击QTableView的某一单元格对数据进行修改时,都是显示一个文本框。如果用于需要改变编辑器,则需要为其指定QItemDelegate。这里以下拉框为例进行说明:
1)首先,需要创建自定义类SelectDelegate,它继承自QItemDelegate,并声明Q_OBJECT宏。
2)在该类中重载以下公有成员函数:
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;//返回以parent构造的UI控件,如 new QComboBox(parent); void setEditorData(QWidget *editor, const QModelIndex &index) const;//已知模型中的值,设置编辑器的值 void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;//已知编辑器的值,设置模型中的值 void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;//设置编辑器的几何尺寸,如 editor->setGeometry(option.rect);3)这样,就可以在QTableView中设置某一列或某一行或所有单元格的编辑器:
SelectDelegate* delegate = new SelectDelegate(); ui->tableView->setItemDelegateForColumn(1,delegate);//设置第2列的编辑器的下拉框QTableView与QSqlTableModel
QTableView是表格视图类,可以通过为其指定model(模型)来配置它的数据及操作。例如,如果设置其模型为QSqlTableModel的对象,它的数据将来自于数据库中查询出来的数据,对它的修改将影响数据库。
1)创建QSqlTableModel对象,并进行必要的初始化:
QSqlTableModel *model = new QSqlTableModel; model->setTable("record"); //设置数据来源于数据库中的哪张表 model->setSort(3,Qt::DescendingOrder);//设置排序规则:按第4列降序排列 model->setFilter("User='admin'"); //设置过滤器:这里要求用户为admin model->setEditStrategy(QSqlTableModel::OnManualSubmit);//设置编辑策略:手工提交数据。可能的值还有:QSqlTableModel::OnFieldChange(改变单元格时提交)、QSqlTableModel::OnRowChange(改变行时交)。 model->select(); //查询数据 for(int i=0;isetHeaderData(i,Qt::Horizontal,header[i]);//设置表头 } 2)为QTableView绑定模型:
ui->tableView->setModel(model);3)对QTableView进行设置:
ui->tableView->setColumnHidden(0,true);//隐藏第1列4)设置焦点到某一个单元格中以编辑:
ui->tableView->edit(model->index(0,1));//modex->(index(0,1))用于指定第1行第2列的单元格5)设置model某一单元格中的值:
model->setData(model->index(0,6),tr("尚未处理"));6)获取所有选择的行:
QItemSelectionModel *selectionModel = ui->tableView->selectionModel(); QModelIndexList indexes = selectionModel->selectedRows();foreach
foreach关键字是Qt对标准C++的扩展,需要先用Qt自带的qmake预编译。也可以使用Q_FOREACH宏,它可以被标准C++编译器识别。foreach用于方便地遍历集合。语法是:
foreach(item, collection){ //... }MainWindow最大化时的事件处理
1)需要重载MainWindow的保护成员:虚函数virtual void changeEvent(QEvent* event);
2)在changeEvent()函数的实现中,判断事件类别,若为WindowStateChange,而且当前窗口被最大化,则执行相关操作。如:
if(event->WindowStateChange){ if(this->isMaximized()){ ui->actToolText->trigger(); return; } }关闭MainWindow时隐藏到系统托盘
1)需要重载MainWindow的保护成员:虚函数virtual void closeEvent(QCloseEvent * event )
2)在closeEvent()函数的实现中,显示系统托盘提示,并隐藏窗口。
trayIcon->showMessage(tr("河南师范大学宿舍报修系统"), tr("最小化到这里"), QSystemTrayIcon::Information, 5000); hide(); event->ignore();Qt应用程序的发布
首先需要以release方式编译应用程序,将编译好的程序文件复制到发布文件夹。
其次将以下动态链接库复制到发布文件夹中:mingwm10.dll、QtCore4.dll、QtGui4.dll。可以从“Qt安装目录\qt\bin”下面找到它们。
如果用到了其他功能,如OpenGL,则需要将QtOpenGL4.dll也复制到发布文件夹中。
如果应用程序有访问数据库的功能,则不仅要将QtSql4.dll复制到发布文件夹,而且还需要将对应的数据库驱动程序(同样也是dll)复制过来,放到“发布文件夹\sqldrivers”目录下面。可以从可以从“Qt安装目录\qt\plugins\sqldrivers”下面找到它们,如qsqlite4.dll。
如果应用程序含有中文,还需要在发布文件夹下面建立codecs目录,并将“Qt安装目录\qt\plugins\codecs”目录下面的qcncodecs4.dll复制过来。
对于其他以插件方式提供的功能,如imageformats,也需要像上面的方式将所有需要的dll复制过来。
阅读(2051) | 评论(0) | 转发(0) |给主人留下些什么吧!~~