当前位置: 首页 > news >正文

杭州鼎易科技做网站太坑溜冰鞋 东莞网站建设

杭州鼎易科技做网站太坑,溜冰鞋 东莞网站建设,中国龙岩网,如何申请免费网站作为一套开源跨平台的UI代码库#xff0c;窗体绘制与响应自然是最为基本的功能。在前面的博文中#xff0c;已就Qt中的元对象系统(反射机制)、事件循环等基础内容进行了分析#xff0c;并捎带阐述了窗体响应相关的内容。因此#xff0c;本文着重分析Qt中窗体绘制相关的内容…作为一套开源跨平台的UI代码库窗体绘制与响应自然是最为基本的功能。在前面的博文中已就Qt中的元对象系统(反射机制)、事件循环等基础内容进行了分析并捎带阐述了窗体响应相关的内容。因此本文着重分析Qt中窗体绘制相关的内容。 在本文最后通过FreeCAD SheetTableView单元格缩放功能的实现来对研究分析予以检验与测试。 注1限于研究水平分析难免不当欢迎批评指正。 注2文章内容会不定期更新。 一、坐标系统 在Qt中每个窗口(准确说是派生于QPaintDevice的C类)均有一个以像素为单位的二维窗体坐标系默认情况下坐标原点位于窗体左上角轴水平向右轴竖直向下。 Ref. from QPaintDevice  A paint device is an abstraction of a two-dimensional space that can be drawn on using a QPainter. Its default coordinate system has its origin located at the top-left position. X increases to the right and Y increases downwards. The unit is one pixel. The drawing capabilities of QPaintDevice are currently implemented by the QWidget, QImage, QPixmap, QGLPixelBuffer, QPicture, and QPrinter subclasses. 整体上世界坐标(也称作逻辑坐标)需要首先转换成窗体坐标然后再转换为设备坐标(也称作物理坐标)。 Ref. from Qt Coordinate System 将上述坐标变换写成矩阵变换的形式如下 其中 默认值 :窗体左边界坐标 :窗体上边界坐标 : 窗体宽度 : 窗体高度 :设备左边界坐标 :设备上边界坐标 : 设备宽度 : 设备高度 从中看可以看出默认情况下世界坐标与窗体坐标是重合的但设备坐标则由窗体尺寸、设备尺寸等决定。上述分析也可以通过QPainter的代码分析印证。 // src/gui/painting/qpainter.cppvoid QPainter::setViewport(const QRect r) { #ifdef QT_DEBUG_DRAWif (qt_show_painter_debug_output)printf(QPainter::setViewport(), [%d,%d,%d,%d]\n, r.x(), r.y(), r.width(), r.height()); #endifQ_D(QPainter);if (!d-engine) {qWarning(QPainter::setViewport: Painter not active);return;}d-state-vx r.x();d-state-vy r.y();d-state-vw r.width();d-state-vh r.height();d-state-VxF true;d-updateMatrix(); }QTransform QPainterPrivate::viewTransform() const {if (state-VxF) {qreal scaleW qreal(state-vw)/qreal(state-ww);qreal scaleH qreal(state-vh)/qreal(state-wh);return QTransform(scaleW, 0, 0, scaleH,state-vx - state-wx*scaleW, state-vy - state-wy*scaleH);}return QTransform(); } 二、窗体绘制 2.1 整体流程 QWidget::update() QWidget::repaint() 从上述流程分析可以得到以下结论 QWidget update()、repaint()绘制流程几乎相似最终均会路由到QWidget::paintEvent函数。不同点在于update通过QCoreApplication::postEvent触发了QEvent::UpdateLater事件而repaint()通过QCoreApplication::sendEvent触发了QEvent::UpdateRequest事件。 Ref. from QWidget::update()  Updates the widget unless updates are disabled or the widget is hidden. This function does not cause an immediate repaint; instead it schedules a paint event for processing when Qt returns to the main event loop. This permits Qt to optimize for more speed and less flicker than a call to repaint() does. Calling update() several times normally results in just one paintEvent() call. Ref. from QWidget::repaint()  Repaints the widget directly by calling paintEvent() immediately, unless updates are disabled or the widget is hidden. We suggest only using repaint() if you need an immediate repaint, for example during animation. In almost all circumstances update() is better, as it permits Qt to optimize for speed and minimize flicker. 对于QPaintEvent事件相关的绘制区域实际上是在窗口坐标系下描述的这可通过  QWidgetRepaintManager::paintAndFlush()看出。 void QWidgetRepaintManager::paintAndFlush() {qCInfo(lcWidgetPainting) Painting and flushing dirty top level dirty and dirty widgets dirtyWidgets;const bool updatesDisabled !tlw-updatesEnabled();bool repaintAllWidgets false;const bool inTopLevelResize tlw-d_func()-maybeTopData()-inTopLevelResize;const QRect tlwRect tlw-data-crect;const QRect surfaceGeometry(tlwRect.topLeft(), store-size());if ((inTopLevelResize || surfaceGeometry.size() ! tlwRect.size()) !updatesDisabled) {if (hasStaticContents() !store-size().isEmpty() ) {// Repaint existing dirty area and newly visible area.const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());const QRegion staticRegion(staticContents(0, clipRect));QRegion newVisible(0, 0, tlwRect.width(), tlwRect.height());newVisible - staticRegion;dirty newVisible;store-setStaticContents(staticRegion);} else {// Repaint everything.dirty QRegion(0, 0, tlwRect.width(), tlwRect.height());for (int i 0; i dirtyWidgets.size(); i)resetWidget(dirtyWidgets.at(i));dirtyWidgets.clear();repaintAllWidgets true;}}// ... ... } 三、分析演练FreeCAD SheetTableView鼠标滚动缩放 “学以致用”作为前面分析研究的验证与测试本文抛出下面一个小功能的实现以期将上述原理串联起来。 在FreeCAD中通过引用Sheet内的单元格数据可以方便的实现几何参数化建模同时FreeCAD SpreadsheetGui模块也提供了SheetTableView来显示/编辑电子表格。 当参数数据较多时希望滚动缩放电子表格从而可以在屏幕内完整的显示整个电子表格也就是说鼠标滚动缩放时要求单元格尺寸、单元格内容同等比例缩放。但SheetTableView目前并不支持此功能。 SheetTableView继承自QTableView由horizontal header、vertical header、view port、horizontal scrollbar、vertical scrollbar、corner widget等组成。而且horizontal header、vertical header、QTableView共享了相同的model。 QTableView portrait QTableView实际上使用水平/竖直QHeaderView来定位(表格)单元格也就是说QTableView利用水平/竖直QHeaderView将窗体坐标转换成单元格索引这一点可由QTableView::paintEvent(QPaintEvent *event)看出。 void QTableView::paintEvent(QPaintEvent *event) {// ... ...for (QRect dirtyArea : region) {dirtyArea.setBottom(qMin(dirtyArea.bottom(), int(y)));if (rightToLeft) {dirtyArea.setLeft(qMax(dirtyArea.left(), d-viewport-width() - int(x)));} else {dirtyArea.setRight(qMin(dirtyArea.right(), int(x)));}// dirtyArea may be invalid when the horizontal header is not stretchedif (!dirtyArea.isValid())continue;// get the horizontal start and end visual sectionsint left horizontalHeader-visualIndexAt(dirtyArea.left());int right horizontalHeader-visualIndexAt(dirtyArea.right());if (rightToLeft)qSwap(left, right);if (left -1) left 0;if (right -1) right horizontalHeader-count() - 1;// get the vertical start and end visual sections and if alternate colorint bottom verticalHeader-visualIndexAt(dirtyArea.bottom());if (bottom -1) bottom verticalHeader-count() - 1;int top 0;bool alternateBase false;if (alternate verticalHeader-sectionsHidden()) {const int verticalOffset verticalHeader-offset();int row verticalHeader-logicalIndex(top);for (int y 0;((y verticalHeader-sectionSize(top)) verticalOffset) (top bottom);top) {row verticalHeader-logicalIndex(top);if (alternate !verticalHeader-isSectionHidden(row))alternateBase !alternateBase;}} else {top verticalHeader-visualIndexAt(dirtyArea.top());alternateBase (top 1) alternate;}if (top -1 || top bottom)continue;// Paint each row itemfor (int visualRowIndex top; visualRowIndex bottom; visualRowIndex) {int row verticalHeader-logicalIndex(visualRowIndex);if (verticalHeader-isSectionHidden(row))continue;int rowY rowViewportPosition(row);rowY offset.y();int rowh rowHeight(row) - gridSize;// Paint each column itemfor (int visualColumnIndex left; visualColumnIndex right; visualColumnIndex) {int currentBit (visualRowIndex - firstVisualRow) * (lastVisualColumn - firstVisualColumn 1) visualColumnIndex - firstVisualColumn;if (currentBit 0 || currentBit drawn.size() || drawn.testBit(currentBit))continue;drawn.setBit(currentBit);int col horizontalHeader-logicalIndex(visualColumnIndex);if (horizontalHeader-isSectionHidden(col))continue;int colp columnViewportPosition(col);colp offset.x();int colw columnWidth(col) - gridSize;const QModelIndex index d-model-index(row, col, d-root);if (index.isValid()) {option.rect QRect(colp (showGrid rightToLeft ? 1 : 0), rowY, colw, rowh);if (alternate) {if (alternateBase)option.features | QStyleOptionViewItem::Alternate;elseoption.features ~QStyleOptionViewItem::Alternate;}d-drawCell(painter, option, index);}}alternateBase !alternateBase alternate;}if (showGrid) {// Find the bottom right (the last rows/columns might be hidden)while (verticalHeader-isSectionHidden(verticalHeader-logicalIndex(bottom))) --bottom;QPen old painter.pen();painter.setPen(gridPen);// Paint each rowfor (int visualIndex top; visualIndex bottom; visualIndex) {int row verticalHeader-logicalIndex(visualIndex);if (verticalHeader-isSectionHidden(row))continue;int rowY rowViewportPosition(row);rowY offset.y();int rowh rowHeight(row) - gridSize;painter.drawLine(dirtyArea.left(), rowY rowh, dirtyArea.right(), rowY rowh);}// Paint each columnfor (int h left; h right; h) {int col horizontalHeader-logicalIndex(h);if (horizontalHeader-isSectionHidden(col))continue;int colp columnViewportPosition(col);colp offset.x();if (!rightToLeft)colp columnWidth(col) - gridSize;painter.drawLine(colp, dirtyArea.top(), colp, dirtyArea.bottom());}painter.setPen(old);}}// ... ... } 因此要实现QTableView支持鼠标滚动缩放就需要使QTableView在方向缩放与水平QHeaderView保持一致而在方向伸缩与竖直QHeaderView保持一致。 以水平QHeaderView为例设坐标变换表示为对于QTableView设坐标变换为。则有。 另一方面从代码实现可以看出QTableView::paintEvent(QPaintEvent *event)绘制函数采用了默认的变换矩阵。 /*!Paints the table on receipt of the given paint event \a event. */ void QTableView::paintEvent(QPaintEvent *event) {// ... ...QPainter painter(d-viewport);// if theres nothing to do, clear the area and returnif (horizontalHeader-count() 0 || verticalHeader-count() 0 || !d-itemDelegate)return;const int x horizontalHeader-length() - horizontalHeader-offset() - (rightToLeft ? 0 : 1);const int y verticalHeader-length() - verticalHeader-offset() - 1;// ... ... } 因此一种实现方法就是通过重写QTableView::paintEvent(QPaintEvent *event)指定合适的变换矩阵来实现QTableView滚动缩放。 具体来说首先重写wheelEvent(QWheelEvent* event)以将鼠标滚动输入转化成缩放比例 // following the zoom strategy in SALOME GraphicsView_Viewer // see SALOME gui/src/GraphicsView/GraphicsView_Viewer.cpp void SheetTableView::wheelEvent(QWheelEvent* event) {if (QApplication::keyboardModifiers() Qt::ControlModifier) {const double d 1.05;double q pow(d, -event-delta() / 120.0);this-scale(q, q);event-accept();return;}return QTableView::wheelEvent(event); } void SheetTableView::scale(qreal sx, qreal sy) {//Q_D(QGraphicsView);QTransform matrix myMatrix;matrix.scale(sx, sy);setTransform(matrix);for (int i 0; i horizontalHeader()-count(); i) {int s horizontalHeader()-sectionSize(i);horizontalHeader()-resizeSection(i, s * sx);}for (int i 0; i verticalHeader()-count(); i) {int s verticalHeader()-sectionSize(i);verticalHeader()-resizeSection(i, s * sy);}this-update(); } 然后重写paintEvent(QPaintEvent* event)依据缩放比例将单元格内容进行缩放。需要注意的是由于水平/竖直 QHeaderView已经进行了缩放而QTableView是依据水平/竖直QHeaderView计算单元格坐标因此在绘制窗体时需要使用传入的窗体坐标但为了缩放单元格内容为QPainter指定了变换矩阵,所以单元格坐标要施加矩阵变化。 void SheetTableView::paintEvent(QPaintEvent* event) {// ... ...auto matrix viewportTransform();auto inv_matrix matrix.inverted();QPainter painter(viewport());painter.setWorldTransform(matrix);// ...for (QRect dirtyArea : region) {// ... ...// Paint each row itemfor (int visualRowIndex top; visualRowIndex bottom; visualRowIndex) {int row verticalHeader-logicalIndex(visualRowIndex);if (verticalHeader-isSectionHidden(row))continue;int rowY rowViewportPosition(row);rowY offset.y();int rowh rowHeight(row) - gridSize;// Paint each column itemfor (int visualColumnIndex left; visualColumnIndex right; visualColumnIndex) {int currentBit (visualRowIndex - firstVisualRow) * (lastVisualColumn - firstVisualColumn 1) visualColumnIndex - firstVisualColumn;if (currentBit 0 || currentBit drawn.size() || drawn.testBit(currentBit))continue;drawn.setBit(currentBit);int col horizontalHeader-logicalIndex(visualColumnIndex);if (horizontalHeader-isSectionHidden(col))continue;int colp columnViewportPosition(col);colp offset.x();int colw columnWidth(col) - gridSize;const QModelIndex index model()-index(row, col, rootIndex());if (index.isValid()) {//option.rect QRect(colp (showGrid rightToLeft ? 1 : 0), rowY, colw, rowh);option.rect inv_matrix.mapRect(QRect(colp (showGrid rightToLeft ? 1 : 0), rowY, colw, rowh));if (alternate) {if (alternateBase)option.features | QStyleOptionViewItem::Alternate;elseoption.features ~QStyleOptionViewItem::Alternate;}this-drawCell(painter, option, index);}}alternateBase !alternateBase alternate;}if (showGrid) {// Find the bottom right (the last rows/columns might be hidden)while (verticalHeader-isSectionHidden(verticalHeader-logicalIndex(bottom)))--bottom;QPen old painter.pen();painter.setPen(gridPen);// Paint each rowfor (int visualIndex top; visualIndex bottom; visualIndex) {int row verticalHeader-logicalIndex(visualIndex);if (verticalHeader-isSectionHidden(row))continue;int rowY rowViewportPosition(row);rowY offset.y();int rowh rowHeight(row) - gridSize;//painter.drawLine(dirtyArea.left(), rowY rowh, dirtyArea.right(), rowY rowh);QPoint p1(dirtyArea.left(), rowY rowh), p2(dirtyArea.right(), rowY rowh);painter.drawLine(inv_matrix.map(p1), inv_matrix.map(p2));}// Paint each columnfor (int h left; h right; h) {int col horizontalHeader-logicalIndex(h);if (horizontalHeader-isSectionHidden(col))continue;int colp columnViewportPosition(col);colp offset.x();if (!rightToLeft)colp columnWidth(col) - gridSize;//painter.drawLine(colp, dirtyArea.top(), colp, dirtyArea.bottom());QPoint p1(colp, dirtyArea.top()), p2(colp, dirtyArea.bottom());painter.drawLine(inv_matrix.map(p1), inv_matrix.map(p2));}painter.setPen(old);}}//#if QT_CONFIG(draganddrop) // // Paint the dropIndicator // d-paintDropIndicator(painter); //#endif }依据上述方案的确可以实现QTableView单元格尺寸、单元格内容的滚动缩放但是存在以下问题 性能问题 QHeaderView由一串连续的section组成每个section对应一个列/行字段在section移动过程中visualIndex会发生变化但logicalIndex不变。 Ref. from  QHeaderView  Each header has an orientation() and a number of sections, given by the count() function. A section refers to a part of the header - either a row or a column, depending on the orientation. Sections can be moved and resized using moveSection() and resizeSection(); they can also be hidden and shown with hideSection() and showSection(). Each section of a header is described by a section ID, specified by its section(), and can be located at a particular visualIndex() in the header.  You can identify a section using the logicalIndex() and logicalIndexAt() functions, or by its index position, using the visualIndex() and visualIndexAt() functions. The visual index will change if a section is moved, but the logical index will not change. 虽然QHeaderView::resizeSection(int logical, int size)可以调整单元格大小但如果section数较多逐个调整section尺寸比较卡。 缩放QHeaderView 在QHeaderView::paintEvent(QPaintEvent *e)中所使用QPainter的没有施加缩放变换矩阵。因此无法对QHeaderView section内容进行缩放。 网络资料 Qt源码分析QMetaObject实现原理https://blog.csdn.net/qq_26221775/article/details/137023709?spm1001.2014.3001.5502 Qt源码分析: QEventLoop实现原理https://blog.csdn.net/qq_26221775/article/details/136776793?spm1001.2014.3001.5502 QWidgethttps://doc.qt.io/qt-5/qwidget.htmlQPainterhttps://doc.qt.io/qt-5/qpainter.htmlQPaintDevicehttps://doc.qt.io/qt-5/qpaintdevice.htmlQPaintEnginehttps://doc.qt.io/qt-5/qpaintengine.htmlCoordinate Systemhttps://doc.qt.io/qt-5/coordsys.html
文章转载自:
http://www.morning.mmjqk.cn.gov.cn.mmjqk.cn
http://www.morning.nckzt.cn.gov.cn.nckzt.cn
http://www.morning.xsjfk.cn.gov.cn.xsjfk.cn
http://www.morning.skrrq.cn.gov.cn.skrrq.cn
http://www.morning.nxwk.cn.gov.cn.nxwk.cn
http://www.morning.yhgbd.cn.gov.cn.yhgbd.cn
http://www.morning.ydrfl.cn.gov.cn.ydrfl.cn
http://www.morning.zfrs.cn.gov.cn.zfrs.cn
http://www.morning.zkdbx.cn.gov.cn.zkdbx.cn
http://www.morning.hpprx.cn.gov.cn.hpprx.cn
http://www.morning.tgtrk.cn.gov.cn.tgtrk.cn
http://www.morning.wfcqr.cn.gov.cn.wfcqr.cn
http://www.morning.krywy.cn.gov.cn.krywy.cn
http://www.morning.spxk.cn.gov.cn.spxk.cn
http://www.morning.ygrdb.cn.gov.cn.ygrdb.cn
http://www.morning.ktfbl.cn.gov.cn.ktfbl.cn
http://www.morning.wsxxq.cn.gov.cn.wsxxq.cn
http://www.morning.xhpnp.cn.gov.cn.xhpnp.cn
http://www.morning.gtxrw.cn.gov.cn.gtxrw.cn
http://www.morning.fsrtm.cn.gov.cn.fsrtm.cn
http://www.morning.dwrbn.cn.gov.cn.dwrbn.cn
http://www.morning.dpfr.cn.gov.cn.dpfr.cn
http://www.morning.hxsdh.cn.gov.cn.hxsdh.cn
http://www.morning.oumong.com.gov.cn.oumong.com
http://www.morning.qkqzm.cn.gov.cn.qkqzm.cn
http://www.morning.hnkkf.cn.gov.cn.hnkkf.cn
http://www.morning.atoinfo.com.gov.cn.atoinfo.com
http://www.morning.zyslyq.cn.gov.cn.zyslyq.cn
http://www.morning.pskjm.cn.gov.cn.pskjm.cn
http://www.morning.xfncq.cn.gov.cn.xfncq.cn
http://www.morning.jqmqf.cn.gov.cn.jqmqf.cn
http://www.morning.gynls.cn.gov.cn.gynls.cn
http://www.morning.jxwhr.cn.gov.cn.jxwhr.cn
http://www.morning.rxrw.cn.gov.cn.rxrw.cn
http://www.morning.nrwr.cn.gov.cn.nrwr.cn
http://www.morning.beijingzy.com.cn.gov.cn.beijingzy.com.cn
http://www.morning.ftlgy.cn.gov.cn.ftlgy.cn
http://www.morning.nhlnh.cn.gov.cn.nhlnh.cn
http://www.morning.rqmqr.cn.gov.cn.rqmqr.cn
http://www.morning.ngkgy.cn.gov.cn.ngkgy.cn
http://www.morning.kkjhj.cn.gov.cn.kkjhj.cn
http://www.morning.nrjr.cn.gov.cn.nrjr.cn
http://www.morning.wsrcy.cn.gov.cn.wsrcy.cn
http://www.morning.mflhr.cn.gov.cn.mflhr.cn
http://www.morning.pbygt.cn.gov.cn.pbygt.cn
http://www.morning.pbxkk.cn.gov.cn.pbxkk.cn
http://www.morning.rwmqp.cn.gov.cn.rwmqp.cn
http://www.morning.fhddr.cn.gov.cn.fhddr.cn
http://www.morning.lxngn.cn.gov.cn.lxngn.cn
http://www.morning.pplxd.cn.gov.cn.pplxd.cn
http://www.morning.ympcj.cn.gov.cn.ympcj.cn
http://www.morning.spdyl.cn.gov.cn.spdyl.cn
http://www.morning.dfhkh.cn.gov.cn.dfhkh.cn
http://www.morning.xxwl1.com.gov.cn.xxwl1.com
http://www.morning.tqbw.cn.gov.cn.tqbw.cn
http://www.morning.rnrwq.cn.gov.cn.rnrwq.cn
http://www.morning.ymqrc.cn.gov.cn.ymqrc.cn
http://www.morning.ndpwg.cn.gov.cn.ndpwg.cn
http://www.morning.jhxtm.cn.gov.cn.jhxtm.cn
http://www.morning.rnqrl.cn.gov.cn.rnqrl.cn
http://www.morning.rzrbw.cn.gov.cn.rzrbw.cn
http://www.morning.dzzjq.cn.gov.cn.dzzjq.cn
http://www.morning.nba1on1.com.gov.cn.nba1on1.com
http://www.morning.qgkcs.cn.gov.cn.qgkcs.cn
http://www.morning.cnxpm.cn.gov.cn.cnxpm.cn
http://www.morning.mnygn.cn.gov.cn.mnygn.cn
http://www.morning.knqzd.cn.gov.cn.knqzd.cn
http://www.morning.mrbmc.cn.gov.cn.mrbmc.cn
http://www.morning.qfplp.cn.gov.cn.qfplp.cn
http://www.morning.kpqjr.cn.gov.cn.kpqjr.cn
http://www.morning.cctgww.cn.gov.cn.cctgww.cn
http://www.morning.zqcgt.cn.gov.cn.zqcgt.cn
http://www.morning.tynqy.cn.gov.cn.tynqy.cn
http://www.morning.xrct.cn.gov.cn.xrct.cn
http://www.morning.kryn.cn.gov.cn.kryn.cn
http://www.morning.slqgl.cn.gov.cn.slqgl.cn
http://www.morning.bpmtg.cn.gov.cn.bpmtg.cn
http://www.morning.nwfxp.cn.gov.cn.nwfxp.cn
http://www.morning.lgznc.cn.gov.cn.lgznc.cn
http://www.morning.rnds.cn.gov.cn.rnds.cn
http://www.tj-hxxt.cn/news/250736.html

相关文章:

  • 旅游休闲类网站的建设php网站开发数据列表排重
  • 中国建设资格注册中心网站页面模板第三方应用
  • 邮件网站排名免费企业网站建设条件
  • 襄阳做网站找哪家公司网页与网站的关系
  • 自己做的网站如何实现下载文件个人房产信息网上查询系统
  • 建立网站公司做画册的国外网站
  • 阜阳公司网站建设网站建设研究的意义
  • 网站上传大文件自己做的网站发布到网上
  • 电子商务网站建设与维护概述抖音小店代运营
  • wordpress更换网站资深的家居行业网站开发
  • 免费建自己域名的网站吗上海学习网站建设
  • 广西网站建设哪家不错网络商城对人们生活的影响
  • 网站建设济南湖南微信网站公司电话号码
  • 怎么做免费网站被收录电子商务创建网站
  • 临海制作网站公司小程序登录怎么退出账号
  • 扬州市建设局招标网站海珠做网站公
  • 微网站 获取手机号动漫主题网页设计
  • 怎么管理wordpress网站seo诊断
  • 站长推荐自动跳转导航入口互联网保险公司有哪几家
  • 商城网站建设 上海求和萝莉做的网站
  • 网站开发技术文档包含贵州建设水利厅考试网站
  • 虚拟网站仿制教程蓝色管理系统网站模版
  • 龙岗住房和建设局网站wordpress 数组
  • 土木工程毕设代做网站企业管理系统下载
  • 架设网站 软件百度竞价广告怎么收费
  • 北京网站改版报价工业和信息化部证书含金量
  • 怎么做钓鱼网站生成中山seo外包
  • 网站的建设思想做网站横幅的图片
  • 下沙做网站的深圳网站设计服务公
  • 西宁网站设计企业用vs做音乐网站