鱼C论坛

 找回密码
 立即注册
查看: 128|回复: 3

pyside6子类收不到正确的父类的信号

[复制链接]
发表于 2025-8-10 11:49:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
以下是父类EXPANDABLE_MENU.py的代码:
from CHROMELESS_WINDOW import *

# 伸缩菜单 父类
class ExpandableMenu(ChromelessWindow):
    list_index = Signal(dict)   # 发射 鼠标移动时的位置   {序号:[矩形起始y,矩形结束y,文字起始y,文字结束y]}
    scrollbar_start_y = Signal(object)  # 发射滚动条的起始y
    text_gps_dict = Signal(dict)        # 发射文本的gps
    press_left = Signal(int)     # 发射 按下左键时的文本序号
    not_text_area = Signal(str)     # # 发射 '非文本区域按下左键'
    text_order = Signal(QPointF, object)    # 调整文本顺序时发射 参数 鼠标轨迹,文本索引
    def __init__(self, parent=None):
        super().__init__(parent)
        self.is_left_pressed = False        # 左键按住标志
        self.__left = None                  # 记录按下左键的位置
        self.press_left_y = None            # 按住左键时 滚动条的起始y
        self.__pos = None    # 设置 是否按住左键调整文本顺序 同时也时鼠标的移动轨迹
        self.ctrl_left_name = None            # 标记 调整文本顺序时的 名字

        # 调用父类属性
        self.min_button_tf, self.max_button_tf, self.button_close_tf = False, False, False     # 设置三大组件失灵
        self.drive_window = False  # 为真时窗口可拖动

        self.__list_index = None        # 鼠标所在的位置的文本名字
        self.parameters_settings()  # 初始化各项参数

    def parameters_settings(self, min_view: bool = True,                # 设置 本窗口在任务栏不可见
                            adj_up: bool = False,
                            adj_down: bool = False,
                            adj_left: bool = False,                     # 左 为假时不可调整大小
                            adj_right: bool = True,                     # 右
                            window_x: int = 100,
                            window_y: int = 50,
                            window_width: int = 200,
                            text_number: int = 20,                      # 要显示文本数量
                            text_sum: int = 100,                        # 文本的总长度
                            text_size: int | float = 10,                # 字体大小
                            text_lenght: int | float = 2,               # 字体做坐标间距
                            text_window_start_y: int | float = 100,      # 用于显示文本区域的起始x位置 非绘制文字的空白区域总高度
                            header_color: str = '#C4A737',             # 标头颜色'#C4A737'
                            move_create_color: str = '#CEA5DA',        # 跟随鼠标矩形的颜色
                            # column_width: dict[int, int | float] = None,    # 每一列的宽度{类序号:宽度}
                            scrollbar_color: str = '#444343',           # 滚动条颜色
                            scrollbar_area_color: str = '#FAF8F8',      # 滚动条区域的颜色
                            backcolor: str = None,                      # 背景颜色
                            ):
        if min_view:
            self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool)  # 设置窗口在任务栏中不可见
        if backcolor:
            self.setStyleSheet(f"background-color: {backcolor};")   # 设置背景颜色

        self.adj_up = adj_up
        self.adj_down = adj_down
        self.adj_left = adj_left
        self.adj_right = adj_right

        self.__window_x = window_x
        self.__window_y = window_y
        self.__window_width = window_width
        self.__text_number = text_number                    # 要显示文本数量
        self.__text_sum = text_sum                          # 文本的总长度
        self.__text_size = text_size                        # 字体大小
        self.__text_size_ratio = text_lenght                # 字体间距比例
        self.__text_lenght = text_lenght * self.__text_size    # 字体纵坐标间距
        # self.__column_width = {0: 50} if column_width is None else column_width  # 每一列的宽度{类序号:宽度}
        self.__scrollbar_color = scrollbar_color            # 滚动条颜色
        self.scrollbar_area_color = scrollbar_area_color    # 滚动条区域颜色

        screen = QApplication.primaryScreen().geometry()
        self.__screenWidth, self.__screenHeight = screen.width(), screen.height()
        self.__scrollbar_width = self.__screenWidth * 0.01                  # 滚动条宽度
        self.__scrollbar_ratio = self.__text_number / self.__text_sum       # 滚动条占比
        self.__text_window_start_y = text_window_start_y                    # 用于显示文本区域的起始x位置
        self.__header_color = header_color                                  # 标头颜色
        self.move_create_color = move_create_color                          # 跟随鼠标矩形的颜色
        self.text_start_index = 0                                           # 文本的开始索引
        self.text_end_index = self.__text_number                            # 文本的结束索引

        # 初始化 窗口
        a = self.__text_lenght if header_color else 0
        self.setGeometry(self.__window_x,
                         self.__window_y,
                         self.__window_width,
                         a + self.__text_number * self.__text_lenght + self.__text_window_start_y)
        # 文本结束y和跟随鼠标的矩形y的距离
        self.text_entity_lenght = self.__text_size * ((self.__text_size_ratio - 1) / 2)
        if self.__text_window_start_y:  # 空白区域
            if header_color:
                # 显示文本内容的区域 的起始y
                self.__text_start_y = self.__text_size * self.__text_size_ratio + self.__text_window_start_y

                # 滚动条起始y
                self.__scrollbar_start_y = self.__text_start_y
                self.__scrollbar_start_x = self.width() - self.__scrollbar_width  # 滚动条起始x
                # 滚动条长度
                self.__scrollbar_height = self.__scrollbar_ratio * (self.height() - self.__scrollbar_start_y)
                self.__scrollbar_end_y = self.__text_start_y + self.__scrollbar_height  # 滚动条结束y
            else:
                self.__text_start_y = self.__text_window_start_y        # # 显示文本内容的区域 的起始y

                self.__scrollbar_start_y = self.__text_window_start_y   # 滚动条起始y
                self.__scrollbar_start_x = self.width() - self.__scrollbar_width  # 滚动条起始x
                # 滚动条长度
                self.__scrollbar_height = self.__scrollbar_ratio * (self.height() - self.__text_window_start_y)
                self.__scrollbar_end_y = self.__scrollbar_start_y + self.__scrollbar_height  # 滚动条结束y
        else:
            if header_color:
                self.__text_start_y = self.__text_size * self.__text_size_ratio  # 显示文本内容的区域 的起始y

                self.__scrollbar_start_y = self.__text_start_y                      # 滚动条起始y
                self.__scrollbar_start_x = self.width() - self.__scrollbar_width    # 滚动条起始x
                # 滚动条长度
                self.__scrollbar_height = self.__scrollbar_ratio * (self.height() - self.__scrollbar_start_y)
                self.__scrollbar_end_y = self.__scrollbar_start_y + self.__scrollbar_height  # 滚动条结束y
            else:
                self.__text_start_y = 0           # 显示文本内容的区域 的起始y
                self.expandable_scrollbar_gps()  # 初始化滚动条gps
        self.scrollbar_max_start_y = self.height() - self.__scrollbar_height  # 限制滚动论最大的起始y

        self.__text_list = [s for s in range(self.__text_sum)]    # 生成和文本列表同等长度的列表
        self.expandable_text_gps_dict(start_index=0, end_index=self.__text_number)  # 初始化跟随鼠标的矩形gps

    def expandable_text_gps_dict(self, start_index, end_index):
        self.mapping_text_gps_dict = {}     # {序号:[矩形起始y,矩形结束y,文字起始y,文字结束y]}
        for index, s in enumerate(self.__text_list[start_index: end_index]):
            end_y = self.__text_start_y + (index + 1) * self.__text_lenght    # 矩形结束y
            self.mapping_text_gps_dict[s] = [self.__text_start_y + index * self.__text_lenght,
                                             end_y,
                                             end_y - self.text_entity_lenght - self.__text_size,
                                             end_y - self.text_entity_lenght]
        self.text_gps_dict.emit(self.mapping_text_gps_dict)
        print(self.mapping_text_gps_dict)
    def mouseMoveEvent(self, event):  # 鼠标移动
        super().mouseMoveEvent(event)
        pos = event.position()
        if self.is_left_pressed is False and pos.x() < self.__scrollbar_start_x:  # 跟随鼠标的矩形
            if pos.y() > self.__text_start_y:
                for key_number, val_gps in self.mapping_text_gps_dict.items():
                    if val_gps[0] < pos.y() < val_gps[1]:
                        self.__list_index = key_number
                        # 发射 鼠标移动时的位置   {序号:[矩形起始y,矩形结束y,文字起始y,文字结束y]}
                        self.list_index.emit({self.__list_index: val_gps})
                        self.update()
                        break
                    else:
                        self.__list_index = None
        elif self.is_left_pressed and pos.x() < self.__scrollbar_start_x:  # 调整文本显示的位置
            self.__pos = pos    # 设置 是否按住左键调整文本顺序 同时也时鼠标的移动轨迹
            self.text_order.emit(self.__pos, self.__text_list)    # 参数 鼠标轨迹,文本索引
            self.update()

        elif self.is_left_pressed and pos.y() > self.__text_start_y and pos.x() > self.__scrollbar_start_x:
            # 更新滚动条
            new_y = pos.y() - self.__left   # 计算鼠标移动和按下左键时的距离
            new_y = self.press_left_y + new_y   # 按住左键时滚动条的位置 + 鼠标移动的距离
            if self.__text_start_y <= new_y <= self.scrollbar_max_start_y:
                self.__scrollbar_start_y = new_y
                text_start_y_ratio = (new_y - self.__text_start_y) / (self.height() - self.__text_start_y - self.text_entity_lenght)
                self.text_start_index = int(text_start_y_ratio * self.__text_sum)
                self.text_end_index = self.text_start_index + self.__text_number
                self.expandable_text_gps_dict(self.text_start_index,
                                              self.text_end_index)  # {序号:[矩形起始y,矩形结束y,文字起始y,文字结束y]}
                self.scrollbar_start_y.emit(new_y)  # 发射滚动条的起始y
                self.update()

    def mousePressEvent(self, event: QMouseEvent):  # 鼠标案件
        super().mousePressEvent(event)
        pos = event.position()

        if event.button() == Qt.LeftButton:  # 左键
            self.ctrl_left_name = self.__list_index     # 标记 调整文本顺序时的 名字
            self.press_left_y = self.__scrollbar_start_y  # 按住左键时 滚动条的 起始y位置
            self.__left = pos.y()   # 记录按下左键的位置
            self.is_left_pressed = True  # 设置按下标志
            if pos.x() < self.__scrollbar_start_x and pos.y() > self.__text_start_y:
                if self.__list_index:
                    self.press_left.emit(self.__list_index)     # 发射 按下左键时的文本序号
            elif pos.y() < self.__text_start_y:
                self.not_text_area.emit('非文本区域按下左键')    # 发射 '非文本区域'

        elif event.button() == Qt.RightButton:  # 右键
            pass

    def mouseReleaseEvent(self, event):
        super().mouseReleaseEvent(event)
        pos = event.position()
        if event.button() == Qt.LeftButton:
            self.is_left_pressed = False  # 清除按下标志
            if self.__pos:
                for key_number, val_gps in self.mapping_text_gps_dict.items():
                    if val_gps[0] < pos.y() < val_gps[1]:
                        self.__list_index = self.ctrl_left_name
                        # 发射 鼠标移动时的位置   {序号:[矩形起始y,矩形结束y,文字起始y,文字结束y]}
                        self.list_index.emit({self.__list_index: val_gps})
                        self.update()
                        break
                    else:
                        self.__list_index = None
                self.__pos = None  # 设置 是否按住左键调整文本顺序
                pass



    def wheelEvent(self, event):  # 鼠标滚轮
        super().wheelEvent(event)
        angle_delta = event.angleDelta().y()  # 垂直滚动的量
        len_text = len(self.__text_list)
        self.text_start_index, self.text_end_index = wheel_update_index(text_len=len_text,
                                                                        max_number=self.__text_number,
                                                                        start_index=self.text_start_index,
                                                                        end_index=self.text_end_index,
                                                                        angle_delta=angle_delta)
        a = self.text_start_index / len_text    # 开始索引占中长度的比例
        b = self.height() - self.__text_start_y   # 显示区域的长度
        self.__scrollbar_start_y = a * b + self.__text_start_y         # 更新滚动条起始y
        self.expandable_text_gps_dict(start_index=self.text_start_index, end_index=self.text_end_index)
        self.update()

    def expandable_scrollbar_gps(self):
        self.__scrollbar_start_y = 0                                                    # 滚动条起始y
        self.__scrollbar_start_x = self.width() - self.__scrollbar_width                # 滚动条起始x
        self.__scrollbar_height = self.__scrollbar_ratio * self.height()                # 滚动条长度
        self.__scrollbar_end_y = self.__scrollbar_start_y + self.__scrollbar_height     # 滚动条结束y

    def paintEvent(self, event):
        qp = QPainter(self)
        # 开启抗锯齿
        qp.setRenderHint(QPainter.Antialiasing)  # PyQt5/PySide6 通用写法
        # 可选:同时开启其他渲染优化
        qp.setRenderHint(QPainter.TextAntialiasing)  # 文字抗锯齿
        # qp.setRenderHint(QPainter.SmoothPixmapTransform)  # 图片平滑缩放

        # 绘制滚动条区域
        entity_painter(qp, self.scrollbar_area_color, 0).drawRect(self.__scrollbar_start_x,
                                                                  self.__text_start_y,
                                                                  self.__scrollbar_width,
                                                                  self.height() - self.__text_start_y)
        qp.restore()

        # 绘制滚动条 移动的轨迹
        entity_painter(qp, self.__scrollbar_color, 0).drawRect(self.__scrollbar_start_x,
                                                               self.__scrollbar_start_y
                                                               , self.__scrollbar_width
                                                               , self.__scrollbar_height)
        qp.restore()

        # 绘制跟随鼠标的矩形
        if self.__list_index is not None:
            try:
                entity_painter(qp, self.move_create_color, 0).drawRect(0,
                                                      self.mapping_text_gps_dict[self.__list_index][0],
                                                      self.width() - self.__scrollbar_width,
                                                      self.__text_lenght)
                qp.restore()
            except KeyError:
                pass

        if self.__pos:     # 绘制 调整文本顺序
            # 绘制调整文本顺序时 矩形的移动轨迹
            entity_painter(qp, self.move_create_color, 0).drawRect(0,
                                                  self.__pos.y() - self.__text_lenght / 2,
                                                  self.width() - self.__scrollbar_width,
                                                  self.__text_lenght)
            qp.restore()
以下是子类a.py的代码:
from EXPANDABLE_MENU import *
import sys
from data_json import *
from MAPPING import *

# 我的自选
class MyMatchList(ExpandableMenu):
    def __init__(self, parent=None):
        super().__init__(parent)

        screen = QApplication.primaryScreen().geometry()
        self.match_width, self.match_height = screen.width(), screen.height()
        self.match_font_size = self.match_height * 0.015    # 字体大小
        self.text_x_lenght = self.match_font_size * 3       # 文本横向坐标的距离
        self.match_text_start_y = self.match_height * 0.19  # 显示文本区域的起始y,空白区域的结束y
        self.match_window_width = int(self.match_width * 0.3)   # 初始化 窗口宽度
        self.match_font_type = "SimSun"                         # 字体类型
        self.text_y_lenght = 2                                  # 文本纵向坐标的间距

        # 创建与父类的链接
        self.text_gps_dict.connect(self.js_text_gps)  # 接收文本的纵向坐标gps



        # 标头母版
        self.header_mother_set = ['代码/名字', '价格', '涨幅', '大宗交易', '成交额', '流通市值']
        # 数据母版
        self.data_mother_set = ['SH600000_野马电池', '00.00', '++00.00', '20250909', '0.00亿', '000.00亿']
        self.match_data_list = []     # 我的自选数据列表

        self.match_window(window_x=0, window_y=0)   # 初始化窗口 以及各项参数

    def js_text_gps(self, gps: dict):
        '''接收文本的纵向坐标gps'''
        self.match_text_y_gps = gps
        print(gps)

    def match_window(self, window_x: int = 0, window_y: int = 0):
        '''初始化窗口'''
        match_json = Data_Http.mymatch_set_data()
        # 文本列表
        self.match_text_list = match_json['match'] if 'match' in match_json else None
        # 窗口尺寸
        self.match_window_width = int(match_json['window_size']) if 'window_size' in match_json else int(self.match_width * 0.3)

        if self.match_text_list is None:
            self.match_text_list = self.data_mother_set
        # 窗口中可以显示的数据列数
        self.display_column_number = mother_set_calculate(
                                                            data=self.match_text_list,              # 数据
                                                            start_x=self.match_font_size * 2,       # 预留 距离窗口左边的距离
                                                            window_width=self.match_window_width,   # 窗口宽度
                                                            font_type=self.match_font_type,         # 字体类型
                                                            font_size=self.match_font_size,         # 字体大小
                                                            x_lenght=self.text_x_lenght             # 文本横向距离
                                                            )
        # 文本的横向gps          标头的横向gps
        self.match_text_x_gps, self.match_header_gps = mother_set_mapping_gps(
                           header=self.header_mother_set,           # 标头
                           data=self.match_text_list,               # 数据
                           start_x=self.match_font_size * 2,        # 预留 距离窗口左边的距离
                           font_type=self.match_font_type,          # 字体类型
                           font_size=self.match_font_size,          # 字体大小
                           x_lenght=self.text_x_lenght              # 文本横向距离
                           )
        # 调用父类
        self.parameters_settings(window_x=window_x,
                            window_y=window_y,
                            window_width=self.match_window_width,
                            text_number=20,                                # 要显示文本数量
                            text_sum=len(self.match_text_list),            # 文本的总长度
                            text_size=self.match_font_size,                # 字体大小
                            text_lenght=self.text_y_lenght,                # 字体y坐标间距
                            text_window_start_y=self.match_text_start_y      # 用于显示文本区域的起始x位置
                            )


    def resizeEvent(self, event):   # 监控窗口大小
        super().resizeEvent(event)  # 确保父类逻辑执行
        # old_size = event.oldSize()  # 旧尺寸 (QSize)
        new_size = event.size()     # 新尺寸 (QSize)

        if self.match_data_list:
            pass

    # 接收实时数据的接口
    def mymatchlist_data_API(self, data: list = None) -> None:
        self.match_data_list = data     # 我的自选数据列表
        len_data = len(data)
        self.parameters_settings(window_x=100,
                            window_y=50,
                            window_width=200,
                            text_number=20,                      # 要显示文本数量
                            text_sum=len_data,                        # 文本的总长度
                            text_size=self.match_font_size,                # 字体大小
                            text_lenght=2,               # 字体做坐标间距
                            text_window_start_y=self.match_text_start_y      # 用于显示文本区域的起始x位置
                            )
        self.update()
    def paintEvent(self, event):
        super().paintEvent(event)
        qp = QPainter(self)
        #

        # 绘制标头
        for index, i in enumerate(self.header_mother_set):
            text_begin(self, qp, '#BC29E5', "SimSun", self.match_font_size,
                       self.match_header_gps[index][0],
                       self.match_text_start_y - self.match_font_size * ((self.text_y_lenght - 1) / 2),
                       f'{i}')
            qp.restore()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.processEvents()  # 处理未完成的事件
    window = MyMatchList()
    window.show()
    sys.exit(app.exec())
print(gps)语句的打印值为{},但是我通过在父类的发射信号处self.text_gps_dict.emit(self.mapping_text_gps_dict)添加
打印语句print(self.mapping_text_gps_dict),发现父类可以打印处正确的值,当父类的值改变时print(gps)会跟随打印出
{}而父类的打印语句正确无误,这说明父类发射了正确的值,子类MyMatchList也接收到了信号只不过收到的是空字典,这是怎么回事
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2025-8-10 11:52:28 | 显示全部楼层
在PySide6中,子类接收不到父类信号的原因通常是由于信号连接时机不当导致的。以下是问题分析和解决方案:

### 问题原因
1. **信号连接时机错误**:子类在 `__init__` 中连接信号时,父类已经提前发射了信号
2. **父类初始化顺序**:父类在 `__init__` 中调用了 `parameters_settings()`,该方法发射了 `text_gps_dict` 信号
3. **子类连接滞后**:子类连接信号发生在父类初始化之后,错过了最初的信号发射

### 解决方案
在子类中重写父类的 `parameters_settings` 方法,并在其中重新发射信号:

  1. class MyMatchList(ExpandableMenu):
  2.     def __init__(self, parent=None):
  3.         super().__init__(parent)
  4.         # 信号连接
  5.         self.text_gps_dict.connect(self.expandable_text_gps_slot)
  6.         # 其他初始化代码...
  7.    
  8.     def parameters_settings(self, **kwargs):
  9.         # 先调用父类设置
  10.         super().parameters_settings(**kwargs)
  11.         
  12.         # 手动触发信号发射
  13.         self.expandable_text_gps_dict(
  14.             start_index=self.text_start_index,
  15.             end_index=self.text_end_index
  16.         )
  17.    
  18.     def expandable_text_gps_slot(self, gps):
  19.         print("接收到GPS数据:", gps)
  20.         self.mapping_text_gps_dict = gps
复制代码


### 关键修改说明
1. **重写 parameters_settings 方法**:
   - 首先调用 `super().parameters_settings()` 完成父类设置
   - 然后手动调用 `expandable_text_gps_dict()` 重新发射信号

2. **确保连接时机正确**:
   - 子类的信号连接仍在 `__init__` 中
   - 但通过重写方法确保了信号在连接后会被再次触发

3. **传递正确的索引参数**:
   - 使用父类已有的 `text_start_index` 和 `text_end_index`
   - 确保生成的坐标字典范围正确

### 其他注意事项
1. 检查父类中 `self.__text_list` 的初始化:
  1. # 在父类中确保文本列表被正确初始化
  2. def parameters_settings(self, **kwargs):
  3.     # ...
  4.     self.__text_list = [""] * self.__text_sum  # 示例初始化
  5.     # ...
复制代码


2. 如果仍有问题,可在父类发射信号前添加延迟:
  1. # 在父类的 expandable_text_gps_dict 中
  2. QTimer.singleShot(100, lambda: self.text_gps_dict.emit(self.mapping_text_gps_dict))
复制代码


3. 确保信号定义在类顶层(非 `__init__` 内):
  1. class ExpandableMenu(ChromelessWindow):
  2.     text_gps_dict = Signal(dict)  # 正确位置(类属性)
  3.    
  4.     def __init__(self):
  5.         # ... 不要在这里定义信号
复制代码


这种解决方案确保了子类在正确时机接收到信号,同时保持了父类功能的完整性。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-8-10 12:05:40 | 显示全部楼层
QTimer.singleShot(100, lambda: self.text_gps_dict.emit(self.mapping_text_gps_dict))和重写parameters_settings都无效应该不是信号发射时机的问题,请仔细审视代码重新查找问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-8-10 12:08:24 | 显示全部楼层
rxts 发表于 2025-08-10 12:05
QTimer.singleShot(100, lambda: self.text_gps_dict. ...


您遇到的是PySide6信号传递中的典型作用域问题。问题出在子类中信号连接的接收方式上,以下是详细分析和解决方案:

### 问题核心原因
1. **槽函数作用域问题**:
   - 在子类中定义的槽函数 `expandable_text_gps_slot` 是**实例方法**
   - 当信号发射时,PySide6 会尝试调用这个方法,但需要正确的 `self` 上下文

2. **连接方式错误**:
   - 您使用了 `self.text_gps_dict.connect(self.expandable_text_gps_slot)`
   - 这种连接方式在PySide6中会导致槽函数绑定的 `self` 上下文不正确

### 解决方案
修改子类的信号连接方式,使用 `lambda` 或 `functools.partial` 显式传递 `self`:

  1. class MyMatchList(ExpandableMenu):
  2.     def __init__(self, parent=None):
  3.         super().__init__(parent)
  4.         # 修复信号连接方式
  5.         self.text_gps_dict.connect(lambda gps: self.expandable_text_gps_slot(gps))
  6.         
  7.         # 其他初始化代码...
  8.    
  9.     def expandable_text_gps_slot(self, gps):
  10.         print("接收到GPS数据:", gps)
  11.         self.mapping_text_gps_dict = gps
复制代码


### 完整修改步骤

1. **修改子类的信号连接**:
  
  1. # 子类 __init__ 中修改连接方式
  2.    self.text_gps_dict.connect(lambda gps: self.expandable_text_gps_slot(gps))
复制代码


2. **检查父类信号发射**:
   在父类 `expandable_text_gps_dict` 方法中添加调试语句:
  
  1. def expandable_text_gps_dict(self, start_index, end_index):
  2.        print(f"父类发射信号: {self.mapping_text_gps_dict}")
  3.        self.text_gps_dict.emit(self.mapping_text_gps_dict)
复制代码


3. **确保文本数据正确传递**:
   在子类 `set_data` 方法中,调用父类方法设置文本列表:
  
  1. def set_data(self, data: list):
  2.        self.match_data_list = data
  3.        len_data = len(data)
  4.       
  5.        # 设置父类的文本列表
  6.        self.set_text_list(data)  # 需要父类实现此方法
  7.       
  8.        self.parameters_settings(
  9.            text_sum=len_data,
  10.            # 其他参数...
  11.        )
复制代码


4. **在父类中添加设置文本列表的方法**:
  
  1. # 在 ExpandableMenu 类中添加
  2.    def set_text_list(self, text_list):
  3.        self.__text_list = text_list
  4.        self.update_text_gps()  # 触发坐标更新
  5.    
  6.    def update_text_gps(self):
  7.        """手动触发坐标更新"""
  8.        self.expandable_text_gps_dict(
  9.            self.text_start_index,
  10.            self.text_end_index
  11.        )
复制代码


### 其他注意事项

1. **检查信号定义位置**:
   确保信号定义在类顶层(而不是 `__init__` 中):
  
  1. class ExpandableMenu(ChromelessWindow):
  2.        text_gps_dict = Signal(dict)  # 正确位置
  3.       
  4.        def __init__(self):
  5.            # ... 不要在这里定义信号
复制代码


2. **确认线程安全**:
   如果涉及多线程,使用 `Qt.QueuedConnection`:
  
  1. self.text_gps_dict.connect(
  2.        lambda gps: self.expandable_text_gps_slot(gps),
  3.        Qt.ConnectionType.QueuedConnection
  4.    )
复制代码


3. **验证信号连接**:
   在子类中添加检查:
  
  1. print("信号是否已连接:", self.receivers(self.text_gps_dict) > 0)
复制代码


这种解决方案确保了:
1. 槽函数调用时有正确的 `self` 上下文
2. 文本数据在父子类间正确传递
3. 信号连接可靠有效

如果问题仍然存在,请检查父类中 `self.mapping_text_gps_dict` 的生成逻辑,确保它不是空字典。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-9-1 11:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表