QTime time = QTime::currentTime();
3> 窗口 widget 相关
setWindowTitle(tr("My Title")); // 设置窗口标题
width();// 窗口宽度
4> 窗口(widget) 事件回调相关 (具体参考 widget.h 文件)
5> QT 画布(QPainter)的使用
- ,,); // 画笔颜色
- QPainter painter(objWidget); // 创建一个画布, objWidget 为当前 画笔的要画到哪里, 一般为 Widget 对象
- // 设置画布的样式
- painter.setPen(Qt::NoPen);
- painter.setBrush(hourColor);
- painter.translate(width() / 2, height() / 2); // 画布坐标系统的移动(当前窗口的中心点位置)
- painter.scale(side / 200.0, side / 200.0); // 设置缩放
- painter.rotate(30.0); // 坐标系统,旋转 30 度
- painter.save();
- painter.drawLine(92, 0, 96, 0);
- // 常用函数(参考QPainter.h)
- void drawText()
- void fillRect()
- void drawPoint()
- void drawPoints(const QPoint *points, int pointCount);
- void drawLine(int x1, int y1, int x2, int y2);
- void drawLines(const QLineF *lines, int lineCount);
- void drawRect(int x1, int y1, int w, int h);
- void drawRects(const QRectF *rects, int rectCount);
- void drawEllipse(int x, int y, int w, int h);
- void drawPolyline(const QPointF *points, int pointCount);
- void drawText(const QPointF &p, const QString &s);
- void drawImage() // 可以绘制图片
- void eraseRect()
- void scale(qreal sx, qreal sy); // 设置缩放
- void rotate(qreal a);// 设置旋转
- void setBackground(const QBrush &bg); // 设置背景颜色
- void setPen(const QColor &color); // 设置画笔
- // 画一个路径( QPainterPath 可以存储 painter 的路径信息)
- QPainterPath clock; // 初始化一个钟表的形状
- clock.addEllipse(-50.0, -50.0, 100.0, 100.0);
- clock.addEllipse(-48.0, -48.0, 96.0, 96.0);
- clock.moveTo(0.0, 0.0);
- clock.lineTo(-2.0, -2.0);
- clock.lineTo(0.0, -42.0);
- clock.lineTo(2.0, -2.0);
- clock.lineTo(0.0, 0.0);
- clock.moveTo(0.0, 0.0);
- clock.lineTo(2.732, -0.732);
- clock.lineTo(24.495, 14.142);
- clock.lineTo(0.732, 2.732);
- clock.lineTo(0.0, 0.0);
- QPainter painter(objWidget); // 创建一个画布, objWidget 为当前 画笔的要画到哪里, 一般为 Widget 对象
- painter.fillPath(clock, Qt::blue);
- // 绘制一个文本
- QPainterPath text;
- QFont font;
- font.setPixelSize(50);
- QRect fontBoundingRect = QFontMetrics(font).boundingRect(tr("Qt"));
- text.addText(-QPointF(fontBoundingRect.center()), font, tr("Qt"));
- QPainter painter(objWidget); // 创建一个画布, objWidget 为当前 画笔的要画到哪里, 一般为 Widget 对象
- painter.fillPath(text, Qt::blue); // 绘制一个文本
- QGridLayout *mainLayout = new QGridLayout;
- // 2行 3列的一个网格布局
- for (int i = 0; i < 2; ++i) { // 行
- for (int j = 0; j < 3; ++j) { // 列
- glWidgets[i][j] = new GLWidget(0, 0);
- mainLayout->addWidget(glWidgets[i][j], i, j); // 直接将其他窗口对象,添加到 mainLayout 中就可以
- }
- }
- setLayout(mainLayout); // 调用窗口对象的 setLayout 方法来设置布局
7> QT 控件的使用 总结
- QComboBox 下拉选择控件
- shapeComboBox = new QComboBox;
- shapeComboBox->addItem(tr("Clock"));
- shapeComboBox->addItem(tr("House"));
- shapeComboBox->addItem(tr("Text"));
- shapeComboBox->addItem(tr("Truck"));
- // 置回调函数 operationChanged
- connect(shapeComboBox, SIGNAL(activated(int)), this, SLOT(shapeSelected(int)));
- // 回到函数中, index 为当前选择的索引
- void Window::shapeSelected(int index)
- {
- }
- int index = shapeComboBox->currentIndex(); // 可以得到当前选择的索引
- // Table View 的使用
- QStandardItemModel model(4, 2); // 设置表格的数据模型 ( 4 行 2 列)
- QTableView tableView; // 表格对象
- tableView.setModel(&model);// 设置数据模型
- // 设置表格对象的数据显示
- for (int row = 0; row < 10; ++row)
- {
- for (int column = 0; column < 5; ++column)
- {
- QModelIndex index = model.index(row, column, QModelIndex()); // 得到某一个具体的数据索引
- model.setData(index, QVariant("aaaa")); // 设置数据
- }
- }
- model.setColumnCount(5); // 设置表格的列数
- model.setRowCount(2); // 设置表格的行数
- model.insertColumn(1); // 在第 1列后面,插入一列
- model.insertRow(1); // 在第 1 行后面,插入一列
- model.rowCount(); // 表格行数
- model.columnCount(); // 表格列数
截图:
- // MainWindow 为主窗口的对象指针
- // Action初始化 -- 一个 Action 相当于 一个具体的菜单项
- actionShow_Test_Dialog = new QAction(MainWindow);
- actionShow_Test_Dialog->setObjectName(QString::fromUtf8("actionShow_Test_Dialog"));
- actionOpen = new QAction(MainWindow);
- actionOpen->setObjectName(QString::fromUtf8("actionOpen"));
- actionSave = new QAction(MainWindow);
- actionSave->setObjectName(QString::fromUtf8("actionSave"));
- actionShow_Table = new QAction(MainWindow);
- actionShow_Table->setObjectName(QString::fromUtf8("actionShow_Table"));
- // QMenuBar 菜单栏, 上面可以放很多的 QMenu
- menuBar = new QMenuBar(MainWindow);
- menuBar->setObjectName(QString::fromUtf8("menuBar"));
- menuBar->setGeometry(QRect(0, 0, 400, 22));
- // QMenu 菜单, 一个菜单上,可以放很多的 Action
- menuFile = new QMenu(menuBar);
- menuFile->setObjectName(QString::fromUtf8("menuFile"));
- menuTest = new QMenu(menuBar);
- menuTest->setObjectName(QString::fromUtf8("menuTest"));
- MainWindow->setMenuBar(menuBar);
- menuBar->addAction(menuFile->menuAction());
- menuBar->addAction(menuTest->menuAction());
- menuFile->addAction(actionOpen);
- menuFile->addAction(actionSave);
- menuTest->addAction(actionShow_Test_Dialog);
- menuTest->addAction(actionShow_Table);
- // 设置菜单项的具体回调函数
菜单层次关系截图如下:
1、如果在窗体关闭前自行判断是否可关闭
答:重新实现这个窗体的closeEvent()函数,加入判断操作
void MainWindow::closeEvent(QCloseEvent *event)
{
if (maybeSave())
{
writeSettings();
event->accept();
}
else
{
event->ignore();
}
}
2、如何用打开和保存文件对话框
答:使用QFileDialog
QString fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
{
loadFile(fileName);
}
QString fileName = QFileDialog::getSaveFileName(this);
if (fileName.isEmpty())
{
return false;
}
如果用qt自带的话:
选择文件夹
QFileDialog* openFilePath = new QFileDialog( this, " 请选择文件夹", "file"); //打开一个目录选择对话框
openFilePath-> setFileMode( QFileDialog::DirectoryOnly );
if ( openFilePath->exec() == QDialog::Accepted )
{
//code here!
}
delete openFilePath;
选择文件:
QFileDialog *openFilePath = new QFileDialog(this);
openFilePath->setWindowTitle(tr("请选择文件"));
openFilePath->setDirectory(".");
openFilePath->setFilter(tr("txt or image(*.jpg *.png *.bmp *.tiff *.jpeg *.txt)"));
if(openFilePath->exec() == QDialog::Accepted)
{
//code here
}
delete openFilePath;
7、如何使用警告、信息等对话框
答:使用QMessageBox类的静态方法
int ret = QMessageBox::warning(this, tr("Application"),
tr("The document has been modified./n"
"Do you want to save your changes?"),
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No,
QMessageBox::Cancel | QMessageBox::Escape);
if (ret == QMessageBox::Yes)
return save();
else if (ret == QMessageBox::Cancel)
return false;
或者简单点儿:
QMessageBox::information(this, "关于","盲人辅助系统(管理端)!/nVersion:1.0/nNo Copyright");
9、在Windows下Qt里为什么没有终端输出?
答:把下面的配置项加入到.pro文件中
win32:CONFIG += console
11、想在源代码中直接使用中文,而不使用tr()函数进行转换,怎么办?
答:在main函数中加入下面三条语句,但并不提倡
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
或者
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
使用GBK还是使用UTF-8,依源文件中汉字使用的内码而定
这样,就可在源文件中直接使用中文,比如:
QMessageBox::information(NULL, "信息", "关于本软件的演示信息", QMessageBox::Ok, QMessageBox::NoButtons);
12、为什么将开发的使用数据库的程序发布到其它机器就连接不上数据库?
答:这是由于程序找不到数据库插件而致,可照如下解决方法:
在main函数中加入下面语句:
QApplication::addLibraryPath(strPluginsPath");
strPluginsPath是插件所在目录,比如此目录为/myapplication/plugins
则将需要的sql驱动,比如qsqlmysql.dll, qsqlodbc.dll或对应的.so文件放到
/myapplication/plugins/sqldrivers/
目录下面就行了
这是一种解决方法,还有一种通用的解决方法,即在可执行文件目录下写qt.conf文件,把系统相关的一些目录配置写到qt.conf文件里,详细情况情参考Qt Document Reference里的qt.conf部分
13、如何创建QT使用的DLL(.so)以及如何使用此DLL(.so)
答:创建DLL时其工程使用lib模板
TEMPLATE=lib
而源文件则和使用普通的源文件一样,注意把头文件和源文件分开,因为在其它程序使用此DLL时需要此头文件
在使用此DLL时,则在此工程源文件中引入DLL头文件,并在.pro文件中加入下面配置项:
LIBS += -Lyourdlllibpath -lyourdlllibname
Windows下和Linux下同样(Windows下生成的DLL文件名为yourdlllibname.dll而在Linux下生成的为libyourdlllibname.so。注意,关于DLL程序的写法,遵从各平台级编译器所定的规则。
14、如何启动一个外部程序
答:1、使用QProcess::startDetached()方法,启动外部程序后立即返回;
2、使用QProcess::execute(),不过使用此方法时程序会最阻塞直到此方法执行的程序结束后返回,这时候可使用QProcess和QThread这两个类结合使用的方法来处理,以防止在主线程中调用而导致阻塞的情况
先从QThread继承一个类,重新实现run()函数:
class MyThread : public QThread
{
public:
void run();
};
void MyThread::run()
{
QProcess::execute("notepad.exe");
}
这样,在使用的时候则可定义一个MyThread类型的成员变量,使用时调用其start()方法:
class ...............
{...........
MyThread thread;
............
};
.....................
thread.start();
19、如何制作不规则形状的窗体或部件
答:请参考下面的帖子
http://www.qtcn.org/bbs/read.php?tid=8681
20、删除数据库时出现"QSqlDatabasePrivate::removeDatabase: connection 'xxxx' is still in use, all queries will cease to work"该如何处理
答:出现此种错误是因为使用了连接名字为xxxx的变量作用域没有结束,解决方法是在所有使用了xxxx连接的数据库组件变量的作用域都结束后再使用QSqlDatabase::removeDatabae("xxxx")来删除连接。
21、如何显示一个图片并使其随窗体同步缩放
答:下面给出一个从QWidget派生的类ImageWidget,来设置其背景为一个图片,并可随着窗体改变而改变,其实从下面的代码中可以引申出其它许多方法,如果需要的话,可以从这个类再派生出其它类来使用。
头文件: ImageWidget.hpp
#ifndef IMAGEWIDGET_HPP
#define IMAGEWIDGET_HPP
#include <QtCore>
#include <QtGui>
class ImageWidget : public QWidget
{
Q_OBJECT
public:
ImageWidget(QWidget *parent = 0, Qt::WindowFlags f = 0);
virtual ~ImageWidget();
protected:
void resizeEvent(QResizeEvent *event);
private:
QImage _image;
};
#endif
CPP文件: ImageWidget.cpp
#include "ImageWidget.hpp"
ImageWidget::ImageWidget(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
_image.load("image/image_background");
setAutoFillBackground(true); // 这个属性一定要设置
QPalette pal(palette());
pal.setBrush(QPalette::Window,
QBrush(_image.scaled(size(), Qt::IgnoreAspectRatio,
Qt::SmoothTransformation)));
setPalette(pal);
}
ImageWidget::~ImageWidget()
{
}
// 随着窗体变化而设置背景
void ImageWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
QPalette pal(palette());
pal.setBrush(QPalette::Window,
QBrush(_image.scaled(event->size(), Qt::IgnoreAspectRatio,
Qt::SmoothTransformation)));
setPalette(pal);
}
22、Windows下如何读串口信息
答:可通过注册表来读qt4.1.0 读取注册表得到 串口信息的方法!
23.背景修改
QString filename = "E:/图片/壁纸/1.jpg";
QPixmap pixmap(filename);
pal.setBrush(QPalette::Window,QBrush(pixmap));
setPalette(pal);
24.载入某个指定类型文件
openFileName = QFileDialog::getOpenFileName(this,tr("Open Image"), "/home/picture", tr("Image Files (*.png *.tif *.jpg *.bmp)"));
if (!openFileName.isEmpty())
{
Ui_Project_UiClass::statusBar->showMessage("当前打开的文件:" + openFileName);
label_2->setPixmap(QPixmap(openFileName));
}
25.QText乱码问题
发布到别的机器上后,中文全是乱码。gb18030和gb2312我都试过了,都是乱码。
main.cpp里设置如下:
QTextCodec *codec = QTextCodec::codecForName("System");
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
把gb2312改成System就可以了
#include <QTextCodec>
26.图片问题
用label就可以载入图片,方法:
label->setPixmap(QPixmap(“path(可以用geifilename函数得到)”));
但是这样的label没有滚动条,很不灵活,可以这样处理:
在QtDesign中创建一个QScrollArea控件,设置一些属性,然后在代码中新建一个label指针,在cpp的构造函数中用new QLabel(this)初始化(一定要有this,不然后面setWidget会出错)。然后再:
scrollArea->setWidget(label_2);
scrollArea->show();
27.布局
最后要充满窗口,点击最外层的窗口空白处。再点击水平layout即可
28.程序图标
准备一个ICO图标,把这个图标复制到程序的主目录下,姑且名字叫”myicon.ico”吧。然后编写一个icon.rc文件。里面只有一行文字:
IDI_ICON1 ICON “myicon.ico”
最后,在工程的pro文件里加入一行:
RC_FILE = icon.rc
qmake和make一下,就可以发现你的应用程序拥有漂亮的图标了。
29.回车输出
QT中操作文件,从文件流QTextStream输出回车到txt的方法是<< 'r' << endl;
30.QListView的添加或者删除
QStringList user;
user += "first";
user +="second";
QStringListModel *model = new QStringListModel(user);
userList->setModel(model); //useList是个QListView
user += "third";
model->setStringList(user);
31.设置背景音乐
如果只是简单的设置背景音乐的话。用QSound。具体查看qt助手。
windows下的QSound 只能播放wav格式哦。。
32.禁止QAbstractItemView的子类的双击修改功能。
比如listview,双击某个item就会成为编辑模式。禁止此功能。用:
QAbstractItemVIew`s name->setEditTriggers(QAbstractItemView::NoEditTriggers);
33.qt对文件的操作
读文件
QFile inputFile(":/forms/input.txt");
inputFile.open(QIODevice::ReadOnly);
QTextStream in(&inputFile);
QString line = in.readAll();
inputFile.close();
写文件
QFile file(filename);
if (!file.open(QIODevice::WriteOnly))
{
fprintf(stderr, "Could not open %s for writing: %s/n",
qPrintable(filename),
qPrintable(file.errorString()));
return false;
}
file.write(data->readAll());
file.close();
将某个路径转化为当前系统认可的路径
QDir::convertSeparators(openFileName)
获取当前路径
QDir currentPath;
QString filePath = currentPath.absolutePath ();
QString path = QDir::convertSeparators(filePath + "/" +clickedClass);
一些操作
QFile::exists(fileName)
QFile::Remove();
文件打开模式
if(file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::ReadOnly)
34.qt确认对话框
QMessageBox mb(tr("删除确认"), tr("确认删除此项?"),
QMessageBox::Question,
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape,
QMessageBox::NoButton);
if(mb.exec() == QMessageBox::No)
return;
35.QListView
QStringList user;
user += "first";
user +="second";
QStringListModel *model = new QStringListModel(user);
QListView user_id->setModel(model);
user += "third"; //下面2步是更新
model->setStringList(user);
36.允许这样的语句:Layout->setGeometry( QRect( 10,10,100,50 ) ); QHBoxLayout等布局对象(but not widget )里的 Widget 的排列,是按其加入的先后顺序而定的。要让其显示在一个窗口上,需要把让这个窗口作为其 Parent.
37.setMargin() sets the width of the outer border. This is the width of the reserved space along each of the QBoxLayout's four sides. 就是设置其周围的空白距离。
38.setSpacing() sets the width between neighboring boxes. (You can use addSpacing() to get more space at a particular spot. ) 就是设置相邻对象间的距离。
39.addStretch() to create an empty, stretchable box. 相当于加入了一个空白的不显示的部件。
40.Qt程序的全屏幕显示:
//全屏幕显示
//main_window->setGeometry( 0, 0, QApplication::desktop()->width(), QApplication::desktop()->height() );
//或者:
main_window->resize( QApplication::desktop()->width(), QApplication::desktop()->height() );
实际上只有第一种方法可以。第二种方法只是把窗口大小调整为屏幕大小,但是由于其显示位置未定,所以显示出来还是不行。第一种方法直接设置了窗口的显示位置为屏幕左上角。
Qapplication::desktop() 返回了一个 QdesktopWidget 的对象指针。
全屏幕显示后,windows下依然无法挡住任务栏。(为了实现跨平台性,最好还是用Qt提供的方法。例如这里用的就是 Qt的方法,而不是用的Windows API)
41.使用以下代码可以为一个窗口部件加入背景图片:
QPixmap pic;
pic.load( "qqpet.bmp" );
Label.setPixmap( pic );
Label.show();
QpushButton 也可以。但是在使用了 setPixmap 后,原来的文字就显示不了了。如果在setPixmap后设置文字,则图片就显示不了。
其他事项:the constructor of QPixmap() acept char * only for xpm image.
hope file is placed proper and is bmp. jpg's gif's can cause error(configure).----不能缩放图象。
42.调用 void QWidget::setFocus () [virtual slot] 即可设置一个焦点到一个物体上。
43.让窗口保持固定大小:
main_window->setMinimumSize( g_main_window_w, g_main_window_h );
main_window->setMaximumSize( g_main_window_w, g_main_window_h );
只要让最小尺寸和最大尺寸相等即可。
44.获得系统日期:
QDate Date = QDate::currentDate();
int year = Date.year();
int month = Date.month();
int day = Date.day();
45.获得系统时间:
QTime Time = QTime::currentTime();
int hour = Time.hour();
int minute = Time.minute();
int second = Time.second();
46.QString::number 可以直接传其一个数而返回一个 QString 对象。
因此可以用以下代码:
m_textedit->setText( QString::number( 10 ) );
47.利用 QString::toInt() 之类的接口可以转换 字符串为数。这就可以把 QLineEdit之类返回的内容转换格式。
文档里的描述:
int QString::toInt ( bool * ok = 0, int base = 10 ) const
Returns the string converted to an int value to the base base, which is 10 by default and must be between 2 and 36.
If ok is not 0: if a conversion error occurs, *ok is set to FALSE; otherwise *ok is set to TRUE.
48.关于 QTimer .
文档:
QTimer is very easy to use: create a QTimer, call start() to start it and connect its timeout() to the appropriate slots. When the time is up it will emit the timeout() signal.
Note that a QTimer object is destroyed automatically when its parent object is destroyed.
可以这样做:
QTimer *time = new QTimer( this );
Timer->start( 1000, false ); //每1000ms timer-out一次,并一直工作(false ),为 true只工作一次。
Connect( timer, SIGNAL( timeout() ), this, SLOT( dealTimer() ) );
49.关于QSpinBox:
QSpinBox allows the user to choose a value either by clicking the up/down buttons to increase/decrease the value currently displayed or by typing the value directly into the spin box. If the value is entered directly into the spin box, Enter (or Return) must be pressed to apply the new value. The value is usually an integer.
如下方式创建:
QSpinBox *spin_box = new QSpinBox( 0, 100, 1, main_window );
spin_box->setGeometry( 10,10, 20, 10 );
这样创建后,它只允许输入数字,可以设置其几何大小。
使用int QSpinBox::value () const得到其当前值。
50.Main 可以这样:
clock->show();
int result = a.exec();
delete clock;
return result;
51. Qt 中的中文:
如果使程序只支持一种编码,也可以直接把整个应用程序的编码设置为GBK编码, 然后在字符串之前 加tr(QObject::tr),
#include <qtextcodec.h>
qApp->setDefaultCodec( QTextCodec::codecForName("GBK") );
QLabel *label = new QLabel( tr("中文标签") );
QString str;
str = QString::fromLocal8Bit(".....");
QLabel tLabel(str, 0);
53. 去除标题栏和边框
:QWidget(parent,
Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder)
54.修改程序主窗口标题
setWindowTitle(QString &); //Qt 4
55. 给Qt应用程序加图标
1,准备ico图标, 比如myappico.ico
2,建个rc文本文件名, 比如myrc.rc
在里面加入IDI_ICON1 ICON DISCARDABLE "myappico.ico"
3,在pro工程文件中加入
setWindowIcon(QIcon("myappico.ico")); //一般应该加到class::public QWdiget中.因为
setWindowIcon()是QWidget public function
在QT程序中加入OpenGL支持很简单,只需要在Kdevelop连接的库中加入“-lGL -lGLU”即可,如果需要glut支持,还可以加入“-lglut”。具体操作是在kdevelop集成编译环境中按下”F7”,在弹出的对话框中选择 “Linker”一项,在输入栏输入你想添加的库即可,写法与gcc/g++一致。
一般在类QGLWidget中使用OpenGL,调用此类的头文件是qgl.h,具体写法请参考qt例程中的gear,texture,box等程序(在RedHat7.2中,它们在/usr/lib/qt-2.3.1/doc/examples下).
57. 检验linux/Unix环境是否支持OpenGL.
Qt中的QGLFormat类可以帮助我们轻易检验系统是否支持OpenGL,载入头文件(#include <qgl.h>)后,我们就可以使用QGLFormat的静态函数hasOpenGL来检验,具体写法如下例:
if (!QGLFormat::hasOpenGL()) //Test OpenGL Environment
{
qWarning( "This system has no OpenGL support. Exiting." );//弹出警告对话框
return -1;
}
58.获得屏幕的高和宽.
一般我们可以通过QT的Qapplication类来获得系统的一些信息,载入头文件(#include <qapplication.h>)我们就可以调用它,下例是使主程序充满整个屏幕的代码:
Gui_MainForm gui_mainform;
a.setMainWidget( &gui_mainform );
gui_mainform.resize( QApplication::desktop()->width(), QApplication::desktop()->height() ); gui_mainform.show();
59.关于信号和槽.
信号和槽机制是QT库的重要特性,可以说不了解它就不了解Qt.此机制能在各类间建立方便快捷的通信联系,只要类中加载了Q_OBJECT宏并用 connect函数正确连接在一起即可,具体写法这里就不赘述了.但本人在使用过程中发现使用此机制容易破坏程序的结构性和封装性,速度也不是很让人满 意,尤其是在跨多类调用时.鄙人的一孔之见是: 信号和槽机制不可不用,但不可多用.
60.QT程序中界面的设计.
尽管Kdevelop是一个优秀的集成编译环境,可遗憾的是它不是一个可视化的编译环境,好在有Qdesigner来帮助我们完成界面设计,该程序的使用 很简单,使用过VB,VC和Delphi的程序员能很快其操作方式,操作完成后存盘会生成一个扩展名为”ui”的文件,你接下来的任务就是把它解析成 cpp和h文件,假设文件名为myform.ui,解析方法如下:
$uic myform.ui –I myform.h –o myform..cpp //这句生成cpp文件
$uic myform.ui –o myform.h //这句生成h文件.
61.由pro文件生成Makefile.
对于Linux/Unix程序员来说编写Makefile文件是一项令人烦恼的任务,而qt程序员就没有这样的烦恼,一句$qmake –o Makefile myprogram.pro就可以轻松愉快的完成任务,而pro文件的编写也很容易,其核心是h和cpp文件的简单列表.具体写法请参考一下qt自带的样 例和教程吧(在RedHat7.2中,它在/usr/lib/qt-2.3.1/doc/examples下),相对Makefile文件简直没有什么难 度.
62.主组件的选择.
一般我们在编程是使用继承Qwidget类的类作为主组件,这当然未可厚非.但在制作典型的多文档和单文档程序时我们有更好的选择— QmainWindow类,它可以方便的管理其中的菜单工具条主窗口和状态条等,在窗体几何属性发生变化时也能完美的实现内部组件缩放,这比用传统的几何 布局类来管理要方便得多,而且不用写什么代码.关于它的具体细节请查阅QT的帮组文档,这里就不赘述了.
63.菜单项中加入Checked项.
在QT中,菜单项中加入Checked有点麻烦,具体写法如下:
1> 定义int型成员变量,并在创建菜单项中写:
displayGeometryMode=new QPopupMenu(this); //这里创建弹出菜单组displayGeometryMode
m_menuIDWire=displayGeometryMode->insertItem("Wire",this,SLOT(slt_Change2WireMode()));.//创建弹出菜单子项
displayGeometryMode->setItemChecked(m_ menuIDWire,true);//设定此子项为选择状态
2> 再在槽函数中写:
displayGeometryMode->setItemChecked(m_menuIDWire,false);//这里设定此子项为非选择状态
64.截获程序即将退出的信号.
有些时候我们需要在程序即将退出时进行一些处理,如保存文件等等.如何截获程序退出的信号呢?还是要用到Qapplication类的aboutToQuit()信号,程序中可以这样写:
connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(Slot_SaveActions()));
在槽函数Slot_SaveActions()就可以进行相关处理了,注意,使用全局对象qApp需要加载头文件(#include <qapplication.h>).
65.弹出标准文件对话框.
在程序中弹出文件对话框是很容易处理的,举例如下:
QString filter="Txt files(*.txt)/n" //设置文件过滤,缺省显示文本文件
"All files(*)" ; //可选择显示所有文件
QString Filepathname=QFileDialog::getOpenFileName(" ",filter,this);//弹出对话框,这句需要加载头文件(#include < qfiledialog.h >)
66.将当前日期时间转化为标准Qstring.
QDateTime currentdatetime =QDateTime::currentDateTime();//需要加载头文件(#include < qdatetime.h >)
QString strDateTime=currentdatetime.toString();
67.设置定时器
所有Qobject的子类在设置定时器时都不必加载一个Qtimer对象,因为这样造成了资源浪费且需要书写多余的函数,很不方便.最好的办法是重载timerEvent函数,具体写法如下:
class Gui_DlgViewCtrlDatum : public QDialog
{
Q_OBJECT
public:
Gui_DlgViewCtrlDatum( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
~Gui_DlgViewCtrlDatum();
protected:
void timerEvent( QTimerEvent * );
};
void Gui_DlgViewCtrlDatum::timerEvent( QTimerEvent *e )
{
//statements
}
再在Gui_DlgViewCtrlDatum的构造函数中设置时间间隔:
startTimer(50);//单位为毫秒
这样,每隔50毫秒,函数timerEvent便会被调用一次.
68.最方便的几何布局类QGridLayout
在QT的几何布局类中,笔者认为QgridLayout使用最为方便,举例如下:
QGridLayout* layout=new QGridLayout(this,10,10);//创建一个10*10的QgridLayout实例
layout->addMultiCellWidget(gui_dlgslab_glwnd,1,8,0,7);//将OpenGL窗口固定在QgridLayout中的(1,0)单元格到(8,7)单元格中
layout->addMultiCellWidget(Slider1,0,9,8,8);//将一个slider固定在单元格(0,8)到(9,8)中
layout->addWidget(UpLimitLbl,1,9);//将一个label(UpLimitLbl)固定在单元格(1,9)中
这样,无论窗体大小如何改变,它们的布局方式都不会发生改变,这比反复使用QvboxLayout和QhboxLayout要方便快捷许多.
注:使用几何布局类需要调用头文件(#include <qlayout.h>)
69.字符串类Qstring和字符串链表类QstringList.
Qstring是Qt中标准字符串类,下面列出它的一些常用函数:
toInt():将字符串转化成int类型.
ToFloat():将字符串转化成float类型.
ToDouble():将字符串转化成double类型.
Left(n):从左起取n个字符
Right(n):从右起取n个字符
SetNum(n):将实数n(包括int,float,double等)转化为Qsting型.
QstringList是大家比较少使用的类,它可以看成Qstring组成的链表(QT中标准链表类Qlist的函数对它都适用,它的单个节点是Qstring类型的),特别适合与处理文本,下面一段代码就可见其方便快捷:
Qstring strtmp=”abc|b|c|d”;
QstringList strlsttmp;
Strlsttmp =QStringList::split("|", strtmp);
For(unsigned int I=0;I< Strlsttmp.count();I++)
{
cout<< Strlsttmp.at(I);
}
结果输出为:abc b c d,也就是说,通过一个函数split,一行文本就被符号”|”自动分割成了单个字符串.这在文本处理时特别省力.(请参考c语言大全第四版中用”strtok”函数分割文本的例程,将双方比较一下)
70. QGLWidget类如何加入鼠标支持.
QGLWidget类加入鼠标支持需要重载以下函数:
void mousePressEvent(QMouseEvent*);
void mouseMoveEvent(QMouseEvent*);
void mouseReleaseEvent(QMouseEvent*);
请具体看一个实例:
class Gui_WgtMain_GLWnd : public QGLWidget {
Q_OBJECT
public:
Gui_WgtMain_GLWnd(QWidget *parent=0, const char *name=0);
~Gui_WgtMain_GLWnd();
protected:
void initializeGL();
void paintGL();
void resizeGL( int w, int h );
void mousePressEvent(QMouseEvent*);
void mouseMoveEvent(QMouseEvent*);
void mouseReleaseEvent(QMouseEvent*);
private:
int m_nCnt;
};
void Gui_WgtMain_GLWnd::mousePressEvent(QMouseEvent* e)
{
//statements
}
void Gui_WgtMain_GLWnd:: mouseMoveEvent (QMouseEvent* e)
{
//statements
}
void Gui_WgtMain_GLWnd:: mouseReleaseEvent (QMouseEvent* e)
{
//statements
}
其中, e->x();e->y();可以获得鼠标的位置, e->button()可以取得鼠标按键的状态(左中右键以及ctrl,alt,shift等组合键),灵活使用他们就可以在用鼠标操作OpenGL画面了.
71.由ui文件生成.h和.cpp文件
生成.cpp文件
$uic myform.ui -i myform.h -o myform.cpp
生成.h文件
$uic myform.ui -o myform.h