使用 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?

您如何以编程方式更新 Qt 中的 UI?

在Qt中通过信号和插槽系统传递变量[关闭]

Qt - 使用信号/插槽关闭子菜单

Qt QProcess::finished() 信号没有这样的插槽

Qt入门教程QObject篇线程和QOBject