├── README.md ├── TDMDetailDataForm.h ├── TDMDetailDataForm.ui ├── TDMSummaryTableWgt.cpp ├── TDMSummaryTableWgt.h ├── TDMTrendChartForm.ui ├── images └── vSpacer.png ├── main.cpp ├── pieDemo.pro └── resource.qrc /README.md: -------------------------------------------------------------------------------- 1 | # ComplexMeterTable 2 | QTableView QTableWidget 复杂表头(多行表头) 、冻结、固定特定的行 3 | -------------------------------------------------------------------------------- /TDMDetailDataForm.h: -------------------------------------------------------------------------------- 1 | #ifndef TDMDETAILDATAFORM_H 2 | #define TDMDETAILDATAFORM_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class TDMDetailDataForm; 8 | } 9 | 10 | class TDMDetailDataForm : public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit TDMDetailDataForm(QWidget *parent = 0); 16 | ~TDMDetailDataForm(); 17 | 18 | private: 19 | Ui::TDMDetailDataForm *ui; 20 | }; 21 | 22 | #endif // TDMDETAILDATAFORM_H 23 | -------------------------------------------------------------------------------- /TDMDetailDataForm.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TDMDetailDataForm 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1039 10 | 269 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 0 34 | 35 | 36 | 37 | 38 | QFrame#frame 39 | { 40 | background-color:rgba(246, 248, 251, 1); 41 | } 42 | 43 | QFrame#spacer1, QFrame#spacer2, QFrame#spacer3, QFrame#spacer4, QFrame#spacer5 44 | { 45 | background-color: qlineargradient(spread:reflect, x1:1, y1:0.5, x2:1, y2:0, stop:0 rgba(220, 220, 220, 255), stop:1 rgba(246, 248, 251, 1)); 46 | } 47 | 48 | QLabel#titleLabel1, QLabel#titleLabel2, QLabel#titleLabel3, QLabel#titleLabel4, QLabel#titleLabel5, QLabel#titleLabel6 49 | { 50 | color:#333333; 51 | 52 | font-family:"Microsoft Yahei"; 53 | font-size:16px; 54 | font-weight:bold; 55 | 56 | border-top:none; 57 | border-bottom:none; 58 | 59 | border-right:none; 60 | 61 | background-image: url(:/images/vSpacer.png); 62 | background-repeat:none; 63 | background-position:left; 64 | 65 | 66 | 67 | 68 | margin-left:20px; 69 | padding-left:10px; 70 | 71 | min-height:16px; 72 | max-height:16px; 73 | 74 | 75 | } 76 | 77 | QLabel#continueRateLabel, /*续保率*/ 78 | QLabel#returnRateLabel,/*退费率*/ 79 | QLabel#timeoutConnectLabel,/*超时联系*/ 80 | QLabel#crmBandRateLabel,/*微信CRM绑定率*/ 81 | QLabel#correctRateLabel,/*订正率*/ 82 | QLabel#homeworkSubmitRateLabel,/*作业提交率*/ 83 | QLabel#markingOvertimeLabel,/*超时批改量*/ 84 | QLabel#correctResponseTimeLabel,/*批改响应时长*/ 85 | QLabel#correctTimeLabel,/*批改时长*/ 86 | QLabel#attendanceRateLabel,/*学生出勤率*/ 87 | QLabel#broadcastLateTimesLabel,/*直播迟到次数*/ 88 | QLabel#taskQcScoreLabel,/*作业质检得分*/ 89 | QLabel#taskCorrectErrorLabel,/*作业批错数量*/ 90 | QLabel#questionQcScoreLabel,/*答疑质检得分*/ 91 | QLabel#questionCorrectErrorLabel 92 | { 93 | color:#333333; 94 | font-family:"Microsoft Yahei"; 95 | font-size:14px; 96 | font-weight:bold; 97 | } 98 | 99 | QLabel#continueRateValueLabel,/*续保率*/ 100 | QLabel#returnRateValueLabel,/*退费率*/ 101 | QLabel#timeoutConnectValueLabel,/*超时联系*/ 102 | QLabel#crmBandRateValueLabel,/*微信CRM绑定率*/ 103 | QLabel#correctRateValueLabel,/*订正率*/ 104 | QLabel#homeworkSubmitRateValueLabel,/*作业提交率*/ 105 | QLabel#markingOvertimeValueLabel,/*超时批改量*/ 106 | QLabel#correctResponseTimeValueLabel,/*批改响应时长*/ 107 | QLabel#correctTimeValueLabel,/*批改时长*/ 108 | QLabel#attendanceRateValueLabel,/*学生出勤率*/ 109 | QLabel#broadcastLateTimesValueLabel,/*直播迟到次数*/ 110 | QLabel#taskQcScoreValueLabel,/*作业质检得分*/ 111 | QLabel#taskCorrectErrorValueLabel,/*作业批错数量*/ 112 | QLabel#questionQcScoreValueLabel,/*答疑质检得分*/ 113 | QLabel#questionCorrectErrorValueLabel 114 | { 115 | color:#333333; 116 | font-family:"Microsoft Yahei"; 117 | font-size:14px; 118 | } 119 | 120 | 121 | 122 | 123 | QFrame::StyledPanel 124 | 125 | 126 | QFrame::Raised 127 | 128 | 129 | 130 | 0 131 | 132 | 133 | QLayout::SetMaximumSize 134 | 135 | 136 | 0 137 | 138 | 139 | 0 140 | 141 | 142 | 0 143 | 144 | 145 | 0 146 | 147 | 148 | 149 | 150 | 151 | 0 152 | 0 153 | 154 | 155 | 156 | 157 | 180 158 | 0 159 | 160 | 161 | 162 | 163 | 180 164 | 16777215 165 | 166 | 167 | 168 | 169 | 0 170 | 171 | 172 | 0 173 | 174 | 175 | 20 176 | 177 | 178 | 0 179 | 180 | 181 | 0 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 续报 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | Qt::Vertical 200 | 201 | 202 | 203 | 20 204 | 40 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 2 217 | 0 218 | 219 | 220 | 221 | 222 | 2 223 | 16777215 224 | 225 | 226 | 227 | 228 | 229 | 230 | QFrame::StyledPanel 231 | 232 | 233 | QFrame::Raised 234 | 235 | 236 | 237 | 238 | 239 | 240 | backround:transparent; 241 | 242 | 243 | 244 | 20 245 | 246 | 247 | 0 248 | 249 | 250 | 20 251 | 252 | 253 | 9 254 | 255 | 256 | 0 257 | 258 | 259 | 260 | 261 | 续报 262 | 263 | 264 | 265 | 266 | 267 | 268 | 10 269 | 270 | 271 | QLayout::SetMinimumSize 272 | 273 | 274 | 34 275 | 276 | 277 | 278 | 279 | 续报率 280 | 281 | 282 | 283 | 284 | 285 | 286 | 85% 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 34 296 | 297 | 298 | 299 | 300 | 退费率 301 | 302 | 303 | 304 | 305 | 306 | 307 | 80% 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | Qt::Vertical 317 | 318 | 319 | 320 | 20 321 | 124 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 2 334 | 0 335 | 336 | 337 | 338 | 339 | 2 340 | 16777215 341 | 342 | 343 | 344 | 345 | 346 | 347 | QFrame::StyledPanel 348 | 349 | 350 | QFrame::Raised 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 20 359 | 360 | 361 | 0 362 | 363 | 364 | 20 365 | 366 | 367 | 9 368 | 369 | 370 | 0 371 | 372 | 373 | 374 | 375 | 沟通 376 | 377 | 378 | 379 | 380 | 381 | 382 | 10 383 | 384 | 385 | QLayout::SetMinimumSize 386 | 387 | 388 | 34 389 | 390 | 391 | 392 | 393 | 超时联系 394 | 395 | 396 | 397 | 398 | 399 | 400 | 20(10%) 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 10 410 | 411 | 412 | QLayout::SetMinimumSize 413 | 414 | 415 | 34 416 | 417 | 418 | 419 | 420 | 微信CRM绑定率 421 | 422 | 423 | 424 | 425 | 426 | 427 | 85% 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | Qt::Vertical 437 | 438 | 439 | 440 | 20 441 | 124 442 | 443 | 444 | 445 | 446 | 447 | titleLabel3 448 | verticalSpacer_2 449 | 450 | 451 | 452 | 453 | 454 | 455 | 2 456 | 0 457 | 458 | 459 | 460 | 461 | 2 462 | 16777215 463 | 464 | 465 | 466 | 467 | 468 | 469 | QFrame::StyledPanel 470 | 471 | 472 | QFrame::Raised 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 20 481 | 482 | 483 | 0 484 | 485 | 486 | 20 487 | 488 | 489 | 9 490 | 491 | 492 | 0 493 | 494 | 495 | 496 | 497 | 作业批改 498 | 499 | 500 | 501 | 502 | 503 | 504 | 10 505 | 506 | 507 | QLayout::SetMinimumSize 508 | 509 | 510 | 34 511 | 512 | 513 | 514 | 515 | 订正率 516 | 517 | 518 | 519 | 520 | 521 | 522 | 20(10%) 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 10 532 | 533 | 534 | QLayout::SetMinimumSize 535 | 536 | 537 | 34 538 | 539 | 540 | 541 | 542 | 作业提交率 543 | 544 | 545 | 546 | 547 | 548 | 549 | 85% 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 10 559 | 560 | 561 | QLayout::SetMinimumSize 562 | 563 | 564 | 34 565 | 566 | 567 | 568 | 569 | 超时批改量 570 | 571 | 572 | 573 | 574 | 575 | 576 | 85 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 10 586 | 587 | 588 | QLayout::SetMinimumSize 589 | 590 | 591 | 34 592 | 593 | 594 | 595 | 596 | 批改响应时长 597 | 598 | 599 | 600 | 601 | 602 | 603 | 85min 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 10 613 | 614 | 615 | QLayout::SetMinimumSize 616 | 617 | 618 | 34 619 | 620 | 621 | 622 | 623 | 批改时长 624 | 625 | 626 | 627 | 628 | 629 | 630 | 120s 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | Qt::Vertical 640 | 641 | 642 | 643 | 20 644 | 0 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 2 657 | 0 658 | 659 | 660 | 661 | 662 | 2 663 | 16777215 664 | 665 | 666 | 667 | 668 | 669 | 670 | QFrame::StyledPanel 671 | 672 | 673 | QFrame::Raised 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 20 682 | 683 | 684 | 0 685 | 686 | 687 | 20 688 | 689 | 690 | 9 691 | 692 | 693 | 0 694 | 695 | 696 | 697 | 698 | 直播 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 10 707 | 708 | 709 | QLayout::SetMinimumSize 710 | 711 | 712 | 34 713 | 714 | 715 | 716 | 717 | 学生出勤率 718 | 719 | 720 | 721 | 722 | 723 | 724 | 85% 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 10 735 | 736 | 737 | QLayout::SetMinimumSize 738 | 739 | 740 | 34 741 | 742 | 743 | 744 | 745 | 直播迟到次数 746 | 747 | 748 | 749 | 750 | 751 | 752 | 5 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | Qt::Vertical 762 | 763 | 764 | 765 | 20 766 | 124 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 2 779 | 0 780 | 781 | 782 | 783 | 784 | 2 785 | 16777215 786 | 787 | 788 | 789 | 790 | 791 | 792 | QFrame::StyledPanel 793 | 794 | 795 | QFrame::Raised 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 20 804 | 805 | 806 | 0 807 | 808 | 809 | 20 810 | 811 | 812 | 9 813 | 814 | 815 | 0 816 | 817 | 818 | 819 | 820 | 质检 821 | 822 | 823 | 824 | 825 | 826 | 827 | 10 828 | 829 | 830 | QLayout::SetMinimumSize 831 | 832 | 833 | 34 834 | 835 | 836 | 837 | 838 | 作业质检得分 839 | 840 | 841 | 842 | 843 | 844 | 845 | 2.0 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 10 855 | 856 | 857 | QLayout::SetMinimumSize 858 | 859 | 860 | 34 861 | 862 | 863 | 864 | 865 | 作业批错数量 866 | 867 | 868 | 869 | 870 | 871 | 872 | 8 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 10 882 | 883 | 884 | QLayout::SetMinimumSize 885 | 886 | 887 | 34 888 | 889 | 890 | 891 | 892 | 答疑质检得分 893 | 894 | 895 | 896 | 897 | 898 | 899 | 3.5 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 10 909 | 910 | 911 | QLayout::SetMinimumSize 912 | 913 | 914 | 34 915 | 916 | 917 | 918 | 919 | 答疑错误量 920 | 921 | 922 | 923 | 924 | 925 | 926 | 5 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | Qt::Vertical 936 | 937 | 938 | 939 | 20 940 | 40 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | dutyFinishedWgt 950 | resubmitWgt 951 | communicateWgt 952 | homeworkWgt 953 | broadcastWgt 954 | qcWgt 955 | spacer1 956 | spacer2 957 | spacer3 958 | spacer4 959 | spacer5 960 | 961 | 962 | 963 | 964 | 965 | 966 | PieForm 967 | QWidget 968 |
PieForm.h
969 | 1 970 |
971 |
972 | 973 | 974 |
975 | -------------------------------------------------------------------------------- /TDMSummaryTableWgt.cpp: -------------------------------------------------------------------------------- 1 | #pragma execution_character_set("utf-8") 2 | #include "TDMSummaryTableWgt.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | TDMSummaryTableWgt::TDMSummaryTableWgt(QWidget *parent) 14 | : QTableWidget(parent) 15 | { 16 | 17 | initFrozenFrame(); 18 | initFrame(); 19 | 20 | //测试数据 21 | for(int i = 0; i< 10; i++) 22 | appendRowData(); 23 | 24 | } 25 | 26 | TDMSummaryTableWgt::~TDMSummaryTableWgt() 27 | { 28 | delete m_frozenTableWgt; 29 | } 30 | 31 | void TDMSummaryTableWgt::appendRowData() 32 | { 33 | if (rowCount() >= ROWCOUNTPERPAGE) 34 | return; 35 | 36 | //添加到最后一行 37 | int rowIndex = rowCount(); 38 | setRowCount(rowIndex + 1); 39 | 40 | //设置行高 41 | setRowHeight(rowIndex, ROWHEIGHT); 42 | 43 | //填充最后一行的内容 44 | for(int col = 0; col < 9; col++) { 45 | setItem(rowIndex, col, new QTableWidgetItem(QString("item%1%2").arg(rowIndex).arg(col))); 46 | item(rowIndex, col)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 47 | } 48 | 49 | //查看趋势图按钮 50 | QFrame *frame = new QFrame(this); 51 | QPushButton *btn = new QPushButton("查看趋势图"); 52 | btn->setStyleSheet(QString("QPushButton{color:#1564FF; background:transparent; " 53 | "font-family:\"微软雅黑\";" 54 | "font-size:12px;" 55 | "border:1px solid #1564FF;" 56 | "border-radius:4px;" 57 | "min-width:80px; max-width:80px;" 58 | "min-height:24px; max-height:24px;}" 59 | "QPushButton:hover{color:#FFFFFF; background-color:#1F51B3;}" 60 | "QPushButton:checked:{color:#FFFFFF;background-color:#264279;}")); 61 | btn->setCheckable(true); 62 | connect(btn, &QPushButton::clicked, this, [=]{ 63 | emit sigViewBtnClicked(rowIndex); 64 | }); 65 | 66 | QHBoxLayout *layout = new QHBoxLayout(); 67 | layout->addWidget(btn); 68 | layout->addSpacerItem(new QSpacerItem(20,20, QSizePolicy::Expanding)); 69 | frame->setLayout(layout); 70 | 71 | setCellWidget(rowIndex, 9, frame); 72 | } 73 | 74 | void TDMSummaryTableWgt::initFrame() 75 | { 76 | clearContents(); 77 | setColumnCount(10); 78 | horizontalHeader()->setVisible(true);//表头不可见 79 | int headerHeight = m_frozenTableWgt->rowHeight(0) + 80 | m_frozenTableWgt->rowHeight(1);//设置成被m_frozenTableWgt遮挡住 81 | horizontalHeader()->setFixedHeight(headerHeight); 82 | verticalHeader()->setVisible(false);//表头不可见 83 | setShowGrid(false);//网格线不可见 84 | setEditTriggers(QAbstractItemView::NoEditTriggers);//设置单元格不可编辑 85 | setSelectionMode(QAbstractItemView::SingleSelection);//单选 86 | setSelectionBehavior(QAbstractItemView::SelectRows);//选行` 87 | horizontalHeader()->setStretchLastSection(true);//最后一个单元格扩展 88 | setFocusPolicy(Qt::NoFocus);//解决选中虚框问题 89 | setFrameShape(QFrame::NoFrame);//去除边框 90 | 91 | setVerticalScrollMode(ScrollPerPixel); 92 | setHorizontalScrollMode(ScrollPerPixel); 93 | 94 | setItemDelegate(new ItemDelegate(1));//设置绘画代理(主要在代理中画出来header) 95 | } 96 | 97 | void TDMSummaryTableWgt::initFrozenFrame() 98 | { 99 | m_frozenTableWgt = new QTableWidget(this); 100 | 101 | m_frozenTableWgt->horizontalHeader()->setVisible(false);//表头不可见 102 | m_frozenTableWgt->verticalHeader()->setVisible(false);//表头不可见 103 | m_frozenTableWgt->setShowGrid(false);//网格线不可见 104 | m_frozenTableWgt->setEditTriggers(QAbstractItemView::NoEditTriggers);//设置单元格不可编辑 105 | m_frozenTableWgt->horizontalHeader()->setStretchLastSection(true);//最后一个单元格扩展 106 | m_frozenTableWgt->setFocusPolicy(Qt::NoFocus);//解决选中虚框问题 107 | m_frozenTableWgt->setFrameShape(QFrame::NoFrame);//去除边框 尴尬 108 | m_frozenTableWgt->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);//隐藏滚动条 109 | m_frozenTableWgt->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);// 110 | m_frozenTableWgt->setHorizontalScrollMode(ScrollPerPixel); 111 | 112 | m_frozenTableWgt->setItemDelegate(new ItemDelegate(0));//设置绘画代理(主要在代理中画出来header) 113 | 114 | viewport()->stackUnder(m_frozenTableWgt);//设置窗口层次 115 | 116 | m_frozenTableWgt->setColumnCount(10);//header10列 117 | m_frozenTableWgt->setRowCount(2);//header2行 118 | 119 | m_frozenTableWgt->setRowHeight(0, 42);//第一行设置高度42px 120 | m_frozenTableWgt->setRowHeight(1, 42);//第二行设置高度42px 121 | 122 | for (int row = 2; row < m_frozenTableWgt->rowCount(); ++row)//隐藏2行后的行 123 | m_frozenTableWgt->setRowHidden(row, true); 124 | 125 | //===================设置header内容=================// 126 | //合并单元格 127 | m_frozenTableWgt->setSpan(0, 0, 2, 1);//老师ID 128 | m_frozenTableWgt->setSpan(0, 1, 2, 1);//老师姓名 129 | m_frozenTableWgt->setSpan(0, 2, 2, 1);//老师姓名 130 | m_frozenTableWgt->setSpan(0, 3, 1, 4);//最新日期(8月20) 131 | m_frozenTableWgt->setSpan(0, 7, 1, 2);//前一日(8月19) 132 | m_frozenTableWgt->setSpan(0, 9, 2, 1);//操作 133 | 134 | m_frozenTableWgt->setItem(0, 0, new QTableWidgetItem("老师ID")); 135 | m_frozenTableWgt->setItem(0, 1, new QTableWidgetItem("老师姓名")); 136 | m_frozenTableWgt->setItem(0, 2, new QTableWidgetItem("老师姓名")); 137 | m_frozenTableWgt->setItem(0, 3, new QTableWidgetItem("8月20日")); 138 | m_frozenTableWgt->setItem(0, 7, new QTableWidgetItem("8月19日")); 139 | m_frozenTableWgt->setItem(0, 9, new QTableWidgetItem("操作")); 140 | m_frozenTableWgt->setItem(1, 3, new QTableWidgetItem("续报率")); 141 | m_frozenTableWgt->setItem(1, 4, new QTableWidgetItem("新学员续报率")); 142 | m_frozenTableWgt->setItem(1, 5, new QTableWidgetItem("续报增长人数")); 143 | m_frozenTableWgt->setItem(1, 6, new QTableWidgetItem("续报增长率")); 144 | m_frozenTableWgt->setItem(1, 7, new QTableWidgetItem("续报增长率")); 145 | m_frozenTableWgt->setItem(1, 8, new QTableWidgetItem("新学员续报率")); 146 | 147 | //连接信号槽。用于滚动条联动 148 | connect(m_frozenTableWgt->verticalScrollBar(), &QAbstractSlider::valueChanged, 149 | verticalScrollBar(), &QAbstractSlider::setValue); 150 | connect(verticalScrollBar(), &QAbstractSlider::valueChanged, 151 | m_frozenTableWgt->verticalScrollBar(), &QAbstractSlider::setValue); 152 | 153 | updateFrozenTableGeometry();//更新位置 154 | m_frozenTableWgt->show(); 155 | } 156 | 157 | void TDMSummaryTableWgt::updateFrozenTableGeometry() 158 | { 159 | m_frozenTableWgt->setGeometry(frameWidth(), 160 | frameWidth(), 161 | viewport()->width(), 162 | horizontalHeader()->height()); 163 | 164 | } 165 | 166 | void TDMSummaryTableWgt::resizeEvent(QResizeEvent *event) 167 | { 168 | QTableView::resizeEvent(event); 169 | updateFrozenTableGeometry(); 170 | } 171 | 172 | QModelIndex TDMSummaryTableWgt::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers) 173 | { 174 | QModelIndex current = QTableView::moveCursor(cursorAction, modifiers); 175 | 176 | if (cursorAction == MoveUp && current.row() > 0 177 | && visualRect(current).topLeft().y() < m_frozenTableWgt->rowHeight(1) ){ 178 | const int newValue = verticalScrollBar()->value() + visualRect(current).topLeft().y() 179 | - m_frozenTableWgt->rowHeight(0) - m_frozenTableWgt->rowHeight(1); 180 | verticalScrollBar()->setValue(newValue); 181 | } 182 | return current; 183 | } 184 | 185 | void TDMSummaryTableWgt::scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint) 186 | { 187 | if (index.row() > 0) 188 | QTableView::scrollTo(index, hint); 189 | 190 | } 191 | 192 | 193 | 194 | ItemDelegate::ItemDelegate(int type, QObject *parent) 195 | : QStyledItemDelegate(parent), 196 | m_type(type) 197 | { 198 | 199 | } 200 | 201 | void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 202 | { 203 | if(0 == m_type) //header tablewidget 204 | { 205 | int rowIndex = index.row();//行号 206 | int colIndex = index.column();//列号 207 | if (rowIndex == 0 || rowIndex == 1)//前两行作为header 208 | { 209 | //背景 210 | QColor color; 211 | 212 | if (rowIndex == 0 && (colIndex == 0 || //老师ID 213 | colIndex == 1 || //老师姓名 214 | colIndex == 2 || //课程类型 215 | colIndex == 9)) //操作 216 | { 217 | color.setRgb(231, 238, 251); 218 | } 219 | else if ((rowIndex == 0 && colIndex == 3) || //8月20日 220 | (rowIndex == 1 && (colIndex == 3 || //续报率 221 | colIndex == 4 || //新学员续报率 222 | colIndex == 5 || //续报增长人数 223 | colIndex == 6))) //续报增长率 224 | { 225 | color.setRgb(214, 228, 253); 226 | } 227 | else if ((rowIndex == 0 && colIndex == 7) || //8月19日 228 | (rowIndex == 1 && (colIndex == 7 || //续报率 229 | colIndex == 8))) //新学员续报率 230 | { 231 | color.setRgb(203, 221, 255); 232 | } 233 | 234 | //绘制背景 235 | painter->setPen(color); 236 | painter->setBrush(QBrush(color)); 237 | painter->drawRect(option.rect); 238 | 239 | //右侧spacer 240 | if ((rowIndex == 0 && (colIndex == 0 || colIndex == 1) )) { 241 | int startX = option.rect.right(); 242 | int startY = option.rect.y() + (option.rect.height() - 40) / 2; 243 | int endX = startX; 244 | int endY = startY + 40; 245 | QLinearGradient linearGradient(startX, startY, endX, endY); 246 | linearGradient.setColorAt(0, QColor(164, 188, 240, 0)); 247 | linearGradient.setColorAt(0.5, QColor(164, 188, 240, 255)); 248 | linearGradient.setColorAt(1, QColor(164, 188, 240, 0)); 249 | painter->setBrush(linearGradient); 250 | painter->drawRect(option.rect.right()- 2, startY, 2, 40); 251 | 252 | } 253 | else if (rowIndex == 1 && (colIndex == 3 || 254 | colIndex == 4 || 255 | colIndex == 5 || 256 | colIndex == 7 )) { 257 | 258 | int startX = option.rect.right(); 259 | int startY = option.rect.y() + (option.rect.height() - 28) / 2; 260 | int endX = startX; 261 | int endY = startY + 28; 262 | QLinearGradient linearGradient(startX, startY, endX, endY); 263 | linearGradient.setColorAt(0, QColor(164, 188, 240, 0)); 264 | linearGradient.setColorAt(0.5, QColor(164, 188, 240, 255)); 265 | linearGradient.setColorAt(1, QColor(164, 188, 240, 0)); 266 | painter->setBrush(linearGradient); 267 | painter->drawRect(option.rect.right()- 2, startY, 2, 28); } 268 | 269 | //字体 270 | painter->setPen(QColor(51, 51, 51)); 271 | QTextOption op; 272 | op.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 273 | 274 | QFont font; 275 | font.setFamily("Microsoft YaHei"); 276 | font.setPixelSize(14); 277 | font.setBold(true); 278 | painter->setFont(font); 279 | 280 | QRect rect; 281 | if (rowIndex == 0 && colIndex == 9){//"操作" 左对齐 282 | rect = QRect(option.rect.x(), option.rect.y(), 100, option.rect.height()); 283 | } 284 | else {//其他的居中 285 | rect = option.rect; 286 | } 287 | 288 | painter->drawText(rect, index.data(Qt::DisplayRole).toString(), op); 289 | 290 | } 291 | 292 | } 293 | else { //content table widget 294 | //文字 295 | painter->setPen(QColor(102, 102, 102)); 296 | QTextOption op; 297 | op.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); 298 | 299 | QFont font; 300 | font.setFamily("Microsoft YaHei"); 301 | font.setPixelSize(12); 302 | painter->setFont(font); 303 | 304 | if( option.state & QStyle::State_Selected ) { 305 | painter->fillRect( option.rect, QBrush(QColor(239,244,255))); 306 | } 307 | 308 | painter->drawText(option.rect, index.data(Qt::DisplayRole).toString(), op); 309 | 310 | //底边框 311 | painter->setPen(QColor(248,251,255)); 312 | painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); 313 | 314 | } 315 | } 316 | 317 | -------------------------------------------------------------------------------- /TDMSummaryTableWgt.h: -------------------------------------------------------------------------------- 1 | #ifndef TDMSUMMARYTABLEWGT_H 2 | #define TDMSUMMARYTABLEWGT_H 3 | 4 | #include 5 | #include 6 | 7 | #define ROWCOUNTPERPAGE 15 8 | #define ROWHEIGHT 60//行高 9 | 10 | class TDMSummaryTableWgt : public QTableWidget 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit TDMSummaryTableWgt(QWidget *parent = 0); 15 | ~TDMSummaryTableWgt(); 16 | 17 | /** 18 | * @brief appendRowData 添加一行数据到最后一行 19 | */ 20 | void appendRowData(); 21 | 22 | signals: 23 | void sigViewBtnClicked(int i); 24 | 25 | protected: 26 | /** 27 | * @brief resizeEvent 重载虚函数 resize事件,同时更新m_frozenTableWgt的位置 28 | * @param event 29 | */ 30 | virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; 31 | 32 | /** 33 | * @brief moveCursor 重载虚函数 鼠标移动事件 34 | * @param cursorAction 35 | * @param modifiers 36 | * @return 37 | */ 38 | virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) Q_DECL_OVERRIDE; 39 | 40 | /** 41 | * @brief scrollTo TableWidget移动事件 42 | * @param index 43 | * @param hint 44 | */ 45 | void scrollTo (const QModelIndex & index, ScrollHint hint = EnsureVisible) Q_DECL_OVERRIDE; 46 | 47 | 48 | private: 49 | /** 50 | * @brief initFrozenTable 初始化被冻结tableWidget 51 | */ 52 | void initFrozenFrame(); 53 | 54 | /** 55 | * @brief updateFrozenTableGeometry 更新被冻结的tableWidget位置 56 | */ 57 | void updateFrozenTableGeometry(); 58 | 59 | /** 60 | * @brief initFrame 初始化显示内容的tableWidget 61 | */ 62 | void initFrame(); 63 | 64 | private: 65 | QTableWidget *m_frozenTableWgt;// 使用TableWidget 作为header,并冻结 66 | 67 | }; 68 | 69 | class ItemDelegate : public QStyledItemDelegate 70 | { 71 | Q_OBJECT 72 | public: 73 | ItemDelegate(int type, QObject *parent=0); 74 | 75 | void paint(QPainter *painter, 76 | const QStyleOptionViewItem &option, const QModelIndex &index) const; 77 | 78 | private: 79 | int m_type;//type=0: header type=1:content 80 | }; 81 | 82 | 83 | #endif // TDMSUMMARYTABLEWGT_H 84 | -------------------------------------------------------------------------------- /TDMTrendChartForm.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TDMTrendChartForm 4 | 5 | 6 | 7 | 0 8 | 0 9 | 677 10 | 382 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | background-color: rgb(248, 251, 255); 18 | 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 0 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | QChartView 47 | QGraphicsView 48 |
qchartview.h
49 |
50 |
51 | 52 | 53 |
54 | -------------------------------------------------------------------------------- /images/vSpacer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezhongyuan/ComplexMeterTable/0d11ad0bc8e5b4e7f14eab647d96de2d0a8f8852/images/vSpacer.png -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "TDMDetailDataForm.h" 4 | 5 | #include "TDMSummaryTableWgt.h" 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | QApplication a(argc, argv); 10 | // MainWindow w; 11 | // TDMTrendChartForm w; 12 | TDMSummaryTableWgt w; 13 | w.resize(1000,600); 14 | w.show(); 15 | 16 | return a.exec(); 17 | } 18 | -------------------------------------------------------------------------------- /pieDemo.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2018-09-13T11:09:51 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui charts 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = pieDemo1 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | TDMSummaryTableWgt.cpp 17 | 18 | HEADERS += \ 19 | TDMSummaryTableWgt.h 20 | 21 | FORMS += \ 22 | TDMTrendChartForm.ui 23 | 24 | RESOURCES += \ 25 | resource.qrc 26 | -------------------------------------------------------------------------------- /resource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/vSpacer.png 4 | 5 | 6 | --------------------------------------------------------------------------------