检验和(checksum),在数据处理和数据通信领域中,用于校验目的地一组数据项的和。它通常是以十六进制为数制表示的形式。如果校验和的数值超过十六进制的FF,也就是255. 就要求其补码作为校验和。通常用来在通信中,尤其是远距离通信中保证数据的完整性和准确性。
这些数据项可以是数字或在计算检验的过程中看作数字的其它字符串。校验和(checksum)是指传输位数的累加,当传输结束时,接收者可以根据这个数值判断是否接到了所有的数据。如果数值匹配,那么说明传送已经完成。TCP和UDP传输层都提供了一个校验和与验证总数是否匹配的服务功能。
#include #include #include #include #include #include 窜口头文件 窜口头文件 核心头文件 等待头文件 QT对话框类 #include //*************** class groupbox 显示虚线分割线 QwtPlot是用来绘制二维图像的widget,在它的画板上可以无的显示绘画组件。绘画组件可以是曲线(QwtPlotCurve)、标记 (QwtPlotMark)、网格(QwtPlotGrid)、或者其它从QwtPlotItem继承的组件、QwtScaleDraw可以用来绘制线性或对数尺度,一个标尺可以指定位置、对齐方式、长度等。标签可使用setLabelRotation()和setLabelAlignment()来设置旋转和对齐方式。通过 QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s)设置的标尺QwtScaleDiv对象,标尺可以使用QwtAbstractScaleDraw::draw()函数来绘制 QT中主界面实现N*N窗口,每个窗口可以实现分割,可以多个窗口拼接成一个窗口。每个窗口可以显示不同东西 主窗口是MainWindow,然后在MainWindow里面添加需要的子窗口,子窗口用QWidget就可以了,然后每个子窗口你就设置到相应的位置。 MainWindow是主窗口,然后要添加子窗口Class A(QWidget),Class B(QWidget),那么就在MainWindow初始化里面new A(this),new B(this) 同理,子窗口分割意思也是一样的,那就需要在A里面分割,那么就需要在A的初始化里new自己需要的窗口就行了。 QT如何分割界面窗口:把窗口分成两部分,左边用一个tree显示数据库的目录,主窗口用table显示数据库中数据,上面是菜单栏和工具栏。 先建一个QMainWindow菜单栏和工具栏就有了,tree和table可以用QTreeView和QTableView,左右分栏直接在QMainWindow中添加布局就行了,可以用水平布局或者用期水平布局。 QT splitter分割窗口后如何按比例显示,即分割后的窗口大小设置方法 控件有水平伸展和垂直伸展的属性(sizePolicy里),比如用splitter分割了上下2个GroupBox,2个垂直策略都是在Expanding(扩展),第一个垂直伸展的值是2,第二个垂直伸展的值是1,那么出来的效果就是上下2个Group占界面高度为2:1,即2/3和1/3,伸展设的值都是比例,不是大小。 QT如何给一个窗口设置标题 调用窗体类的setWindowTitle()函数就可以对窗体设置标题 窗体类继承于QWidget类,其setWindowTitle函数原型, Void QWidget::setWindowTitle(const QSgtring & title);//title是标题内容字符串; MyWidget setWindow Title(QString(“我的窗体标题”)); QT中如何隐藏窗口标题栏 setwindowFlags(QT::FramelessWindowHint); QT下如何实现鼠标移动触发窗口显示 重写moveEvent虚函数 QT中怎么在一个窗口中获得另一个窗口的指针? 问题描述:我用Widget作为母窗口,在其主函数中用信号槽建立了一个Dialog的窗口,那么这个Dialog窗口是不是Widget的子窗口呢?如果是的话,我想通过信号槽在 Dialog中调用Widget中的数据,这样的话Widget母窗口应该是SIGNAL信号,在信号槽函数中需要使用它的指针,我在建立Dialog窗口的时候用new Dialog(this)将主函数指针传递给子函数,在子函数体的信号槽中槽函数写的parentWidget()获得母函数指针,但是没有成功, Dialog是不是Widge的子窗口,要看构造函数是否制定了如this这样的父窗口,或者setParent(),如果是的话,parentWidget()可以获得QWidget的指针,但是对象(WIdget)需要做一个类型的强制转化, 解决办法:在创建子窗口的时候没有把父窗口指针this传过去 QT中如何给主窗口添加滚动条 eventTableSlider = new QScrollBar(QT::Vertical, this); eventTableSlider->setRange(0, 99); eventTableSlider->setPageStep(20); eventTableSlider->setSingleStep(1); ui.tableWidget_4->setVerticalScrollBar(eventTableSlider); 注意要包含对应的头文件 QT多界面问题 问题描述:在一个界面中,有2个按钮A和B,按下A按钮,在主界面上某个位置显示AA对话框;按下B按钮,先销毁AA对话框,再在同一位置显示BB对话框,再按A按钮 A和B的槽函数都要放到主界面中处理,AA对话框与BB对话框做成主界面的成员变量,非模态画面 QT界面优化问题 刚做完初始化版本是像这样的,现在想把按钮都变成自定义的找来的圆形图案,应该怎么做? 自定义QpushButton的形状、背景色用setStyileSheet()这个函数。设置按钮为自定义的图标使用setlcon()这个函数。setStyleSheet()的语法可以看一下帮助文件,如果说设置为圆角按钮的话可以用button->setStyleSheet(“border-radius:20px”); 设置图标可以用: Button->setlcon(QIcon(“./images/palarm.png”)); Button->setIconSize(QSize(60,60)); QT界面切换 首先你得使用QSplitter分割线,吧主界面分成两半, 左边一半,你可以使用QListWidget,然后里面的项用图标显示;也可以使用QToolBox类 右边一半,你可以使用QStackedWidget类,将对应的窗口定义为一个个的QWidget,然后使用QStackedWidget的addWidget方法加进来,点击左边按钮项时,使用QStackedWidget的setCurrentlndex设置当前需要显示的窗口的索引号。 QT做界面的问题 问题描述:上面这个界面可以用textedit实现吗,怎么实现换行和上下对齐,要用那些类,我想把单片机的数据在这个界面上实现实时显示 这个用QTableList比较方便,TextEidt 的话,使用ui->taxtEdit->append(“...”);或者\\n可自动换行,对齐用\把你可以用转义序列把字符串排好,然后setText()显示 做表格的是在控件QTable里面 QT中如何使用QDial控件 Void Dialog::on_dia_sliderMoved(int position) { Ui->plainTextEdit->setFont(QFont(“Times”, position)); } QT中ui->的作用是什么? .ui通常是用QT设计师设计出来的界面文件的后缀,ui通常指向用这个ui文件里面的类创建的实例,就是说通常情况下ui是一个指向这个界面类的指针,而ui->一般就是用来 访问这个界面类里面的控件。 例如:你的ui文件里有一个叫btn的QPushButton,你就可以这样来访问这个按钮:ui->btn QT ui界面调用问题 问题描述: 已经使用一个界面文件mainwindow.ui作为界面,mainwindow.cpp控件该ui界面的数据,现在需要在新建一个ui文件作为对话框,主界面内数据需要传递参数给该对话框,请问如何是否只是需要新建ui对话框文件,还是说相应的类文件也要建立?再问如何传参数给对话框,并调用该对话框ui显示? 最直观的方法如楼上说的新建一个对话框ui类,利用Qt Creator的向导功能很容易实现。在主界面中显示该对话框,即在mainwindow.cpp的某个方法中调用对话框的显示方法,传递参数可以修改对话框的构造函数,或者在显示对话框之前调用其他的函数,将参数传递进对话框。 QT C++编写多窗口之间的跳转在一个窗口中可以变化很多UI界面 问题描述:点击“欢迎”按钮会显示一个界面,点击“编辑”又会显示一个界面 这个可以用QTabWidget实现。这是QT的标签类,构建mainwindow后,用一个qtabwidget作为centralwidget,然后再构建每一个页面,分别用QTabWidget::addTab(部件,图标,标题)添加到作为centralwidget的qtabwidget中,然后就可以利用标签前后翻页了,如果你想做成像qt creator一样的界面,你可以用QTabWidget::setTabPosition设置标签栏的位置,事例在附件中(仅有mainwindow的构造函数部分) MainWindow::MainWindow(QWidget *parent) { QLabel* pWelcome = new QLabel(\"Welcome\QTextEdit* pEdit = new QTextEdit(this); QTreeWidget* pDesign = new QTreeWidget(this); QListWidget* pDebug = new QListWidget(this); QTableWidget* pProject = new QTableWidget(this); QCalendarWidget* pAnalyze = new QCalendarWidget(this); QWebView* pHelp = new QWebView(this); QTabWidget* pTab = new QTabWidget(this); pTab->setTabShape(QTabWidget::Triangular); pTab->setTabPosition(QTabWidget::West); pTab->addTab(pWelcome, QIcon(), \"Welcome\"); pTab->addTab(pEdit, QIcon(), \"Edit\"); pTab->addTab(pDesign, QIcon(), \"Design\"); : QMainWindow(parent) pTab->addTab(pDebug, QIcon(), \"Debug\"); pTab->addTab(pProject, QIcon(), \"Project\"); pTab->addTab(pAnalyze, QIcon(), \"Analyze\"); pTab->addTab(pHelp, QIcon(), \"Help\"); QMainWindow::setCentralWidget(pTab); { } pEdit->setText(\"Type here ...\"); pDesign->setHeaderHidden(true); { } QTreeWidgetItem* pItem1 = new QTreeWidgetItem(pDesign); pItem1->setText(0, \"Item1\"); QTreeWidgetItem* pItem2 = new QTreeWidgetItem(pItem1); pItem2->setText(0, \"Item2\"); QTreeWidgetItem* pItem3 = new QTreeWidgetItem(pDesign); pItem3->setText(0, \"Item3\"); QFont ftFont = pWelcome->font(); ftFont.setPointSize(); pWelcome->setFont(ftFont); } pDebug->addItem(\"Item1\"); pDebug->addItem(\"Item2\"); pDebug->addItem(\"Item3\"); pProject->setRowCount(100); pProject->setColumnCount(100); pProject->setItem(0, 0, new QTableWidgetItem(\"Item1\")); pProject->setItem(0, 1, new QTableWidgetItem(\"Item2\")); pProject->setItem(1, 0, new QTableWidgetItem(\"Item3\")); pProject->setItem(1, 1, new QTableWidgetItem(\"Item4\")); pAnalyze->setGridVisible(true); pAnalyze->showToday(); pHelp->load(QUrl(\"http://bing.com\")); QT如何实现标签页? 用QMdiArea可实现标签页视图:setViewMode(QMdiArea::TabbedView); QT界面中文字体及大小设置 在QT中经常会涉及到界面字体大小的设置,默认字体一般都比较小,特别是在移植到开发板上进行显示一般都要放大字体,因为开发板上液晶显示屏分辨率都是非常小的,跟电脑上显示有很大的差别。 一种整体界面字体设置的方法: 在main函数中添加程序: QFont font = app.font(); font.setPointSize(16); app.setFont(font); 在QT/embedded中显示中文,可以采用如下运行方式: ./wireless -qws -font unifont 改变QT中QLineEdit中显示内容的大小: QLineEdit *lineEdit = new QLineEdit(); lineEdit->setStylesheet(“font-size:16px”); 也可以在主函数中添加语句: qApp->setStyoleSheet(“QLineEdit{font:16px;}”); QT中checkbox不显示复选框,用变换背景色来表示选中状态 protectedvoidPage_Load(objectsender,EventArgs.e) { CheckBoxchk=newCheckBox(); chk.Text=\"testall\";//这里可以换成数据库的内容 chk.CheckedChanged+=newEventHandler(chk_CheckedChanged); chk.AutoPostBack=true; Page.Form.Controls.Add(chk); for(inti=0;i<10;i++) { CheckBoxchk2=newCheckBox(); chk2.Text=\"test\"+i.ToString();//这里可以换成数据库的内容 chk2.Checked=(i%3==0); Page.Form.Controls.Add(chk2); } } voidchk_CheckedChanged(objectsender,EventArgse) { CheckBoxall=senderasCheckBox; foreach(ControlctlinPage.Form.Controls) { if(ctlisCheckBox) { CheckBoxchk=ctlasCheckBox; chk.Checked=all.Checked; } } } 打对打错的方法 输入一个alt+41420 ×alt+41409输入一个R,选中R再将字体换为Wingdings2得到 关于串口通信: bool QSerialPortInfo::isNull() const Returns whether this QSerialPortInfo object holds a serial port definition. 返回这是否QSerialPortInfo对象拥有一个串行端口的定义。 bool QSerialPortInfo::isBusy() const 返回true,如果串口很忙;否则返回假。 QString QSerialPortInfo::manufacturer() const 若可用,串口返回制造商字符串,否则返回空字符串 QString QSerialPortInfo::portName() const 返回串口名称 QString QSerialPortInfo::serialNumber() const 返回序列号串口的字符串,如果可用,否则返回空字符串。 quint16 QSerialPortInfo::productIdentifier() const 返回串口的16位产品编号,如果可用,否则返回0。 QList void QSerialPortInfo::swap(QSerialPortInfo &other) 用这个QSerialPortInfo互换QSerialPortInfo其他。该操作是非常之快,从不失败 QString QSerialPortInfo::systemLocation() const 返回系统串行端口的位置。 quint16 QSerialPortInfo::vendorIdentifier() const 返回串口的16位的供应商数量,如果可用,否则返回0。 QSerialPortInfo & QSerialPortInfo::operator=(constQSerialPortInfo & other) 设置QSerialPortInfo对象等于其他。 QSerialPortInfo::QSerialPortInfo() 构造一个空QSerialPortInfo对象。 QSerialPortInfo::QSerialPortInfo(const QSerialPort& port) 构造一个从串口QSerialPortInfo对象。 QSerialPortInfo::QSerialPortInfo(const QString &name) 构造一个QSerialPortInfo对象从串行端口的名字 QSerialPortInfo::QSerialPortInfo(constQSerialPortInfo & other) 结构的一个副本。 QList QString QSerialPortInfo::description() const 返回的字符串描述串行端口,如果可用,否则返回空字符串 bool QSerialPortInfo::hasVendorIdentifier() const 返回true,如果有一个有效的16位供应商编号存在;否则返回false。 bool QSerialPortInfo::hasProductIdentifier() const 返回true,如果有一个有效的16位产品数量存在;否则返回false。 QT中信号 信号的声明是在头文件中进行的,QT的signals关键字指出进入了信号声明区,随后即可声明自己的信号。例如,下面定义了三个信号: Signals: Void mySignal(); Void mySignal(int x); Void mySignalParam(int x, int y); 在上面的定义中,signals是QT的关键字,而非C/C++的关键字。接下来的一行void mySignal()定义了信号mySignal。这个信号没有携带参数,接下来的一行void mySignal(int x)定义了才重名信号mySignal,不过他携带一个整形参数,这有点类似于C++中的虚函数,从形式上讲信号的声明和普通的C++函数是相同的,不过信号却没有函数体定义,另外,信号的返回类型都是void ,不要指望能从信号返回一个什么有用信息。 信号有moc自动产生,他么不应该在.cpp文件中实现。 槽: 槽是普通的C++成员,能被正常调用,他么唯一的特别性就是非常多信号能和其相关联。当和其关联的信号发射是,这个槽就会被调用。槽能有参数,但槽的参数不能有缺省值。 既然槽是普通的成员函数,因此和其他的函数相同,他们也有存取权限。槽的存取权限决定了谁能够和其相关联。同普通的C++成员函数相同,槽函数也分为三种类型,即:public slots、private slots和protected slots。 Public slots:在这个区内声明的槽意味着所有对象都可将信号和之相连接。这对于组件编程非常有用,你能创建彼此互不了解的对象,将他们的信号和槽进行连接以便信息能够正确的传递。 protected slots:在这个区内声明的槽意味着当前类及其子类能够将信号和之相连接。这适用于那些槽,他们是类实现的一部分,不过其界面接口却面向外部。 Private slots:在这个区内声明的槽意味着只有类自己能够将信号和之相连接。这适用于纤细非常紧密的类。 槽也是能够声明为虚函数,这也是非常有用的。 槽的声明也是在头文件中进行的,例如: Public slots: Void mySlot(); Void mySlot(int x); Void mySignalParam(int x, int y); 信号和槽的关联: 通过调用QObject对象的connect函数来将某个对象的信号和另外一个对象的槽函数相关联,这样当发射者信号发射信号时,接收者的槽函数将被调用。该函数的定义如下: Bool QObject::connect (const QObject *sender, const char *signal, Const QObject *receiver, const char *member) [static] 这个函数的作用就是将发射者sender对象中的信号signal和接收者receiver 中的member槽函数联系起来。当指定信号signal时必须使用QT的宏SIGNAL(),当指定槽函数时必须使用宏SLOT()。如果发射者和接收者属于同一个对象的话,那么在connect调用中接收者参数能省略。 例如,下面定义了两个对象:标签对象label和滚动条对象scroll,并将valueChanged()信号和标签对象的setNum()相关联,另外信号还携带了一个整形参数,这样标签总是显示滚动条所处位置的值。 QLabel *label = new QLabel; QScrollBar *scroll = new QScrollBar; QObject::connect( scroll, SIGNAL(valueChanged(int)), label, SLOT(setNum(int)) ); 一个信号甚至能够和另一个信号相关联,看下面的例子: class MyWidget : public QWidget { public: MyWidget(); „ signals: void aSignal(); „ private: „ QPushButton *aButton; }; MyWidget::MyWidget() { aButton = new QPushButton( this ); connect( aButton, SIGNAL(clicked()), SIGNAL(aSignal()) ); } 在上面的构造函数中,MyWidget创建了一个私有的按钮aButton,按钮的单击事件产生的信号clicked()和另外一个信号aSignal() 进行了关联。这样一来,当信号clicked()被发射时,信号aSignal()也接着被发射。当然,你也能直接将单击事件和某个私有的槽函数相关联,然后在槽中发射aSignal()信号,这样的话似乎有点多余。 当信号和槽没有必要继续保持关联时,我们能使用disconnect函数来断开连接。其定义如下: bool QObject::disconnect ( const QObject * sender, const char * signal, const Object * receiver, const char * member ) [static] 这个函数断研发射者中的信号和接收者中的槽函数之间的关联。 有三种情况必须使用disconnect()函数: 断开和某个对象相关联的所有对象。这似乎有点不可理解,事实上,当我们在某个对象中定义了一个或多个信号,这些信号和另外若干个对象中的槽相关联,如果我们要切断这些关联的话,就能利用这个方法,非常之简洁。 disconnect( myObject, 0, 0, 0 ) 或 myObject->disconnect() 断开和某个特定信号的所有关联。 disconnect( myObject, SIGNAL(mySignal()), 0, 0 ) 或 myObject->disconnect( SIGNAL(mySignal()) ) 断开两个对象之间的关联。 disconnect( myObject, 0, myReceiver, 0 ) 或 myObject->disconnect( myReceiver ) 在disconnect函数中0能用作一个通配符,分别表示所有信号、所有接收对象、接收对象中的所有槽函数。不过发射者sender不能为0,其他三个参数的值能等于0。 使用槽或信号函数时应注意: 1. 信号和槽的效率是非常高的,不过同真正的回调函数比较起来,由于增加了灵活性,因此在熟读上 还是有所损失,当然这种损失相对来说是比较小的,通过在一台i586-133的机器上测试是10微秒(运行Linux),可见这种机制所提供的简洁性、灵活性还是值得的。但是如果我们要追求高效率的话,比如在实时系统中就要尽可能的少用这种机制。 2. 信号和槽机制和普通函数的调用相同,如果使用不当的话,在程式执行时也有可能产生死循环。因 此,在定义槽函数是一定要注意避免简介形成无限循环,即在槽中再次发射所接收到的同样信号。例如:在前面给出的例子中如果再myslot()槽函数中加上语句emit mysignal()即可形成死循环。 3. 如果一个信号和多个槽相联系的话,那么,当这个信号飞发射时,和之相关的槽被集火的顺序是随 机的。 4. 宏定义不能用在signal和slot的参数中。 5. 构造函数不能用在signals或者slots声明区域内。将一个构造函数放在signals或slots区内有点不 可理解,无论怎么,都不能将他们放在private slots、protected slots或public slots区内。下面的用法是不合语法需求的: class SomeClass : public QObject { Q_OBJECT public slots: SomeClass( QObject *parent, const char *name ) : QObject( parent, name ) {} // 在槽声明区内声明构造函数不合语法 [„] }; 6、函数指针不能作为信号或槽的参数。 例如,下面的例子中将void (*applyFunction)(QList*, void*)作为参数是不合语法的: class someClass : public QObject { Q_OBJECT [„] public slots: void apply(void (*applyFunction)(QList*, void*), char*); // 不合语法 }; 你能采用下面的方法绕过这个: typedef void (*ApplyFunctionType)(QList*, void*); class someClass : public QObject { Q_OBJECT [„] public slots: void apply( ApplyFunctionType, char *); }; 1. 信号和槽不能有缺省参数 既然signal->slot绑定是发生在运行时刻,那么,从概念上讲使用缺省参数是困难的。下面的用法是不合理的: class SomeClass : public QObject { Q_OBJECT public slots: void someSlot(int x=100); // 将x的缺省值定义成100,在槽函数声明中使用是错误的 }; 8.信号和槽也不能携带模板类参数。 如果将信号、槽声明为模板类参数的话,即使moc工具不报告错误,也不可能得到预期的结果。例如,下面的例子中当信号发射时,槽函数不会被正确调用: [„] public slots: void MyWidget::setLocation (pair location); [„] public signals: void MyObject::moved (pair location); 不过,你能使用typedef语句来绕过这个。如下所示: typedef pair IntPair; [„] public slots: void MyWidget::setLocation (IntPair location); [„] public signals: void MyObject::moved (IntPair location); 这样使用的话,你就能得到正确的结果。 9.嵌套的类不能位于信号或槽区域内,也不能有信号或槽。 例如,下面的例子中,在class B中声明槽b()是不合语法的,在信号区内声明槽b()也是不合语法的。 class A { Q_OBJECT public: class B { public slots: // 在嵌套类中声明槽不合语法 void b(); [„.] }; signals: class B { // 在信号区内声明嵌套类不合语法 void b(); [„.] }: }; 10.友元声明不能位于信号或槽声明区内。相反,他们应该在普通C++的private、protected或public区内进行声明。下面的例子是不合语法规范的: class someClass : public QObject { Q_OBJECT [„] signals: //信号定义区 friend class ClassTemplate; // 此处定义不合语法 QTextStream和QDataStream的区别 QTextStream和QDataStream都是面向数据流的,都适用于QIODevice,但是他们的侧重点不同。可以这么说,QTextStream能做的事情QDataStream都能做。 QTextStream侧重于向QIODevice文本读写,这里所说的文本指的是普通的简单的QChar,QString,QLatin1Char,int等等之内的,和C语言中写文件或者网络传输的时候,先将内容填充到一个buffer,进行操作有点类似,属于普通的轻量级的流操作类。 //下面代码就是写文件操作 QFiledata(\"output.txt\"); if(data.open(QFile::WriteOnly|QFile::Truncate)) { QTextStreamout(&data); out<<\"Result:\"< QDataStream则是侧重于数据格式和类型。QDataStream数据流不仅可以操作QTextStream所能处理的普通文本,而且可以对特定格式的类型数据进行完美的输入与输出。 熟悉Linux C开发的程序员都应该知道,通过socket传输text文本数据比较容易,如果我们想通过socket传输特定的数据结构而且跨平台以及CUP进行操作和解析就比较麻烦。比如对于一个点的坐标,幺妹传输一个结构体,让接收端进行解析,但是可能对于不同的平台以及不同的内存分配方式的CPU来说,解析的结果不一定是我们预期的,可是实现,但是会比较麻烦。 QDataSream就可以轻松的做到这一点,QDataSream将数据序列化。不仅可以读写 text,而且还好可以读写一个特定数据类型,比如QPoint QFont,几乎QT支持的所有类型都可以使用QDataSream进行操作。 一下以读写QPoint为例: QPointpos(8,6) QPointtmp; QByteArraydatagram; QDataStreamout(&datagram,QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_3); out< QDataStream是根据类型以及输出输入顺序来决定输出数据,列举下面的例子来说明问题: QFilefile(\"file.dat\"); file.open(QIODevice::WriteOnly); QDataStreamout(&file);//wewillserializethedataintothefile out< QFilefile(\"file.dat\"); file.open(QIODevice::ReadOnly); QDataStreamin(&file);//readthedataserializedfromthefile QStringstr; qint32a; in>>atr>>a;//extract\"theanseweris\"and42 串口通信 异步传输:是指一次传输一个字符(5~8位)的数据。每个字符用一个韦始位引 导,用一个停止位结束。这样就能是接收方分析出发送方式的数据。但容易发生计时漂移。 异步通信中两个重要的指标:字符帧格式和波特率。数据通常以字符或者字节为单位组成字符帧传送。字符帧由发送端逐帧发送,通过传输线被接收设备逐帧接收。发送端和接收端可以由鸽子的时钟来控制数据的发送和接收,这两个时钟源彼此,互补同步。接收端检测到传输线上发送过来的低电平逻辑“0”(即字符帧起始位)时,确定发送端已开始发送数据,每当接收端收到字符帧中的停止位时,就知道一帧字符已经发送完毕。 同步传输:采用面向字符或面向位的插入方式,控制所传送的一帧的起始。同步异 步报文传输方式也是如此。 缺点:要求发送时钟和接收时钟要保持严格的同步。 串口参数定义: BaudRateType BaudRate; 波特率设置,我们设置为9600,即程序中用BAUD9600; DataBitsType DataBits; 数据位设置,我们设置为8位数据位,即DATA_8; ParityType Parity; 奇偶校验设置,我们设置为无校验,即PAR_NONE; StopBitsType StopBits; 停止位设置,我们设置为1为停止位,即STOP_1; FlowType FlowControl; 数据流控制设置,我们设置为无数据流控制,即FLOW_OFF; Long Timeout_Millisec; 延时设置,我们设置为延时500ms,即500; 这样便写出以下程序: Struct PortSettings myComSetting = {BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,500}; 我们定义了一个结构体变量myComSetting,并对其进行了初始化 QT写的Win_QextSerialPort串口数量不能超过10个如下修改,愿意几个就几个: QString portleft = port.mid(3,3) //qDebug()<<”port name is:” < Portb=”\\\\\\\\.\\\\”; Portb+=port; } Win_Handle=CreateFileA(portb.toAscii(),GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, dwFlagsAttributes, NULL); QT串口发送十六进制数据接收串口数据并十六进制显示 代码如下: structPortSettingsmyComSetting={BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,10}; //定义一个结构体,用来存放串口各个参数 myCom=newWin_QextSerialPort(ui->comboBox->currentText(), myComSetting,QextSerialBase::EventDriven); //定义串口对象,并传递参数,在构造函数里对其进行初始化 myCom->open(QIODevice::ReadWrite); myCom->setBaudRate(BAUD115200); myCom->setDataBits(DATA_8); myCom->setParity(PAR_NONE); myCom->setStopBits(STOP_1); myCom->setFlowControl(FLOW_OFF); myCom->setTimeout(10); //以可读写方式打开串口 connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom())); //信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作 //发送十六进制数据 QByteArrayba; for(inti=0;i<256;i++) { ba[i]=i; } myCom->write(ba); //接收串口数据以字符合十六进制数据显示 QByteArraytemp=myCom->readAll(); //读取串口缓冲区的所有数据给临时变量temp ui->textBrowser->insertPlainText(temp); ui->textEdit_2->insertPlainText(temp.toHex()); //将串口的数据显示在窗口的文本浏览器中 串口以十六进制发送数据 voidWidget::String2Hex(QStringstr,QByteArray&senddata) { inthexdata,lowhexdata; inthexdatalen=0; intlen=str.length(); senddata.resize(len/2); charlstr,hstr; for(inti=0;i hstr=str[i].toAscii(); if(hstr=='') { i++; continue; } i++; if(i>=len) { break; } lstr=str[i].toAscii(); hexdata=ConvertHexChar(lstr); if((hexdata==16)||(lowhexdata==16)) break; else hexdata=hexdata*16+lowhexdata; i++; senddata[hexdatalen]=(char)hexdata; hexdatalen++; } senddata.resize(hexdatalen); } charWidget::ConvertHexChar(charch) { if((ch>='0')&&(ch<='9')) returnch-0x30; elseif((ch>='A')&&(ch<='F')) returnch-'A'+10; elseif((ch>='a')&&(ch<='f')) returnch-'a'+10; elsereturn(-1); } 串口接收十六进制 QByteArraytmp; if(highCom->bytesAvailable()>=41) { tmp=highCom->readAll(); QDataStreamout(&tmp,QIODevice::ReadWrite); while(!out.atEnd()) { qint8outChar=0; out>>outChar; QStringstr=QString(\"%1\").arg(outChar&0xFF,2,16,QLatin1Char('0')); strHex+=str; } qDebug()< 读取串口 voidMySerial::readMyCom() { QByteArraytemp; if(myCom->butesAvailable()>=8) { temp=myCom->readAll();//读串口缓冲区数据 } QDataStreamout(&temp,QIODevice::ReadWrite);//将字节数组读入 while(!out.atEnd()) { qint8outChar=0; out>>outChar;//每字节填充一次,直到结束 QStringstr= //十六进制的转换 recBrowser->insertPlainText(str); } recBrowser->inserPlainText(tr(\"\\n\")); QString(\"%1\").arg(outChar&0xFF,2,16,QLatin1Char('0')); } 十六进制转换成十进制 intChangNum(CStringstr,intlength) { charrevstr[16]={0};//根据十六进制字符串的长度,这里注意数组不要越界 intnum[16]={0}; intcount=1; intresult=0; strcpy(revstr,str); for(inti=length-1;i>=0;i--) { if((revstr[i]>='0')&&(revstr[i]<='9')) num[i]=revstr[i]-48;//字符0的ASCii码是48 elseif((revstr[i]>='a')&&(revstr[i]<='f')) num[i]=revstr[i]-'a'+10; elseif((revstr[i]>='A')&&(revstr[i]<='F')) num[i]=revstr[i]-'A'+10; else num[i]=0; result=result+num[i]*count; count=count*16;//十六进制(如果是八进制就在这里乘以8) } returnresult; } intmain() { CStringstr=\"0x11\"; intn=0; n=ChangeNum(str,str.GetLength()); printf(\"%d\\n\",n); return0; } //输出17 //*********************************** QLineEdit是单行文本框 QTextEdit是多行文本框 (1)单行文本框QLineEdit常用的方法和属性 (a)获取和设置文本对齐方式 Qt::Alignment alignment() const void setAlignment(Qt::Alignment flag); (b)获取和设置文件框的内容 QString text() const void setText(const QString &) (c)获取和设置选择的文本 QString selectedText() const void QLineEdit::setSelection(int start, int length) (d)获取和设置echoMode模式 EchoMode echoMode() const void setEchoMode(EchomMode) echoMode模式的值可以是: QLineEdit::Normal 0 Display characters as they are entered. This is the default. QLineEdit::NoEcho 1 Do not display anything. This may be appropriate for passwords where even the length of the password should be kept secret. QLineEdit::Password 2 Display asterisks instead of the characters actually entered. QLineEdit::PasswordEchoOnEdit 3 Display characters as they are entered while editing otherwise display asterisks. (2)多行文本框QTextEdit QTextEdit显示多行文本内容,当文本内容超出控件显示范围时,可以显示水平和垂直滚动条 通过设置acceptRichText属性,QTextEdit不仅可以显示文字,还可以显示HTML文档、图像、表格等元素 示例: (1)设置多行文本框的内容 textEdit->setPlainText(\"12345\\nabcdef\"); (2)获取多行文本框内容 QString str; str = textEdit->toPlainText(); ui->textBrowser->setPlainText(\"\");//这是清空textBrowser 里面所有数据 QT中是用textBrowser使窗口显示最后的信息 问题描述: 使用textBrowser写入数据,当数据超过窗口大小后会自动显示活动条,怎么样使 滚动条随着数据的写入移动,显示窗口的最后获得的信息呢? 在界面设计内,先选定textBrowser,然后右击选择GoToSlot(转道槽),找到如下信号函数textChanged() QTextEdit 单击“OK”(确定),转到如下程序 void MainWindow::on_textBrowser_textChanged() { } QT中单选框和复选框 在Qt GUI中,单选框类是QRadioButton,复选框类是QCheckBox,他们都是QAbstractButton的paishengl (1)单选框 示例: //设置为选择状态 radioButton->setChecked(true); //返回选择状态 bool radio_sel = radioButton->isChecked(); (2)复选框 复选框不同于单选框,他有三种状态:checked、unchecked和Checked Qt::Unchecked 0 The item is unchecked. Qt::PartiallyChecked 1 The item is partially checked. Items in hierarchical models may be partially checked if some, but not all, of their children are checked. Qt::Checked 2 The item is checked. 常用方法和属性如下: //返回选择的状态 Qt::CheckState checkState() const //是否处于PartiallyChecked状态 bool isTristate() const //设置选择的状态,checked或者unchecked void setCheckState( Qt::CheckState state) //设置为PartiallyChecked状态 void setTristate(bool y = true) longQString::toLong(bool*ok,intbase)const Returnsthestringconvertedtoalongusingbasebase,whichis10bydefaultandmustbebetween2and36,or0.Returns0iftheconversionfails. Example: QStringstr=\"FF\"; boolok; longhex=str.toLong(&ok,16);//hex=255,ok==true longdec=str.toLong(&ok,10);//dec==0,ok==false ui->textBrowser->moveCursor(QTextCursor::End);//便可实现显示最后的信息 QT中如何显示和隐藏光标 cursorVisible:bool true显示,false隐藏 //快捷键设置 ui->udpSendButton->setShortcut(tr(\"Alt+F\")); //获取本地IP地址函数 QStringWidget::getIp() { QList if(address.protocol()==QAbstractSocket::IPv4Protocol)//我们使用ipv4地址 { if(address.toString().contains(\"127.0.\")) continue; qDebug()<<\"本机IP:\"< //发送数据的槽函数 voidWidget::send() { autoScroll(); QStringsendStr=ui->sendTextEdit->toPlainText(); QByteArraysendByteArray=sendStr.toAscii(); QMessageBoxbox; if(sendStr.length()==0) { box.setText(tr(\"请输入发送内容\")); box.exec(); } elseif(configFlag) { udpSocket1->writeDatagram(sendByteArray,sendByteArray.length(), *remoteHostAddr,6665); //本地发送信息再信息交互窗口的显示 QDateTimetime; QStringtimeStr=time.currentDateTime().toString(\"yyy-MM-ddhh:mm:ssddd\"); ui->getTextEdit->setTextColor(QColor(\"red\")); ui->getTextEdit->insertPlainText(\"本机1\"+localIpStr+\":\"+timeStr+\"\\n\"); ui->getTextEdit->setTextColor(QColor(\"black\")); ui->getTextEdit->insertPlainText(sendStr+\"\\n\"); ui->sendTextEdit->clear();//点击发送后,发送编辑框内清零 ui->sendTextEdit->setFocus();//焦点停留在发送编辑框 } elseif(!configFlag) { box.setText(\"请您先点击确认按钮!\"); box.exec(); } } 解析: 1、发送数据的实现 QStringsendStr=ui->sendTextEdit->toPlainText(); QByteArraysendByteArray=sendStr.toAscii(); udpSocket1->writeDatagram(sendByteArray,sendByteArray.length(), *remoteHostAddr,6665); 能否正确显示中文就在这一句,必须把QString转变换成QByteArray再发送,接收端有好几种实现方法,但是发送端不这么搞得话,就解析不了中文。 2、本地时间显示 QDateTimetime; QStringtimeStr=time.currentDateTime().toString(\"yyy-MM-ddhh:mm:ssddd\"); 包含一个头文件#include 3、显示文本的时候,ui->getTextEdit->insertPlainText(sendStr+\"\\n\"); ui->sendTextEdit->clear();//点击发送后,发送编辑框内清零 ui->sendTextEdit->setFocus();//焦点停留在发送编辑框 一定要搞成insertPlainText,如果搞成setText,就会把显示窗口搞成只有一句话,这个函数是不销毁以前的内容,插入在以前的文本内容之后的函数。 4、自动滚屏的实现,函数实现如下: voidWidget::autoScroll() { QTextCursorcursor=ui->getTextEdit->textCursor(); cursor.movePosition(QTextCursor::End); ui->getTextEdit->setCursor(cursor); } 四、接收槽的实现 voidWidget::receive() { while(udpSocket1->hasPendingDatagrams()) { QTextCodec*tc=QTextCodec::codecForName(\"UTF-8\");//UTF-8 QDateTimetime; QStringtimeStr=time.currentDateTime().toString(\"yyy-MM-ddhh:mm:ssddd\"); QByteArraydata; data.resize(udpSocket1->pendingDatagramSize()); udpSocket1->readDatagram(data.data(),data.size()); //QStringdataStr=QString::fromUtf8(data.data());这样写也是正确的、 //QStringdataStr=tc->toUnicode(data); ui->getTextEdit->setTextColor(QColor(\"red\")); ui->getTextEdit->insertPlainText(\"远程\"+remoteIpStr+\":\"+timeStr+\"\\n\"); ui->getTextEdit->setTextColor(QColor(\"black\")); ui->getTextEdit->insertPlainText(dataStr+\"\\n\"); autoScroll(); } } 为了显示中文,关键在三句 QTextCodec*tc=QTextCodec::codecForName(\"UTF-8\"); QStringdataStr=tc->toUnicode(data); 如果不写这两句,用这句也可以实现: QStringdataStr=QString::fromUtf8(data.data()); 五、点确定按钮的槽函数 voidWidget::on_configButton_clicked() { remoteIpStr=ui->ipEdit->text(); QStringport=ui->portEdit->text(); qDebug()<<\"远程端ip:\"< if(remoteIpStr.length()==0||port.length()==0||port.tolnt()<1024) { configFlag=false; box.setText(\"请正确设置远程端IP地址和端口号!\"); box.exec(); } else { configFlag=true; box.setText(\"您设置的远程端ip:\"+remoteIpStr+\"端口号:\"+port); box.exec(); } } QT中的中文(国际化) 在QT中,QString使用Unicode的方式来存放字符串,那么在讲乡音到本地化字符串中传递给QString时,一定要 用相应到编码器进行编码,才能得到正确的本地化字符串。 方法: 这里介绍中文的转换方法。 在main()中,设置QApplication的到缺省编码方式。 如: QApplicationapp(argc,argv); app.setDefaultCodec(QTextCodec::codecForName(\"GBK\")); 或者 QTextCodec::setCodecForLocale(QTextCodec::codecForName(\"GBK\")); 然后设置tr的编码方式: QTextCodec::setCodecForTr(QTextCodec::codecForName(\"GBK\")); 具体的使用: constchar*pcszStr=\"中文化\"; QStrings=trUtf8(pcszStr);//1 或者: QStrings=QString::fromLocal8Bit(pcszStr);//2 将鼠标移到最后面: ui->receive_data_textEdit->insertPlainText(com_str); ui->receive_data_textEdit->moveCursor(QTextCursor::End); //QT串口发送十六进制数据接收串口数据并十六进制显示 structPortSettingsmyComSetting={BAUD9600,DATA_8,PAR_NONE,STOP_1,FLOW_OFF,10}; //定义一个结构体,用来存放串口各个参数 myCom=newWin_QextSerialPort(ui.comboBox->currentText(),myComSetting,QextSerialBase::EventDriven); //定义串口对象,并传递参数,在构造函数里对其进行初始化 myCom->open(QIODevice::ReadWrite); myCom->setBaudRate(BAUD115200); myCom->setDataBits(DATA_8); myCom->setParity(PAR_NONE); myCom->setStopBits(STOP_1); myCom->setFlowControl(FLOW_OFF); myCom->setTimeout(10); //以可读写方式打开串口 connect(myCom,SIGNAL(readyRead()),this,SLOT(readCom())); //信号和槽函数关联,当串口缓冲区有数据时,进行读串口操作 //发送十六进制上数据 QByteArrayba; for(inti=0;i<256;i++) { ba[i]=i; } myCom->write(ba); //接收端串口数据已字符和十六进制数据显示 QByteArraytemp=myCom->readALL(); //读取串口缓冲区的所有数据给临时变量temp ui.textBrowser->insertPlainText(temp); ui.textEdit_2->insertPlainText(temp.toHex()); //将串口的数据显示在窗口的文本浏览器中 //将汉字转换为二进制 GBK(\"GB2312\")编码是,一个汉字对应两个字节,UFT8(\"utf-8\")编码时,一个汉字对应3个字节 UFT8编码时的例程: QStringstr=\"中\"; QTextCodec*code=QTextCodec::codecForName(\"utf-8\");//UFT8编码 QByteArrayba=code->fromUnicode(str); for(inti=0;i qDebug()<<\"ba.at(i)\"< intnum=1; QStringstr=QString(\"%1\").arg(num,3,2,QChar('0')); qDebug()< 我要接收的数据比较长,“01 03 24 01 19 …………00 D5 F6”中间省略一大截,为将这些数据接收到一个字符串中,参考QT论坛里的文章,总结如下: 1. QByteArray tmp; 2. if(highCom->bytesAvailable() >= 41) 3. { 4. tmp = highCom->readAll(); 5. QDataStream out(&tmp,QIODevice::ReadWrite); 6. while(!out.atEnd()) 7. { 8. qint8 outChar = 0; 9. out>>outChar; 10. QString str = QString(\"%1\").arg(outChar&0xFF,2,16,QLatin1Char('0')); 11. strHex += str; 12. } 13. qDebug()< 想要做什么处理,就根据实际情况来吧。 当然可以参考下面的代码 //读取串口 void MySerial::readMyCom() { QByteArray temp; if(myCom->bytesAvailable() >= 8) { temp = myCom->readAll(); //读串口缓冲区数据 } QDataStream out(&temp,QIODevice::ReadWrite); //将字节数组读入 while(!out.atEnd()) { qint8 outChar = 0; out>>outChar; //每字节填充一次,直到结束 QString str = QString(\"%1\").arg(outChar&0xFF,2,16,QLatin1Char('0')); //十六进制的转换 recBrowser->insertPlainText(str); } recBrowser->insertPlainText(tr(\"\\n\")); } QT中16进制数据的QByteArray与QString的转换 (1)QByteArraytoQString的第一种方法 /******************************/ QByteArraybyteArrayTempInfo; byteArrayTempInfo.toHex(); /*************** *这种方法比较方便,将AByteArray中的数据一下子就转换成了一个QString */ (2)QByteArraytoQString的第二种方法 /****************/ QByteArraychariTemp=byteArrayTempInfo; unsignedchariTemp=byteArrayTempInfo.at(i); QStringstr=QString::number(iTemp&0xFF,16); if(iTemp<10)str.insert(0,\"0\");//注意 /************* *这种方法不如第一种方法好用,要注意0xff的运用,同时有一个细节,要注意的是当有一些数据小于10的时候要补上0 QT的QString和进制转换 使用QString的setNum就可以了 例子: QString.setNum(num) QString.setNum(num,16) QString.setNum(num,8) QString.setNum(num,2) QString arg; arg.setNum(123456); //丰和 10进制 16进制 8进制 2进制 ui->textBrowser->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//设置垂直滚动条不可见 ui->textBrowser->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//设置水平滚动条不可见 QTextCursor text_cursor(ui->textBrowser->textCursor());//设置光标的位置 text_cursor.movePosition(QTextCursor::End); ui->textBrowser->setTextCursor(text_cursor); 串口如何接收固定字节数: 问题: 下位机不断向上位机发送数据,但是上位机每次只接收固定数目的字符(如200字符),并触发OnComm事件进行处理,该如何实现? 解答: 1、对串口初始化时加入以下两句 m_ctrlComm.SetRThreshold(200);//每当串口接收缓冲区中有多于或等于134个字符时,将引发一个接收数据的onComm事件 m_ctrlComm.SetInputLen(200);//每次从接收缓冲区读取的字符数 2、OnComm()中添加如下代码: If(m_ctrlComm,GetCommEvent()==2 && m_ctrlComm.GetInBufferCount()>=200);//如果接收缓冲区内的字节》=200 { vResponse=m_ctrlComm.GetInput();//获取数据 Char Rec_Data_Array[200]; Memcpy(Rec_Data_Array,(char*)vResponse.parray->pvData,200); }
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- gamedaodao.com 版权所有 湘ICP备2022005869号-6
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务