wince_btn 建造者

本文介绍了一个用于Windows CE环境下按钮构建与绘制的类库,包括按钮初始化、文本绘制等功能,并详细展示了如何使用该类库来创建和管理按钮。

#pragma once
#include "LAYOUT_BTN_INFO.h"
#include <vector>
#include "..//..//SourceWinCE600//MFC_UI//ButtonEx//UniBtnEx.h"
#include "..//..//SourceWinCE600//SdeFont//SdeFontEx.h"
#include "..//..//SourceWinCE600//MFC_2D.h"


using namespace std;

class BuildBtns
{
public:
 BuildBtns();
 virtual ~BuildBtns(void){ UnInit(); }
 int Init(const BTN_INFO btnInfo[], int iStart, int iEnd,
  CDC* pDC, CRect rtSrc);
 void UnInit();
 static void Build_AButton(CUniBtnEx& o_btnDest, const HRGN hRgn,
  CWnd* pParentWnd,int nID,int nImgID);

 static bool drawText(CDC* i_pCDC, CString strText, CRect rtDest,
  CSize sizeText, COLORREF cls, UINT uSign);

private:
 struct BMPS
 {
  CPoint objPoint;
  CSize objSize;
  BMPS()
  {
   bmp[0] = bmp[1] = NULL;
  }
  CBitmap* bmp[2];
 };
 static vector<BMPS> m_vtBMPS;
};


extern BuildBtns g_BuildBtnser;

 

//////////////////////////////////////////////////////////////////////////////////////////////

 

 

#include "StdAfx.h"
#include "BuildBtns.h"
#include "..//..//SourceWinCE600//MFC_2D.h"
#include "..//..//SourceWinCE600//COM_IMAGE.h"

 

BuildBtns g_BuildBtnser;

vector<BuildBtns::BMPS> BuildBtns::m_vtBMPS;

static bool DEBUG_IS_PRODUCE = true;


BuildBtns::BuildBtns()
{
}

bool BuildBtns::drawText(CDC* i_pCDC, CString strText, CRect rtDest,
       CSize sizeText, COLORREF cls, UINT uSign)
{
 if( NULL == i_pCDC)
  return false;
 CSdeFontEx::SetEvent(true);
 CSdeFontEx::SetTextColor(cls);
 CSdeFontEx::SetFontSize(sizeText.cx,sizeText.cy);
 CSdeFontEx::DrawText(i_pCDC,strText,&rtDest,uSign);
 CSdeFontEx::PrevFontSize();
 CSdeFontEx::PrevTextColor();
 CSdeFontEx::SetEvent(false);
 return true;
}

int BuildBtns::Init(const BTN_INFO btnInfo[], int iStart, int iEnd,
     CDC* pDC, CRect rtSrc)
{
 if( DEBUG_IS_PRODUCE)
 {
  if( NULL == pDC)
   return 0;
  CDCEx* pcdcBk = NULL;
  CDCEx* pImgDC = NULL;

  try
  {
   pcdcBk = new CDCEx(CSize(rtSrc.Width(),rtSrc.Height()),pDC, rtSrc);
  }
  catch (std::exception *e)
  {
   pcdcBk = NULL;
   return 0;
  }


  for(int i=iStart; i<iEnd; i++)
  {
   //大背景
   pcdcBk->drawImg(btnInfo[i].strSrcPath[0],&rtSrc,NULL);

   BMPS btnBmp;
   btnBmp.objPoint = btnInfo[i].point;
   btnBmp.objSize = btnInfo[i].csSrc;
   CRect rtBtnDest(0,0,btnBmp.objSize.cx,btnBmp.objSize.cy);
   CRect rtBtnSrc(btnBmp.objPoint.x,btnBmp.objPoint.y,
     btnBmp.objPoint.x+btnBmp.objSize.cx,
     btnBmp.objPoint.y+btnBmp.objSize.cy);
   
   //小背景
   pImgDC = NULL;
   try
   {
    pImgDC = new CDCEx(CSize(btnBmp.objSize.cx,btnBmp.objSize.cy),pDC, rtBtnDest);
   }
   catch (std::exception *e)
   {
    pImgDC = NULL;
    return 0;
   }

   if( NULL != pImgDC)
   {
    //BtnBackground
    ((CDC*)*pImgDC)->StretchBlt(
     rtBtnDest.left,rtBtnDest.top,rtBtnDest.Width(),rtBtnDest.Height(),
     (CDC*)*pcdcBk,
     rtBtnSrc.left,rtBtnSrc.top,rtBtnSrc.Width(),rtBtnSrc.Height(),
     SRCCOPY);

    //BtnImg
    CBitmap* pbmpBk = NULL;
    pbmpBk = pImgDC->save(CSize(btnBmp.objSize.cx,btnBmp.objSize.cy),rtBtnDest);
    if( NULL != pbmpBk)
    {
     for(int j=0; j<2; j++)
     {
      pImgDC->draw(rtBtnDest,pbmpBk,rtBtnDest);
      pImgDC->drawImg(btnInfo[i].strSrcPath[j+1]);
      btnBmp.bmp[j] = pImgDC->save(CSize(rtBtnSrc.Width(),rtBtnSrc.Height()),CRect(0,0,rtBtnSrc.Width(),rtBtnSrc.Height()));
     }
     delete pbmpBk;
     pbmpBk = NULL;
    }

    delete pImgDC;
    pImgDC = NULL;
   }

   m_vtBMPS.push_back(btnBmp);
  }

  delete pcdcBk;
  pcdcBk = NULL;

  return m_vtBMPS.size();
 }
 else
 {
  for(int i=iStart; i<iEnd; i++)
  {
   BMPS btnBmp;
   btnBmp.objPoint = btnInfo[i].point;
   btnBmp.objSize = btnInfo[i].csSrc;
   CRect rtBtnDest(0,0,btnBmp.objSize.cx,btnBmp.objSize.cy);
   CRect rtBtnSrc(btnBmp.objPoint.x,btnBmp.objPoint.y,
     btnBmp.objPoint.x+btnBmp.objSize.cx,
     btnBmp.objPoint.y+btnBmp.objSize.cy);
   m_vtBMPS.push_back(btnBmp);
  }

  return m_vtBMPS.size();
 }
}

void BuildBtns::UnInit()
{
 if( DEBUG_IS_PRODUCE)
 {
  for(int i=0; i<m_vtBMPS.size(); i++)
  {
   delete m_vtBMPS[i].bmp[0];
   delete m_vtBMPS[i].bmp[1];
  }
 }
 else
 {
  NULL;
 }
}

void BuildBtns::Build_AButton(CUniBtnEx& o_btnDest, const HRGN hRgn,
         CWnd* pParentWnd, int nID, int nImgID)
{
 if( DEBUG_IS_PRODUCE)
 {
  o_btnDest.Create(m_vtBMPS[nImgID].objPoint,
   hRgn, pParentWnd, nID,0,
   L"",
   m_vtBMPS[nImgID].bmp[0],
   m_vtBMPS[nImgID].bmp[1],
   m_vtBMPS[nImgID].bmp[0],
   m_vtBMPS[nImgID].bmp[0]
   );
 }
 else
 {
  o_btnDest.Create(m_vtBMPS[nImgID].objPoint,
   hRgn, pParentWnd, nID,0,
   L"",
   RGB(255,0,0),
   RGB(0,255,0),
   RGB(0,0,255),
   RGB(192,192,192)
  );
 }
}

self.tab1=create_tab.CreateTab.create_tab1 class CreateTab: def __init__(self,image_btn,file_path_btn,previous_image_btn,next_image_btn, video_btn, camera_btn,stop_btn,save_btn): self.image_btn=image_btn self.file_path_btn = file_path_btn self.previous_image_btn = previous_image_btn self.next_image_btn = next_image_btn self.video_btn = video_btn self.camera_btn = camera_btn self.stop_btn = stop_btn self.save_btn = save_btn def create_tab1(self): """创建第一个标签页""" tab = QWidget() # layout = QVBoxLayout(tab) buttons_layout = QVBoxLayout(tab) buttons_layout.setSpacing(12) buttons_layout.setContentsMargins(12, 12, 12, 8) row1_layout = QHBoxLayout() row1_layout.setSpacing(12) self.image_btn = UiMainTestStyle.create_button(self, "图片检测", "#00c8ff") self.file_path_btn = UiMainTestStyle.create_button(self, "文件检测", "#00a0c0") self.previous_image_btn = UiMainTestStyle.create_button(self, "上一张", "#ff4a4a") self.next_image_btn = UiMainTestStyle.create_button(self, "下一张", "#a04aff") row1_layout.addWidget(self.image_btn) row1_layout.addWidget(self.file_path_btn) row1_layout.addWidget(self.previous_image_btn) row1_layout.addWidget(self.next_image_btn) row2_layout = QHBoxLayout() row2_layout.setSpacing(12) self.video_btn = UiMainTestStyle.create_button(self, "视频检测", "#00a0c0") self.camera_btn = UiMainTestStyle.create_button(self, "摄像头检测", "#00c8dd") row2_layout.addWidget(self.video_btn) row2_layout.addWidget(self.camera_btn) row3_layout = QHBoxLayout() row3_layout.setSpacing(12) self.stop_btn = UiMainTestStyle.create_button(self, "停止检测", "#ff4a4a") self.save_btn = UiMainTestStyle.create_button(self, "保存结果", "#a04aff") row3_layout.addWidget(self.stop_btn) row3_layout.addWidget(self.save_btn) buttons_layout.addLayout(row1_layout) buttons_layout.addLayout(row2_layout) buttons_layout.addLayout(row3_layout) buttons_layout.addWidget(self.save_btn) print(tab) return tab self.tab1=create_tab.CreateTab.create_tab1为什么无法调用
最新发布
10-12
<think>问题分析: 在提供的代码片段中,您试图通过 `create_tab.CreateTab.create_tab1` 来创建标签页,但是这种方式是不正确的,原因如下: 1. `create_tab1` 是 `CreateTab` 类的一个实例方法,而不是类方法或静态方法。因此,它必须通过 `CreateTab` 的实例来调用,而不是直接通过类调用。 2. 在 `CreateTab` 的构造函数中,需要传入多个按钮参数,但在调用 `create_tab1` 时并没有创建 `CreateTab` 的实例。 3. 在 `create_tab1` 方法内部,又重新创建了按钮(例如 `self.image_btn = ...`),这与构造函数中传入的按钮参数相冲突,而且传入的按钮参数也没有被使用。 解决方案: 有两种改进方式: 方式一:如果每个标签页的按钮都是独立的,那么不需要在构造时传入按钮,而是在创建标签页时内部创建。但这样会导致信号槽连接需要单独处理。 方式二:如果希望多个标签页共享相同的按钮功能(即点击不同标签页的相同按钮执行相同操作),那么可以复用按钮实例,但需要调整 `CreateTab` 类的设计。 考虑到您之前的问题,我建议采用以下设计: 1. 将按钮的创建放在外部,然后将这些按钮传入 `CreateTab` 类,这样同一个按钮可以添加到多个标签页(注意:同一个按钮只能有一个父控件,不能同时添加到多个标签页)。 2. 因此,每个标签页应该有自己的按钮实例,但按钮的功能(槽函数)可以相同。 所以,修改 `CreateTab` 类,使其在创建标签页时创建新的按钮,并连接信号。同时,为了能够连接信号,需要将槽函数也传入或者通过其他方式绑定。 然而,从您的代码看,您似乎希望将按钮作为参数传入,但又在 `create_tab1` 内部重新创建,这是矛盾的。 重新设计: 我们不再将按钮作为构造参数,而是在 `CreateTab` 类的每个创建方法中创建新的按钮。同时,为了能够连接信号,我们可以在创建按钮后连接到一个统一的槽函数(通过外部传入的槽函数或使用信号转发机制)。 但是,您当前的调用方式 `self.tab1=create_tab.CreateTab.create_tab1` 是错误的,因为 `create_tab1` 是实例方法,需要创建 `CreateTab` 的实例。 让我们重构 `CreateTab` 类: 方案A:使用实例方法,每个标签页创建自己的按钮。 ```python class CreateTab: def __init__(self, parent=None): self.parent = parent # 如果需要访问父窗口的槽函数,可以保存父窗口引用 def create_tab1(self): """创建第一个标签页""" tab = QWidget() layout = QVBoxLayout(tab) # 创建按钮 image_btn = UiMainTestStyle.create_button(self.parent, "图片检测", "#00c8ff") # ... 创建其他按钮 ... # 连接信号 image_btn.clicked.connect(self.parent.detect_image) # 假设父窗口有detect_image方法 # 布局按钮... return tab ``` 然后在主窗口中: ```python # 创建CreateTab实例,传入主窗口作为parent(以便连接主窗口的槽函数) tab_creator = CreateTab(self) self.tab1 = tab_creator.create_tab1() ``` 方案B:将按钮创建和布局独立出来,复用相同布局代码。 考虑到多个标签页的布局相同,我们可以写一个通用的创建标签页的方法。 但是,根据您最初的需求,您希望多个标签页都有相同的按钮布局,并且按钮都能工作。因此,我们采用每个标签页独立创建按钮的方式。 下面是完整的修正代码示例: 首先,修改 `CreateTab` 类: ```python class CreateTab: def __init__(self, parent): """初始化标签页创建器,需要传入父窗口(用于连接信号和样式)""" self.parent = parent def create_general_tab(self): """创建一个通用的标签页,包含所有按钮""" tab = QWidget() layout = QVBoxLayout(tab) layout.setSpacing(12) layout.setContentsMargins(12, 12, 12, 8) # 创建按钮 image_btn = UiMainTestStyle.create_button(self.parent, "图片检测", "#00c8ff") file_path_btn = UiMainTestStyle.create_button(self.parent, "文件检测", "#00a0c0") previous_image_btn = UiMainTestStyle.create_button(self.parent, "上一张", "#ff4a4a") next_image_btn = UiMainTestStyle.create_button(self.parent, "下一张", "#a04aff") video_btn = UiMainTestStyle.create_button(self.parent, "视频检测", "#00a0c0") camera_btn = UiMainTestStyle.create_button(self.parent, "摄像头检测", "#00c8dd") stop_btn = UiMainTestStyle.create_button(self.parent, "停止检测", "#ff4a4a") save_btn = UiMainTestStyle.create_button(self.parent, "保存结果", "#a04aff") # 连接信号到父窗口的槽函数(假设父窗口有这些方法) image_btn.clicked.connect(self.parent.detect_image) file_path_btn.clicked.connect(self.parent.detect_file) previous_image_btn.clicked.connect(self.parent.show_previous_image) next_image_btn.clicked.connect(self.parent.show_next_image) video_btn.clicked.connect(self.parent.detect_video) camera_btn.clicked.connect(self.parent.detect_camera) stop_btn.clicked.connect(self.parent.stop_detection) save_btn.clicked.connect(self.parent.save_result) # 按钮布局 row1 = QHBoxLayout() row1.addWidget(image_btn) row1.addWidget(file_path_btn) row1.addWidget(previous_image_btn) row1.addWidget(next_image_btn) row2 = QHBoxLayout() row2.addWidget(video_btn) row2.addWidget(camera_btn) row3 = QHBoxLayout() row3.addWidget(stop_btn) row3.addWidget(save_btn) layout.addLayout(row1) layout.addLayout(row2) layout.addLayout(row3) return tab ``` 然后在主窗口中创建标签页: ```python class MyMainWindow(QMainWindow): def __init__(self): super().__init__() # ... 其他初始化 ... self.tab_creator = CreateTab(self) # 传入self作为父窗口引用 def setup_ui(self): # ... 其他UI设置 ... self.tab1 = self.tab_creator.create_general_tab() self.tab2 = self.tab_creator.create_general_tab() self.tab3 = self.tab_creator.create_general_tab() self.tab_widget.addTab(self.tab1, "标签1") self.tab_widget.addTab(self.tab2, "标签2") self.tab_widget.addTab(self.tab3, "标签3") ``` 这样,每个标签页都有自己的一组按钮,并且点击按钮时会调用主窗口中对应的槽函数。 注意:在 `CreateTab` 类的 `create_general_tab` 方法中,我们使用 `self.parent` 来创建按钮和连接信号,因此需要确保 `self.parent` 有这些槽函数。 为什么之前无法调用? 1. 您使用了 `create_tab.CreateTab.create_tab1`,这是类的方法,但没有创建实例,而且也没有传入必要的参数(尤其是按钮参数)。 2. 在 `CreateTab` 的构造函数中需要多个按钮参数,但在调用时没有提供。 因此,我们通过重构,将按钮的创建移到 `CreateTab` 内部,并且通过传入父窗口来连接信号,这样就能正确创建标签页了。 §§相关问题§§: 1. 在PyQt中,如何避免多个标签页中相同功能的按钮代码重复? 2. 如果每个标签页的按钮功能略有不同,该如何设计? 3. 如何动态地为标签页添加不同的内容? 4. 在多个标签页中使用相同的按钮名称,如何区分信号来源? </think>您的问题在于 `CreateTab` 类的设计和使用方式不正确,导致无法正确创建标签页。以下是详细的问题分析和解决方案: ### 问题分析 1. **类方法调用错误**: - `self.tab1 = create_tab.CreateTab.create_tab1` 只是获取了方法的引用,没有实际调用方法 - 缺少必要的括号 `()` 来调用方法 2. **构造函数参数问题**: - `CreateTab` 的 `__init__` 需要多个按钮参数 - 但在调用 `create_tab1` 前没有创建这些按钮实例 3. **方法逻辑冲突**: - 在 `create_tab1` 方法中又重新创建了按钮实例 - 这与构造函数传入的按钮参数相冲突 4. **实例化缺失**: - 没有创建 `CreateTab` 的实例就直接调用其方法 ### 正确的解决方案 ```python class CreateTab: def __init__(self, parent): """初始化标签页创建器,只需父窗口引用""" self.parent = parent # 保存父窗口引用 def create_tab(self, tab_name="Tab"): """创建通用标签页""" tab = QWidget() layout = QVBoxLayout(tab) layout.setSpacing(12) layout.setContentsMargins(12, 12, 12, 8) # 创建按钮 image_btn = UiMainTestStyle.create_button(self.parent, "图片检测", "#00c8ff") file_path_btn = UiMainTestStyle.create_button(self.parent, "文件检测", "#00a0c0") previous_image_btn = UiMainTestStyle.create_button(self.parent, "上一张", "#ff4a4a") next_image_btn = UiMainTestStyle.create_button(self.parent, "下一张", "#a04aff") video_btn = UiMainTestStyle.create_button(self.parent, "视频检测", "#00a0c0") camera_btn = UiMainTestStyle.create_button(self.parent, "摄像头检测", "#00c8dd") stop_btn = UiMainTestStyle.create_button(self.parent, "停止检测", "#ff4a4a") save_btn = UiMainTestStyle.create_button(self.parent, "保存结果", "#a04aff") # 连接信号槽 image_btn.clicked.connect(self.parent.detect_image) file_path_btn.clicked.connect(self.parent.detect_file) previous_image_btn.clicked.connect(self.parent.show_previous_image) next_image_btn.clicked.connect(self.parent.show_next_image) video_btn.clicked.connect(self.parent.detect_video) camera_btn.clicked.connect(self.parent.detect_camera) stop_btn.clicked.connect(self.parent.stop_detection) save_btn.clicked.connect(self.parent.save_result) # 布局按钮 row1 = QHBoxLayout() row1.addWidget(image_btn) row1.addWidget(file_path_btn) row1.addWidget(previous_image_btn) row1.addWidget(next_image_btn) row2 = QHBoxLayout() row2.addWidget(video_btn) row2.addWidget(camera_btn) row3 = QHBoxLayout() row3.addWidget(stop_btn) row3.addWidget(save_btn) layout.addLayout(row1) layout.addLayout(row2) layout.addLayout(row3) return tab ``` ### 在主窗口中的正确使用方式 ```python class MyMainWindow(QMainWindow): def __init__(self): super().__init__() self.setup_ui() def setup_ui(self): # 初始化UI... self.setup_tabs() def setup_tabs(self): """设置标签页""" # 创建标签页创建器实例 tab_creator = CreateTab(self) # 传入当前窗口作为父对象 # 创建标签页 self.tab1 = tab_creator.create_tab("1号摄像头") self.tab2 = tab_creator.create_tab("2号摄像头") self.tab3 = tab_creator.create_tab("3号摄像头") # 添加标签页到Tab控件 self.tab_widget.addTab(self.tab1, "1号摄像头||") self.tab_widget.addTab(self.tab2, "2号摄像头||") self.tab_widget.addTab(self.tab3, "3号摄像头") # 槽函数实现 def detect_image(self): print("图片检测功能被触发") def detect_file(self): print("文件检测功能被触发") # 其他槽函数... ``` ### 解决方案详解 1. **重构 `CreateTab` 类**: - 简化构造函数,只需父窗口引用 - 创建通用方法 `create_tab()` 处理标签页创建 - 在方法内部创建按钮实例和连接信号 2. **正确的类实例化**: - 使用 `tab_creator = CreateTab(self)` 创建实例 - `self` 作为父窗口引用传入 3. **正确的调用方法**: - 使用 `tab_creator.create_tab()` 实际调用方法 - 添加可选参数指定标签页名称 4. **信号槽连接**: - 通过 `self.parent` 访问主窗口的槽函数 - 确保点击按钮能触发主窗口的功能 ### 完整的使用示例 ```python import sys from PyQt5.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QTabWidget, QPushButton ) # 假设的样式类(简化版) class UiMainTestStyle: @staticmethod def create_button(parent, text, color): btn = QPushButton(text, parent) btn.setStyleSheet(f"background-color: {color}; color: white; padding: 8px;") return btn class CreateTab: def __init__(self, parent): self.parent = parent def create_tab(self, tab_name="Tab"): """创建通用标签页""" tab = QWidget() layout = QVBoxLayout(tab) layout.setSpacing(12) layout.setContentsMargins(12, 12, 12, 8) # 创建按钮 buttons = [ ("图片检测", "#00c8ff", "detect_image"), ("文件检测", "#00a0c0", "detect_file"), ("上一张", "#ff4a4a", "show_previous_image"), ("下一张", "#a04aff", "show_next_image"), ("视频检测", "#00a0c0", "detect_video"), ("摄像头检测", "#00c8dd", "detect_camera"), ("停止检测", "#ff4a4a", "stop_detection"), ("保存结果", "#a04aff", "save_result") ] # 创建按钮布局 rows = [ buttons[0:4], # 第一行4个按钮 buttons[4:6], # 第二行2个按钮 buttons[6:8] # 第三行2个按钮 ] for row_buttons in rows: row_layout = QHBoxLayout() for text, color, slot in row_buttons: btn = UiMainTestStyle.create_button(self.parent, text, color) # 连接信号槽 if hasattr(self.parent, slot): btn.clicked.connect(getattr(self.parent, slot)) row_layout.addWidget(btn) layout.addLayout(row_layout) return tab class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setup_ui() def setup_ui(self): self.setWindowTitle("多摄像头检测系统") self.setGeometry(100, 100, 800, 600) # 主控件 central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) # 创建Tab控件 self.tab_widget = QTabWidget() main_layout.addWidget(self.tab_widget) # 创建标签页 self.setup_tabs() def setup_tabs(self): """创建并添加标签页""" tab_creator = CreateTab(self) # 创建3个标签页 tabs = [ ("1号摄像头", "1号摄像头||"), ("2号摄像头", "2号摄像头||"), ("3号摄像头", "3号摄像头") ] for tab_name, tab_title in tabs: tab = tab_creator.create_tab(tab_name) self.tab_widget.addTab(tab, tab_title) # 槽函数实现 def detect_image(self): print(f"图片检测 - 标签页 {self.tab_widget.currentIndex() + 1}") def detect_file(self): print(f"文件检测 - 标签页 {self.tab_widget.currentIndex() + 1}") def show_previous_image(self): print(f"上一张图片 - 标签页 {self.tab_widget.currentIndex() + 1}") def show_next_image(self): print(f"下一张图片 - 标签页 {self.tab_widget.currentIndex() + 1}") def detect_video(self): print(f"视频检测 - 标签页 {self.tab_widget.currentIndex() + 1}") def detect_camera(self): print(f"摄像头检测 - 标签页 {self.tab_widget.currentIndex() + 1}") def stop_detection(self): print(f"停止检测 - 标签页 {self.tab_widget.currentIndex() + 1}") def save_result(self): print(f"保存结果 - 标签页 {self.tab_widget.currentIndex() + 1}") if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_()) ``` ### 关键改进点 1. **简洁的类设计**: - `CreateTab` 只需父窗口引用 - 单一方法 `create_tab()` 处理所有创建逻辑 2. **动态槽函数连接**: - 使用 `hasattr()` 和 `getattr()` 动态连接信号 - 避免硬编码连接,提高灵活性 3. **按钮布局优化**: - 使用列表结构管理按钮配置 - 循环创建按钮和布局,减少重复代码 4. **标签页独立性**: - 每个标签页有自己的按钮实例 - 通过 `currentIndex()` 获取当前标签页信息 5. **可扩展性**: - 轻松添加新标签页 - 自定义每个标签页的名称和标题 这种设计确保了: - 正确创建标签页 - 按钮功能正常工作 - 代码结构清晰可维护 - 便于扩展和定制
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值