double ObjectSettings:: objectT(double s, double t, double roadDistance) { LaneSection *laneSection = object_->getParentRoad()->getLaneSection(s); double dist = 0.0; double sSection = s - laneSection->getSStart(); if (t >= 0) { dist = laneSection->getLaneSpanWidth(0, laneSection->getLeftmostLaneId(), sSection) + roadDistance; } else { dist = -laneSection->getLaneSpanWidth(0, laneSection->getRightmostLaneId(), sSection) - roadDistance; } return dist; }
/*! * Initializes the path (only once). */ void OSCBridgeItem::createPath() { if (path_) { delete path_; } path_ = new QPainterPath(); setBrush(QBrush(outerColor_)); setPen(QPen(outerColor_, 2.0)); if (bridge_->getLength() > NUMERICAL_ZERO3) // Bridge is repeated { double totalLength = 0.0; double currentS = bridge_->getSStart(); // Left and right side // // while ((totalLength < bridge_->getLength()) && (currentS < road_->getLength())) { LaneSection *laneSection = road_->getLaneSection(currentS); double t = laneSection->getLaneSpanWidth(0, laneSection->getRightmostLaneId() - 1, currentS); QPointF currentPos = road_->getGlobalPoint(currentS, t); if (totalLength == 0) { path_->moveTo(currentPos.x(), currentPos.y()); } else { path_->lineTo(currentPos.x(), currentPos.y()); path_->moveTo(currentPos.x(), currentPos.y()); } // double dist = 4; // TODO get configured tesselation length Jutta knows where to get this from double dist = 1 / getProjectGraph()->getProjectWidget()->getLODSettings()->TopViewEditorPointsPerMeter; if ((totalLength + dist) > bridge_->getLength()) { QPointF currentPos = road_->getGlobalPoint(currentS + (bridge_->getLength() - totalLength), t); path_->lineTo(currentPos.x(), currentPos.y()); } totalLength += dist; currentS += dist; } totalLength = 0.0; currentS = bridge_->getSStart(); // Left and right side // // while ((totalLength < bridge_->getLength()) && (currentS < road_->getLength())) { LaneSection *laneSection = road_->getLaneSection(currentS); double t = -laneSection->getLaneSpanWidth(laneSection->getLeftmostLaneId(), 0, currentS); QPointF currentPos = road_->getGlobalPoint(currentS, t); if (totalLength == 0) { path_->moveTo(currentPos.x(), currentPos.y()); } else { path_->lineTo(currentPos.x(), currentPos.y()); path_->moveTo(currentPos.x(), currentPos.y()); } // double dist = 4; // TODO get configured tesselation length Jutta knows where to get this from double dist = 1 / getProjectGraph()->getProjectWidget()->getLODSettings()->TopViewEditorPointsPerMeter; if ((totalLength + dist) > bridge_->getLength()) { QPointF currentPos = road_->getGlobalPoint(currentS + (bridge_->getLength() - totalLength), t); path_->lineTo(currentPos.x(), currentPos.y()); } totalLength += dist; currentS += dist; } } setPath(*path_); }
osg::Geode *RoadObject::createOutlineGeode() { osg::Geode *OutlineGeode = new osg::Geode(); OutlineGeode->setName(name.c_str()); double h = 4.5; double texlength = 4.5; double texwidth = 0.33; double railLength = length; if (repeatLength > 0) railLength = repeatLength; if (s + railLength > road->getLength()) { railLength = road->getLength() - s; } if (repeatDistance > 0) { h = repeatDistance; texlength = repeatDistance; } osg::Geometry *OutlineGeometry; OutlineGeometry = new osg::Geometry(); OutlineGeode->addDrawable(OutlineGeometry); OutlineGeometry->setUseDisplayList(true); OutlineGeometry->setUseVertexBufferObjects(false); osg::Vec3Array *OutlineVertices; OutlineVertices = new osg::Vec3Array; OutlineGeometry->setVertexArray(OutlineVertices); osg::Vec3Array *OutlineNormals; OutlineNormals = new osg::Vec3Array; OutlineGeometry->setNormalArray(OutlineNormals); OutlineGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); osg::Vec2Array *OutlineTexCoords; OutlineTexCoords = new osg::Vec2Array; OutlineGeometry->setTexCoordArray(3, OutlineTexCoords); RoadPoint railPoint; RoadPoint railPoint2; RoadPoint nextRailPoint; osg::Vec3 n; int numVert = outline->size(); int numSegments = numVert - 1; osg::Vec2 *profile = new osg::Vec2[numVert]; float len=0; float *tcv = new float[numVert]; for (int i = 0; i < numVert; i++) { profile[i] = osg::Vec2(outline->at(i).v, outline->at(i).z); } tcv[0]=0; for (int i = 1; i < numVert; i++) { len += (profile[i] - profile[i-1]).length(); tcv[i]=len; } for (int i = 1; i < numVert; i++) { tcv[i]/= len; } LaneSection * startLaneSection = NULL; int startLaneId = 0; double sSection = s; double d = 0.0; int lengthSegments; double currentT; LaneSection * currentLaneSection; int currentLaneId; for (int pseg = 0; pseg < numSegments; pseg++) { lengthSegments = 0; currentT = t; currentLaneSection = startLaneSection; currentLaneId = startLaneId; for (double currentS = s; currentS <= s + railLength; currentS += h) { if (currentS > (s + railLength - (h))) { currentS = (s + railLength); } if (road->getLaneSection(currentS) != currentLaneSection) { LaneSection * newLaneSection = road->getLaneSection(currentS); while (currentLaneSection && (currentLaneSection != newLaneSection)) { if (t < 0) { currentT = -currentLaneSection->getLaneSpanWidth(0, currentLaneId, road->getLaneSectionEnd(currentLaneSection->getStart())) + d; } else if (t > 0) { currentT = currentLaneSection->getLaneSpanWidth(0, currentLaneId, road->getLaneSectionEnd(currentLaneSection->getStart())) + d; } currentLaneSection = road->getLaneSectionNext(currentLaneSection->getStart() + 1.0e-3); currentLaneId = road->getLaneNumber(currentLaneSection->getStart(), currentT); sSection = currentLaneSection->getStart(); } currentLaneSection = newLaneSection; currentLaneId = road->getLaneNumber(sSection, currentT); if (t < 0) { if (fabs(currentT) < currentLaneSection->getLaneSpanWidth(0, currentLaneId + 1, currentS) + currentLaneSection->getLaneWidth(currentS, currentLaneId)/2) { currentLaneId++; } d = currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + currentT; } else if (t > 0) { if (currentT < currentLaneSection->getLaneSpanWidth(0, currentLaneId - 1, currentS) + currentLaneSection->getLaneWidth(currentS, currentLaneId)/2) { currentLaneId--; } d = currentT - currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS); } } if (t < 0) { currentT = -currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + d; } else if (t > 0) { currentT = currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + d; } nextRailPoint = road->getRoadPoint(currentS + h, currentT); osg::Vec3 p3(nextRailPoint.x(), nextRailPoint.y(), nextRailPoint.z()); railPoint = road->getRoadPoint(currentS, currentT); if (t > 0) railPoint2 = road->getRoadPoint(currentS, currentT + 1.0); else railPoint2 = road->getRoadPoint(currentS, currentT - 1.0); n.set(railPoint2.x() - railPoint.x(), railPoint2.y() - railPoint.y(), railPoint2.z() - railPoint.z()); n.normalize(); osg::Vec3 negn = -n; osg::Vec3 p1(railPoint.x(), railPoint.y(), railPoint.z()); p1 += n * profile[pseg].x(); p1[2] += profile[pseg].y(); OutlineVertices->push_back(osg::Vec3(p1.x(), p1.y(), p1.z())); OutlineTexCoords->push_back(osg::Vec2((currentS/texlength), tcv[pseg])); osg::Vec3 p2(railPoint.x(), railPoint.y(), railPoint.z()); p2 += n * profile[pseg + 1].x(); p2[2] += profile[pseg + 1].y(); OutlineVertices->push_back(osg::Vec3(p2.x(), p2.y(), p2.z())); OutlineTexCoords->push_back(osg::Vec2((currentS/texlength), tcv[pseg+1])); lengthSegments += 2; osg::Vec3 up = p2 - p1; osg::Vec3 forward = p3 - p1; osg::Vec3 norm = up ^ forward; /* if(p1.z() == p2.z()) { norm.set(0,0,-1); } else if(p1.z() < p2.z()) { osg::Vec3 up = p2-p1; up.normalize(); osg::Vec3 right; if(t>=0) { right= up ^ negn; } else { right= up ^ n; } right.normalize(); norm = up ^ right; norm.normalize(); } else { osg::Vec3 up = p1-p2; up.normalize(); osg::Vec3 right; if(t>=0) { right= up ^ negn; } else { right= up ^ n; } right.normalize(); norm = up ^ right; norm.normalize(); } */ OutlineNormals->push_back(norm); OutlineNormals->push_back(norm); } osg::DrawArrays *OutlineBarrier = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, lengthSegments * pseg, lengthSegments); OutlineGeometry->addPrimitiveSet(OutlineBarrier); } osg::StateSet *OutlineStateSet = OutlineGeode->getOrCreateStateSet(); OutlineStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); if(numSegments>2) { osg::CullFace *cullFace = new osg::CullFace(); cullFace->setMode(osg::CullFace::BACK); OutlineStateSet->setAttributeAndModes(cullFace, osg::StateAttribute::ON); } if(textureFileName!="") { const char *fileName = coVRFileManager::instance()->getName(textureFileName.c_str()); if (fileName) { osg::Image *OutlineTexImage = osgDB::readImageFile(fileName); osg::Texture2D *OutlineTex = new osg::Texture2D; OutlineTex->setWrap(osg::Texture2D::WRAP_S, osg::Texture::REPEAT); OutlineTex->setWrap(osg::Texture2D::WRAP_T, osg::Texture::CLAMP); if (OutlineTexImage) OutlineTex->setImage(OutlineTexImage); OutlineStateSet->setTextureAttributeAndModes(3, OutlineTex, osg::StateAttribute::ON); osg::AlphaFunc *alphaFunc = new osg::AlphaFunc(); alphaFunc->setFunction(osg::AlphaFunc::GEQUAL, 0.1f); OutlineStateSet->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON); } else { std::cerr << "ERROR: no texture found named: "<< textureFileName<< std::endl; } } return OutlineGeode; }
osg::Geode *RoadObject::createGuardRailGeode() { osg::Geode *guardRailGeode = new osg::Geode(); guardRailGeode->setName(name.c_str()); double h = 4.5; double texlength = 4.5; double texwidth = 0.33; double railLength = length; if (repeatLength > 0) railLength = repeatLength; if (s + railLength > road->getLength()) { railLength = road->getLength() - s; } if (repeatDistance > 0) { h = repeatDistance; texlength = repeatDistance; } osg::Geometry *guardRailGeometry; guardRailGeometry = new osg::Geometry(); guardRailGeode->addDrawable(guardRailGeometry); guardRailGeometry->setUseDisplayList(true); guardRailGeometry->setUseVertexBufferObjects(false); osg::Vec3Array *guardRailVertices; guardRailVertices = new osg::Vec3Array; guardRailGeometry->setVertexArray(guardRailVertices); osg::Vec3Array *guardRailNormals; guardRailNormals = new osg::Vec3Array; guardRailGeometry->setNormalArray(guardRailNormals); guardRailGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); osg::Vec2Array *guardRailTexCoords; guardRailTexCoords = new osg::Vec2Array; guardRailGeometry->setTexCoordArray(3, guardRailTexCoords); osg::Geometry *guardRailPostGeometry; guardRailPostGeometry = new osg::Geometry(); guardRailGeode->addDrawable(guardRailPostGeometry); osg::Vec3Array *guardRailPostVertices; guardRailPostVertices = new osg::Vec3Array; guardRailPostGeometry->setVertexArray(guardRailPostVertices); osg::Vec2Array *guardRailPostTexCoords; guardRailPostTexCoords = new osg::Vec2Array; guardRailPostGeometry->setTexCoordArray(3, guardRailPostTexCoords); osg::Vec3Array *guardRailPostNormals; guardRailPostNormals = new osg::Vec3Array; guardRailPostGeometry->setNormalArray(guardRailPostNormals); guardRailPostGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); bool up = true; if (s == 0) up = false; // do not go up if we start right at the bginning of a road, then we continue from the last road bool down = false; RoadPoint railPoint; RoadPoint railPoint2; osg::Vec3 n; LaneSection * currentLaneSection = NULL; int currentLaneId = 0; double sSection = s; double d = 0.0; double currentT = t; for (double currentS = s; currentS <= s + railLength; currentS += h) { if (currentS > (s + railLength - (h))) { currentS = (s + railLength); if (fabs(s + railLength - road->getLength()) > 1.0e-6) // only go down if the rail does not extend to the end of the road. { down = true; } } if (road->getLaneSection(currentS) != currentLaneSection) { LaneSection * newLaneSection = road->getLaneSection(currentS); while (currentLaneSection && (currentLaneSection != newLaneSection)) { if (t < 0) { currentT = -currentLaneSection->getLaneSpanWidth(0, currentLaneId, road->getLaneSectionEnd(currentLaneSection->getStart())) + d; } else if (t > 0) { currentT = currentLaneSection->getLaneSpanWidth(0, currentLaneId, road->getLaneSectionEnd(currentLaneSection->getStart())) + d; } currentLaneSection = road->getLaneSectionNext(currentLaneSection->getStart() + 1.0e-3); currentLaneId = road->getLaneNumber(currentLaneSection->getStart(), currentT); sSection = currentLaneSection->getStart(); } currentLaneSection = newLaneSection; currentLaneId = road->getLaneNumber(sSection, currentT); if (t < 0) { if (fabs(currentT) < currentLaneSection->getLaneSpanWidth(0, currentLaneId + 1, currentS) + currentLaneSection->getLaneWidth(currentS, currentLaneId)/2) { currentLaneId++; } d = currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + currentT; } else if (t > 0) { if (currentT < currentLaneSection->getLaneSpanWidth(0, currentLaneId - 1, currentS) + currentLaneSection->getLaneWidth(currentS, currentLaneId)/2) { currentLaneId--; } d = currentT - currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS); } } if (t < 0) { currentT = -currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + d; } else if (t > 0) { currentT = currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + d; } railPoint = road->getRoadPoint(currentS, currentT); if (t > 0) railPoint2 = road->getRoadPoint(currentS, currentT + 1.0); else railPoint2 = road->getRoadPoint(currentS, currentT - 1.0); n.set(railPoint2.x() - railPoint.x(), railPoint2.y() - railPoint.y(), railPoint2.z() - railPoint.z()); n.normalize(); osg::Vec3 negn = -n; if (up || down) { guardRailVertices->push_back(osg::Vec3(railPoint.x(), railPoint.y(), railPoint.z() - 0.31)); guardRailTexCoords->push_back(osg::Vec2((currentS / texlength), 0)); guardRailVertices->push_back(osg::Vec3(railPoint.x(), railPoint.y(), railPoint.z())); guardRailTexCoords->push_back(osg::Vec2((currentS / texlength), 0.33 / texwidth)); } else { guardRailVertices->push_back(osg::Vec3(railPoint.x(), railPoint.y(), railPoint.z() + 0.44)); guardRailTexCoords->push_back(osg::Vec2((currentS / texlength), 0)); guardRailVertices->push_back(osg::Vec3(railPoint.x(), railPoint.y(), railPoint.z() + 0.75)); guardRailTexCoords->push_back(osg::Vec2((currentS / texlength), 0.33 / texwidth)); // post osg::Vec3 p1, p2, p3, p4; osg::Vec3 n2; n2.set(railPoint.nx(), railPoint.ny(), railPoint.nz()); n2.normalize(); osg::Vec3 n3 = n2 ^ n; n3.normalize(); p1.set(railPoint.x(), railPoint.y(), railPoint.z()); p1 += n * 0.01; p2 = p1 + (n3 * 0.08); p3 = p2 + (n * 0.06); p4 = p1 + (n * 0.06); osg::Vec3 p5, p6, p7, p8; p5.set(p1.x(), p1.y(), p1.z() + 0.44); p6.set(p2.x(), p2.y(), p2.z() + 0.44); guardRailPostVertices->push_back(p1); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.02)); guardRailPostNormals->push_back(n); guardRailPostVertices->push_back(p2); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.1)); guardRailPostNormals->push_back(n); guardRailPostVertices->push_back(p6); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.1)); guardRailPostNormals->push_back(n); guardRailPostVertices->push_back(p5); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.02)); guardRailPostNormals->push_back(n); p5.set(p1.x(), p1.y(), p1.z() + 0.6); p6.set(p2.x(), p2.y(), p2.z() + 0.6); p7.set(p3.x(), p3.y(), p3.z() + 0.6); p8.set(p4.x(), p4.y(), p4.z() + 0.6); osg::Vec3 negn3 = -n3; guardRailPostVertices->push_back(p2); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.02)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p3); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.1)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p7); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.1)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p6); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.02)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p1); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.02)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p4); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.1)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p8); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.1)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p5); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.02)); guardRailPostNormals->push_back(negn3); } if (t > 0) { guardRailNormals->push_back(n); guardRailNormals->push_back(n); } else { guardRailNormals->push_back(negn); guardRailNormals->push_back(negn); } up = false; } osg::DrawArrays *guardRailPosts = new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, guardRailPostVertices->size()); guardRailPostGeometry->addPrimitiveSet(guardRailPosts); osg::DrawArrays *guardRail = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, 0, guardRailVertices->size()); guardRailGeometry->addPrimitiveSet(guardRail); osg::StateSet *guardRailStateSet = guardRailGeode->getOrCreateStateSet(); guardRailStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); //guardRailStateSet->setMode ( GL_LIGHT0, osg::StateAttribute::ON ); //guardRailStateSet->setMode ( GL_LIGHT1, osg::StateAttribute::ON); const char *fileName = coVRFileManager::instance()->getName("share/covise/materials/guardRailTex.jpg"); if (fileName) { osg::Image *guardRailTexImage = osgDB::readImageFile(fileName); osg::Texture2D *guardRailTex = new osg::Texture2D; guardRailTex->setWrap(osg::Texture2D::WRAP_S, osg::Texture::REPEAT); guardRailTex->setWrap(osg::Texture2D::WRAP_T, osg::Texture::REPEAT); if (guardRailTexImage) guardRailTex->setImage(guardRailTexImage); guardRailStateSet->setTextureAttributeAndModes(3, guardRailTex, osg::StateAttribute::ON); } else { std::cerr << "ERROR: no texture found named: share/covise/materials/guardRailTex.jpg"; } return guardRailGeode; }
void SignalSettings::onEditingFinished() { if (valueChanged_) { double t = ui->tSpinBox->value(); int fromLane = ui->fromLaneSpinBox->value(); int toLane = ui->toLaneSpinBox->value(); if (toLane > fromLane) { toLane = fromLane; } if (signal_->getType() != 293) { if (((t < 0) && ((fromLane > 0) || (fromLane < signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getRightmostLaneId()))) || ((t > 0) && ((fromLane < 0) || (fromLane > signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getLeftmostLaneId())))) { fromLane = signal_->getParentRoad()->getValidLane(signal_->getSStart(), t); } if (((t < 0) && ((toLane > 0) || (toLane < signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getRightmostLaneId()))) || ((t > 0) && ((toLane < 0) || (toLane > signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getLeftmostLaneId())))) { toLane = signal_->getParentRoad()->getValidLane(signal_->getSStart(), t); } } else { if ((fromLane != signal_->getValidFromLane()) || (toLane != signal_->getValidToLane())) { if ((fromLane >= 0) && (toLane >= 0) && (t < 0)) { LaneSection *laneSection = signal_->getParentRoad()->getLaneSection(signal_->getSStart()); t = laneSection->getLaneSpanWidth(fromLane, toLane, signal_->getSStart()); } else if ((fromLane <= 0) && (toLane <= 0) && (t > 0)) { LaneSection *laneSection = signal_->getParentRoad()->getLaneSection(signal_->getSStart()); t = -laneSection->getLaneSpanWidth(fromLane, toLane, signal_->getSStart()); } } if (fromLane < signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getRightmostLaneId()) { fromLane = signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getRightmostLaneId(); } else if (fromLane > signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getLeftmostLaneId()) { fromLane = signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getLeftmostLaneId(); } if (toLane < signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getRightmostLaneId()) { toLane = signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getRightmostLaneId(); } else if (toLane > signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getLeftmostLaneId()) { toLane = signal_->getParentRoad()->getLaneSection(signal_->getSStart())->getLeftmostLaneId(); } } double crossingProb = 0.0; double resetTime = 0.0; if (ui->crossingProbLabel->isEnabled()) { crossingProb = ui->crossingSpinBox->value(); resetTime = ui->resetTimeSpinBox->value(); } SetSignalPropertiesCommand *command = new SetSignalPropertiesCommand(signal_, signal_->getId(), signal_->getName(), t, ui->dynamicCheckBox->isChecked(), (Signal::OrientationType)ui->orientationComboBox->currentIndex(), ui->zOffsetSpinBox->value(), ui->countryBox->text(), ui->typeSpinBox->value(), ui->subclassLineEdit->text(), ui->subtypeSpinBox->value(), ui->valueSpinBox->value(), ui->hOffsetSpinBox->value(), ui->pitchSpinBox->value(), ui->rollSpinBox->value(), ui->poleCheckBox->isChecked(), ui->sizeComboBox->currentIndex() + 1, fromLane, toLane, crossingProb, resetTime, NULL); getProjectSettings()->executeCommand(command); valueChanged_ = false; QWidget * focusWidget = QApplication::focusWidget(); if (focusWidget) { focusWidget->clearFocus(); } } }