使用 qt 中的信号/插槽更新 gui [关闭]
Posted
技术标签:
【中文标题】使用 qt 中的信号/插槽更新 gui [关闭]【英文标题】:Update gui using signal/slot in qt [closed] 【发布时间】:2014-10-13 09:05:33 【问题描述】:我正在从套接字获取数据,其中一些参数每秒都在变化。我正在将数据投影到我的 gui 上。我想每秒钟更新一次我的gui。
这是我的 sockettest 类,我正在接收数据,我想在战术小部件中绘制数据。
void socketTest::readyRead()
//QByteArray buffer;
int numRead = 0, numReadTotal = 0;
char buffer[180];
socketTest *a = new socketTest();
tacticalwidget *b = new tacticalwidget();
forever
numRead = socket->read(buffer, 180);
// do whatever with array
numReadTotal += numRead;
memcpy (detailed_track_data, buffer, sizeof(buffer));
//qDebug() << sizeof(buffer);
amp = qToBigEndian(detailed_track_data[0].amplitude);
theta = qToBigEndian(detailed_track_data[0].doa)*0.1;
emit SIGNAL(valuechanged());
connect(a,SIGNAL(valuechanged()), b , SLOT(tacticalwidget::paintEvent()));
int track_state = qToBigEndian(detailed_track_data[0].track_status);
int bit1 = 2^5;
int bit2 = 2^4;
//check hostility level for hostile
if(((track_state) & (bit1)) == 0 && ((track_state) & (bit2)) == 1)
tracktype = 0;// Hostile
else
//check hostility level for unknown
if(((track_state) & (bit1)) == 0 && ((track_state) & (bit2)) == 0)
tracktype = 1;//unknown
else
tracktype = 2;//friendly
if (numRead == 0 && !socket->waitForReadyRead())
break;
TacticalWidget 代码:
void tacticalwidget::paintEvent(QPaintEvent */*e*/)
QSize sz = size();
int radius;
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);
QBrush br;
br.setColor(Qt::black);
painter.setBrush(br);
painter.fillRect(0,0,sz.width(),sz.height(),Qt::SolidPattern);
int centrex = sz.width()/2 ;
int centrey = sz.height()/2;
if (centrex < centrey )
radius = centrex -4;
else
radius = centrey -4;
painter.setPen(QPen(Qt::green,2,Qt::SolidLine,Qt::RoundCap));
painter.drawEllipse(centrex - radius,centrey - radius,2*radius,2*radius);
painter.setPen(QPen(Qt::yellow,2,Qt::SolidLine,Qt::RoundCap));
painter.drawEllipse(centrex - (radius*2/3),centrey-radius*2/3),(radius*4 /3),(radius*4/3));
painter.setPen(QPen(Qt::red,2,Qt::SolidLine,Qt::RoundCap));
painter.drawEllipse(centrex - radius/3,centrey - radius/3,radius*2/3,radius*2/3);
painter.setPen(QPen(Qt::white,2,Qt::SolidLine,Qt::RoundCap));
painter.drawLine(centrex,0,centrex,centrey*2);
painter.drawLine(0,centrey,centrex*2,centrey);
painter.drawText(centrex - radius + 4,centrey,"270");
painter.drawText(centrex,centrey-radius + 4 ,"N");
painter.drawText(centrex,centrey+radius -4,"180");
painter.drawText(centrex + radius -4,centrey,"90");
painter.setPen(QPen(Qt::magenta,2,Qt::SolidLine,Qt::RoundCap));
double theta = 45 * PI /180;
painter.drawLine(centrex,centrey,centrex + radius * sin(theta),centrey - radius * cos(theta));
//Track Display
double amplitudefactor = (theObj.amp + 80)/100;
//int trackNo = i+1;
double pointx,pointy;
int circleradius,innerradius = 0;
switch(theObj.tracktype)
case 0://hostile
circleradius = radius/3;
pointx =centrex + circleradius * sin(theObj.theta) * amplitudefactor;
pointy = centrey - circleradius * cos(theObj.theta)* amplitudefactor;
painter.setPen(QPen(Qt::red,2,Qt::SolidLine,Qt::RoundCap));
painter.drawImage(pointx,pointy,QImage("E:\\bitmaps\\rbitmap.png"));
break;
case 1://unknown
circleradius = radius/3;
innerradius = radius/3;
pointx =centrex + innerradius * sin(theObj.theta) + circleradius * sin(theObj.theta) * amplitudefactor;
pointy = centrey - innerradius * cos(theObj.theta) - circleradius * cos(theObj.theta)* amplitudefactor;
painter.setPen(QPen(Qt::yellow,2,Qt::SolidLine,Qt::RoundCap));
painter.drawImage(pointx,pointy,QImage("E:\\bitmaps\\ybitmap.png"));
break;
case 2: //friendly
circleradius = radius/3;
innerradius = radius *2/3;
pointx =centrex + innerradius * sin(theObj.theta) + circleradius * sin(theObj.theta) * amplitudefactor;
pointy = centrey - innerradius * cos(theObj.theta) - circleradius * cos(theObj.theta)* amplitudefactor;
painter.setPen(QPen(Qt::green,2,Qt::SolidLine,Qt::RoundCap));
painter.drawImage(pointx,pointy,QImage("E:\\bitmaps\\gbitmap.png"));
break;
default:
break;
// setStyleSheet("background-color: rgb(0, 0, 0);");
【问题讨论】:
首先,正确缩进你的代码(如果你想让任何人花时间在你的问题上)。 第二,试着解释一下,你的问题是什么。现在我们有了你的代码和解释你想要它做什么。但是你的问题是什么?emit SIGNAL(valuechanged()); connect(a,SIGNAL(valuechanged()), b , SLOT(tacticalwidget::paintEvent()));
Dave 恐怕你做不到。
看看QWidget::update
插槽。也只将信号连接到插槽一次,而不是在循环内。最好在信号发出之前。否则,插槽将被调用的次数与信号连接到它的次数一样多。
【参考方案1】:
-
您在
readyRead()
中错误地处理了一个套接字,请检查my other answer
您正在发射信号然后连接它,并且您正在多次执行此操作,这是个大问题。
你搞砸了字节序,查看QDataStream
类(它假定默认情况下流采用大字节序)。
一般来说,你有很好的意大利面条代码,所以我并不惊讶它不起作用。
【讨论】:
关于QDataStream
的注释:它无法处理部分读取,因此直接在套接字上使用它不是很可靠(相反,您是否拥有缓冲并仅在您知道的数据上使用 QDataStream完成)。
检查我包含的链接。以上是关于使用 qt 中的信号/插槽更新 gui [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
是否可以将模型对象的插槽连接到 QT4 -Designer 中的 GUI?