AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77083320
Accepted
Poison
Poison
Asked: 2023-09-12 00:28:59 +0800 CST2023-09-12 00:28:59 +0800 CST 2023-09-12 00:28:59 +0800 CST

为什么我将QListwidget的ItemClicked信号连接到槽函数后,QListWidgetItem的复选框无法正常点击?

  • 772

我通过QListWidget实现了一个可选列表,然后我发现如果我想改变复选框的状态,我只能通过点击复选框来改变。

但我也想通过点击Item来切换复选框状态,所以我将QListWidget的ItemClicked信号连接到一个新的槽函数来实现。

后来我发现与该项目关联的复选框的状态只能通过单击该项目来更改,而不能通过单击复选框本身来更改。

我很好奇这个过程中发生了什么,以及我应该做什么来实现我的目标,即可以通过单击复选框或项目本身来切换复选框的状态。打击是我的代码:

class Item(QListWidgetItem):
    def __init__(self):
        super().__init__()
        # self.setFlags(Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled)
        self.setCheckState(Qt.CheckState.Unchecked)
        self.setToolTip("double click edit")


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()
        self.add_btn = QPushButton("add")
        self.select_all = QPushButton("select all")
        self.del_btn = QPushButton("delete")
        btn_layout = QHBoxLayout()
        btn_layout.addWidget(self.select_all)
        btn_layout.addWidget(self.add_btn)
        btn_layout.addWidget(self.del_btn)
        self.list_widget = QListWidget()
        self.list_widget.setSelectionMode(QListWidget.SelectionMode.ContiguousSelection)
        self.list_widget.setAlternatingRowColors(True)
        layout.addLayout(btn_layout)
        layout.addWidget(self.list_widget)

        self.setLayout(layout)
        self.add_btn.clicked.connect(self.addItem)
        # self.list_widget.itemClicked.connect(self.itemClickedEvent)

    def addItem(self):
        item = Item()
        item.setText("test")
        self.list_widget.addItem(item)

    def itemClickedEvent(self, item: QListWidgetItem):
        pass
        if item.checkState() == Qt.CheckState.Checked:
            item.setCheckState(Qt.CheckState.Unchecked)
        else:
            item.setCheckState(Qt.CheckState.Checked)
qt
  • 2 2 个回答
  • 24 Views

2 个回答

  • Voted
  1. Best Answer
    musicamante
    2023-09-12T01:36:22+08:002023-09-12T01:36:22+08:00

    这是因为,当尝试切换该项目的复选框时,它也被单击,因此检查状态实际上更改了两次。

    您可以通过连接信号来验证这一点itemChanged:

    self.list_widget.itemChanged.connect(lambda i: print(i.checkState()))
    

    当您单击检查指示器时,信号会发出两次,第一次是新的检查状态,第二次是以前的状态,由您的函数设置。

    一个可能的解决方案是使该项目不可由用户检查:

    class Item(QListWidgetItem):
        def __init__(self):
            super().__init__()
            self.setCheckState(Qt.CheckState.Unchecked)
            self.setFlags(self.flags() & ~Qt.ItemFlag.ItemIsUserCheckable)
            self.setToolTip("double click edit")
    

    不幸的是,这样做的缺点是无法使用键盘切换状态。

    作为替代方案,您可以使用自定义委托,并使其忽略在检查指示符矩形内发生的鼠标左键释放。在这种情况下,您不得按照上面的说明更改项目标志。

    class Delegate(QStyledItemDelegate):
        _checkFlags = Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsUserCheckable
        def editorEvent(self, event, model, option, index):
            if (
                event.type() == event.Type.MouseButtonRelease
                and event.button() == Qt.MouseButton.LeftButton
                and index.flags() & self._checkFlags == self._checkFlags
                and option.state & QStyle.State.State_Enabled
            ):
                opt = QStyleOptionViewItem(option)
                self.initStyleOption(opt, index)
                checkRect = option.widget.style().subElementRect(
                    QStyle.SubElement.SE_ItemViewItemCheckIndicator, opt, option.widget)
                if event.pos() in checkRect:
                    return False
            return super().editorEvent(event, model, option, index)
    
    
    ...
    self.list_widget.setItemDelegate(Delegate(self.list_widget))
    
    • 1
  2. yotheguitou
    2023-09-12T06:55:06+08:002023-09-12T06:55:06+08:00

    或者简单地使用itemPressed而不是itemClicked:

    self.list_widget.itemPressed.connect(self.itemClickedEvent)
    

    在这里找到

    • 1

相关问题

  • 将项目拖出 MouseArea 时如何更改光标形状?

  • 在 Qt 中重用窗口[重复]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve