亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用PyQt編寫一個簡單的待辦程序

 更新時間:2025年02月18日 09:33:44   作者:0zxm  
這篇文章主要為大家詳細介紹了如何使用PyQt編寫一個簡單的待辦程序,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一

框架選擇

一個簡單的GUI程序,可以使用pyqt完成。pyqt是qt的python實現版本。

界面搭建

設計一個美觀

簡潔的界面

class ToDoApp(QWidget):
    def __init__(self):
        super().__init__()

        # 設置窗口屬性
        self.setWindowTitle("Daily To Do List")
        self.setGeometry(100, 100, 400, 400)

        # 初始化主布局
        self.main_layout = QVBoxLayout()

        # 創(chuàng)建輸入和添加按鈕
        self.input_layout = QGridLayout()

        # 標題輸入
        self.title_label = QLabel("標題:")
        self.title_input = QLineEdit()
        self.input_layout.addWidget(self.title_label, 0, 0)
        self.input_layout.addWidget(self.title_input, 0, 1)

        # 描述輸入
        self.description_label = QLabel("描述:")
        self.description_input = QLineEdit()
        self.input_layout.addWidget(self.description_label, 1, 0)
        self.input_layout.addWidget(self.description_input, 1, 1)

        # 水平按鈕布局
        self.add_layout = QHBoxLayout()
        self.add_layout.setSpacing(20)

        # 導入
        self.import_button = QPushButton('批量導入')
        self.import_button.clicked.connect(self.import_item)
        self.add_layout.addWidget(self.import_button)
        
        self.add_button = QPushButton("添加")
        self.add_button.clicked.connect(self.add_item)
        self.add_layout.addWidget(self.add_button)

        # 任務列表
        self.to_do_list = QListWidget()
        self.to_do_list.setStyleSheet("padding: 10px;")
        self.to_do_list.setVerticalScrollMode(QListWidget.ScrollPerPixel)

        # 創(chuàng)建操作按鈕
        self.buttons_layout = QHBoxLayout()
        self.mark_done_button = QPushButton("標記完成")
        self.mark_done_button.clicked.connect(self.mark_item_done)
        self.delete_button = QPushButton("刪除")
        self.delete_button.clicked.connect(self.delete_item)
        self.buttons_layout.addWidget(self.mark_done_button)
        self.buttons_layout.addWidget(self.delete_button)

        # 將布局添加到主窗口
        self.main_layout.addLayout(self.input_layout)
        self.main_layout.addLayout(self.add_layout)
        self.main_layout.addWidget(self.to_do_list)
        self.main_layout.addLayout(self.buttons_layout)

        # 設置窗口布局
        self.setLayout(self.main_layout)

QGridLayout的使用

QGridLayout是網格布局,在添加子窗口時可以設定位置(行、列)和占據的大?。ㄕ紟仔袔琢校?/p>

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QLabel, QPushButton

class GridExample(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("PyQt QGridLayout Example")
        self.setGeometry(100, 100, 400, 300)

        # 創(chuàng)建 QGridLayout
        layout = QGridLayout(self)

        # 創(chuàng)建一個標題標簽
        title_label = QLabel("Header Label", self)
        title_label.setStyleSheet("font-size: 18px; font-weight: bold; color: blue;")
        # 將標題設置為占據第一行的所有列
        layout.addWidget(title_label, 0, 0, 1, 3)  # 行, 列, 占據行數, 占據列數

        # 創(chuàng)建一個 3x3 的按鈕網格
        for i in range(3):
            for j in range(3):
                button = QPushButton(f"Button {i*3 + j +1}", self)
                layout.addWidget(button, i + 1, j)  # 按鈕從行1開始

        # 創(chuàng)建一個右側按鈕占據一列
        right_button = QPushButton("Right Button", self)
        # 設置右側按鈕占據第3列的所有行
        layout.addWidget(right_button, 1, 3, 3, 1)  # 行1到3, 列3

        # 創(chuàng)建一個底部按鈕占據一行
        bottom_button = QPushButton("Bottom Button", self)
        # 設置底部按鈕占據第4行的所有列
        layout.addWidget(bottom_button, 4, 0, 1, 4)  # 行4, 列0-3

        self.setLayout(layout)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = GridExample()
    window.show()
    sys.exit(app.exec_())

強制子窗口獨立

在 PyQt 中,當給窗口(QWidget 或子類)設置 parent 后窗口不顯示,通常是因為 子窗口被嵌入到了父窗口的布局中,而非作為獨立窗口顯示。以下是常見原因和解決方案:

1. 根本原因:parent 的作用

parent 的作用:在 PyQt 中,parent 表示窗口的父控件。若設置 parent

  • 子窗口會嵌入到父窗口中,成為父窗口的一部分(類似按鈕、文本框等控件)。
  • 子窗口的生命周期與父窗口綁定(父窗口銷毀時,子窗口自動銷毀)。
  • 子窗口默認不會作為獨立窗口彈出,而是跟隨父窗口的布局顯示。

關鍵區(qū)別

# 獨立窗口(無 parent)
child_window = QWidget()
child_window.show()

# 嵌入父窗口(設置 parent)
child_window = QWidget(parent=main_window)  # 不會獨立顯示,而是嵌入到 main_window 中

2. 常見場景和解決方法

場景 1:希望子窗口作為獨立窗口彈出

錯誤寫法

parent_window = QWidget()
child_window = QWidget(parent=parent_window)  # 設置 parent
child_window.show()  # ? 不會顯示獨立窗口!

原因child_window 已成為 parent_window 的子控件,必須通過父窗口的布局顯示(例如將 child_window 添加到父窗口的 QVBoxLayout 中)。

解決方法不要設置 parent,讓子窗口獨立:

parent_window = QWidget()
child_window = QWidget()  # 無 parent
child_window.show()       # ? 作為獨立窗口顯示

場景 2:希望子窗口作為模態(tài)對話框彈出

錯誤寫法

parent_window = QWidget()
child_window = QWidget(parent=parent_window)
child_window.setWindowModality(Qt.ApplicationModal)  # 設置為模態(tài)
child_window.show()  # ? 仍然不顯示!

原因child_windowparent_window 的子控件,必須通過父窗口布局顯示,或明確設置為獨立窗口。

解決方法:使用 Qt.Window 標志強制子窗口成為獨立窗口:

child_window = QWidget(parent=parent_window)
child_window.setWindowFlags(Qt.Window)  # 關鍵:強制為獨立窗口
child_window.setWindowModality(Qt.ApplicationModal)
child_window.show()  # ? 作為模態(tài)對話框彈出

場景 3:子窗口被正確添加到父窗口布局但仍不顯示

錯誤寫法

parent_window = QWidget()
child_window = QWidget(parent=parent_window)
parent_window.show()  # ? 只顯示 parent_window,但 child_window 未添加到布局中

原因child_window 需要被添加到父窗口的布局管理器(如 QVBoxLayout),或手動設置其位置。

解決方法:將子窗口添加到父窗口布局:

parent_window = QWidget()
layout = QVBoxLayout(parent_window)  # 父窗口設置布局
child_window = QWidget()
layout.addWidget(child_window)       # 添加到布局
parent_window.show()  # ? 父窗口和子控件均顯示

3. 通用檢查列表

如果子窗口不顯示,按以下步驟排查:

.是否設置 parent

若設置 parent,子窗口需要添加到父窗口的布局中。

.父窗口是否已顯示

父窗口調用 show() 后,子控件才會顯示。

.窗口標志是否正確

使用 setWindowFlags(Qt.Window) 強制子窗口獨立。

.布局是否正確

確保子窗口被添加到父窗口的布局管理器(如 addWidget(child))。

.生命周期問題

確保父窗口未被提前銷毀(例如在局部作用域中被垃圾回收)。

4. 完整示例對比

示例 1:子窗口嵌入父窗口(正確寫法)

from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QApplication

app = QApplication([])

# 父窗口
parent = QWidget()
layout = QVBoxLayout(parent)

# 子窗口(作為控件嵌入父窗口)
child = QPushButton("我是子控件", parent=parent)
layout.addWidget(child)

parent.show()
app.exec_()

示例 2:子窗口作為獨立窗口(正確寫法)

from PyQt5.QtWidgets import QWidget, QApplication

app = QApplication([])

# 父窗口
parent = QWidget()
parent.show()

# 子窗口(獨立窗口,無 parent)
child = QWidget()
child.setWindowTitle("我是獨立子窗口")
child.show()

app.exec_()

5. 特殊場景:動態(tài)創(chuàng)建子窗口

若通過按鈕點擊動態(tài)創(chuàng)建子窗口,需確保子窗口的引用不被銷毀:

from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout, QApplication

app = QApplication([])

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.button = QPushButton("打開子窗口", self)
        self.button.clicked.connect(self.open_child)
        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.button)

    def open_child(self):
        self.child = QWidget()  # 必須保存為成員變量,否則會被垃圾回收!
        self.child.setWindowTitle("子窗口")
        self.child.show()

window = MainWindow()
window.show()
app.exec_()

通過理解 parent 的作用和布局機制,可以靈活控制窗口的顯示方式。

模型設計

每一個待辦事項有

  • 標題
  • 描述信息
  • 生成時間
  • 是否完成標識
  • 截止時間
class ToDoItem:
    def __init__(self, title, description,deadline_time=None,is_completed=False):
        self.title = title
        self.description = description
        self.deadline_time = deadline_time
        self.is_completed = False

自定義信號

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QMessageBox
from PyQt5.QtCore import pyqtSignal
import sys

class MyWidget(QWidget):
    # 定義一個自定義信號
    custom_signal = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("PyQt Custom Signal Example")
        self.setGeometry(100, 100, 300, 200)

        # 創(chuàng)建一個按鈕
        self.button = QPushButton("Click Me", self)
        self.button.clicked.connect(self.emit_custom_signal)

        # 設置布局
        layout = QVBoxLayout()
        layout.addWidget(self.button)
        self.setLayout(layout)

        # 連接自定義信號到槽
        self.custom_signal.connect(self.handle_custom_signal)

    def emit_custom_signal(self):
        """發(fā)射自定義信號"""
        self.custom_signal.emit("Hello from custom signal!")

    def handle_custom_signal(self, message):
        """處理自定義信號"""
        QMessageBox.information(self, "Custom Signal", message)

if __name__ == "__main__":
    app = QApplication(sys.argv)

    widget = MyWidget()
    widget.show()

    sys.exit(app.exec_())

批量導入功能

使用json格式的字符串進行批量導入,大致格式如下

{
    "items": [
        {
            "title": "測試標題1",
            "description": "測試1",
            "deadline_time": "2024",
            "is_completed": false
        },
        {
            "title": "測試標題2",
            "description": "測試2",
            "deadline_time": "2025",
            "is_completed": true
        }
    ]
}

大致就是新開一個窗口,創(chuàng)建一個QTextEdit輸入對應的json數據,然后通過json.loads()方法解析對應數據,
逐個使用add_item()接口添加,這要求add_item()能夠處理多種情況:按鈕點擊觸發(fā)無需參數批量導入中需要傳遞參數。

而在python中實現類似重載的效果可以給參數一個默認值None,再在函數內部分情況處理

class ImportWidget(QWidget):
    # 自定義信號
    import_finished = pyqtSignal(dict)
    def __init__(self,parent):
        super().__init__(parent)
        self.setFixedSize = (500,500)
        self.setWindowFlags(Qt.Window)  # 關鍵:強制為獨立窗口
        self.input_field = QTextEdit()
        self.main_layout = QVBoxLayout()
        self.btn_layout = QHBoxLayout()
        self.confirm_button = QPushButton("導入")
        self.cancel_button = QPushButton("取消")
        self.btn_layout.addWidget(self.confirm_button)
        self.btn_layout.addWidget(self.cancel_button)

        self.confirm_button.clicked.connect(self.read_json_data)
        # 連接自定義信號到槽
        self.import_finished.connect(self.close)

        self.main_layout.addLayout(self.btn_layout)
        self.main_layout.addWidget(self.input_field)
        self.setLayout(self.main_layout)

    def read_json_data(self):
        text = self.input_field.toPlainText()  # 獲取輸入框的文本
        # print(f"原始文本內容: {text}")  # 調試:打印原始文本內容
        try:
            # 將輸入的文本解析為 JSON 數據
            json_data = json.loads(text.strip())  # 使用 strip() 去除首尾空白字符
            # print(f"解析后的 JSON 數據: {json_data}")
            self.json_data = json_data   
            self.import_finished.emit(json_data)
        except json.JSONDecodeError as e:
            # 如果 JSON 格式不正確,打印錯誤信息
            print(f"JSON 解析失敗: {e}")
            self.json_data =  None
class ToDoApp(QWidget):
    def batch_import(self,json_data):
        print(json_data['items'])
        items = json_data['items']
        for item in items:
            self.add_item(item['title'],item['description'])
        
    def add_item(self, checked,title=None, description=None):
        # 如果 title 和 description 是傳入的參數
        if title is not None or description is not None:
            # 使用傳入的參數
            title = title.strip() if title else ""
            description = description.strip() if description else ""
        else:
            # 獲取輸入框的文本
            title = self.title_input.text().strip()
            print(title, description)
            description = self.description_input.text().strip()
        # TODO 優(yōu)化時間顯示居右
        current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        # 創(chuàng)建 ToDoItem 實例
        todo_item = ToDoItem(title, description, current_time)

        # 創(chuàng)建新的列表項  創(chuàng)建自定義Widget
        item_widget = QWidget()
        layout = QHBoxLayout()

        # 標題部分
        title_label = QLabel(todo_item.title)
        title_label.setStyleSheet("QLabel{padding:0px}")
        title_label.setAlignment(Qt.AlignmentFlag.AlignLeft| Qt.AlignmentFlag.AlignVCenter)

        # 時間部分
        time_label = QLabel(todo_item.created_time)
        time_label.setStyleSheet("QLabel{padding:0px}") # 添加padding設置,Qlabel有默認padding,不設置話,會將文字截斷
        time_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)

        # 添加控件到布局
        layout.addWidget(title_label)
        layout.addWidget(time_label)
        item_widget.setLayout(layout)

        # 創(chuàng)建ListWidgetItem
        item = QListWidgetItem()
        item.setSizeHint(item_widget.sizeHint())  # 設置每一項的寬高
        item.setToolTip(todo_item.description) # 設置懸浮提示
        item.setData(Qt.UserRole, todo_item)  # 保存任務對象
        item.setFlags(item.flags() | Qt.ItemIsSelectable | Qt.ItemIsEnabled)  
        item.setCheckState(Qt.CheckState.Unchecked)
        self.to_do_list.addItem(item)
        self.to_do_list.setItemWidget(item, item_widget)
        
        # 清空輸入框
        self.title_input.clear()
        self.description_input.clear()

bug解析

使用按鈕連接點擊信號至槽函數,發(fā)現槽函數add_item接收到的title參數不是預期的輸入值None(因為點擊事件的槽函數一般不帶參數),而是False。

1.PyQt 的 clicked 信號默認會傳遞一個布爾值:

  • QPushButtonclicked 信號默認會發(fā)送一個 checked 參數(表示按鈕的選中狀態(tài))。
  • 如果你沒有顯式處理這個參數,它會傳遞到槽函數中,導致 title 參數被賦值為 False(因為默認未選中)。

2.槽函數定義與信號參數不匹配

你定義的 add_item 方法有兩個可選參數:

def add_item(self, title=None, description=None):

當通過 self.add_button.clicked.connect(self.add_item) 連接信號時,clicked 信號的 checked 參數(布爾值)會傳遞給 title 參數。

因此,點擊按鈕時 title 實際接收到的是 False,而不是預期的 None。

方法 1:顯式接收并忽略 checked 參數

修改槽函數,增加一個參數接收 checked 值,但不在內部使用它:

def add_item(self, checked, title=None, description=None):  # 增加 checked 參數
    # 如果 title 和 description 是傳入的參數
    if title is not None or description is not None:
        print("not null", title, description)
        title = title.strip() if title else ""
        description = description.strip() if description else ""
    else:
        # 獲取輸入框的文本
        title = self.title_input.text().strip()
        description = self.description_input.text().strip()
    # 其他邏輯...

方法 2:使用 lambda 阻止參數傳遞

在連接信號時,通過 lambda 屏蔽 clicked 信號的參數:

self.add_button.clicked.connect(lambda: self.add_item())  # 不傳遞任何參數

此時 titledescription 將保持 None,代碼會從輸入框中讀取值。

關鍵點解釋

信號參數傳遞機制

  • clicked 信號默認發(fā)送 checked(布爾值),而 QPushButton 默認不可選中,因此總是發(fā)送 False
  • 如果槽函數參數數量不匹配,第一個參數會接收這個 False。

參數優(yōu)先級問題

  • 如果調用 add_item 時傳遞了參數(如 add_item(title="測試")),title 會被正確賦值。
  • 若未傳遞參數,title 會被錯誤地賦值為 False(來自 checked 參數)。 

導出

既然有批量導入功能,就有導出功能

剪切板 QClipboard

在 PyQt 中,可以使用 QApplication.clipboard() 來訪問系統(tǒng)剪貼板,并通過 QClipboard 類的方法將數據復制到剪貼板

def export_to_clipboard(self):
        # 獲取所有任務
        items = []
        for i in range(self.to_do_list.count()):
            item = self.to_do_list.item(i)
            if item:
                todo_item = item.data(Qt.UserRole)
                items.append({
                    "title": todo_item.title,
                    "description": todo_item.description,
                    "deadline_time": todo_item.deadline_time,
                    "is_completed": todo_item.is_completed
                })
        # 轉換為 JSON 格式
        json_data = {
            "items": items
        }
        json_str = json.dumps(json_data, indent=4, ensure_ascii=False)  # 格式化 JSON 字符串
        # 復制到剪切板
        clipboard = QApplication.clipboard()
        clipboard.setText(json_str)
        # 彈出提示
        QMessageBox.information(self, "提示", "已復制到剪切板")

常用的 QClipboard 方法

  • setText(text): 將文本復制到剪貼板。
  • setPixmap(pixmap): 將圖片復制到剪貼板。
  • setMimeData(mimeData): 將 MIME 數據(如 HTML)復制到剪貼板。
  • clear(): 清除剪貼板內容。

持久化存儲

  • 數據庫sqlite
  • 文件保存

直接寫入文件,不使用數據庫了,重寫關閉事件,保存代辦到文件,并在初始化的時候讀取文件

    def init_from_file(self, file_path=None):
        # 默認初始化文件為當前目錄下的 to_do.json
        if file_path is None:
            file_path = "./to_do.json"
            # 讀取文件內容
        with open(file_path, "r", encoding="utf-8") as f:
            text = f.read()
            self.batch_import(json.loads(text))

    def closeEvent(self, event):
        # 關閉窗口時保存數據
        with open("./to_do.json", "w", encoding="utf-8") as f:
            self.export_to_clipboard(True)
            f.write(QApplication.clipboard().text())
            QApplication.clipboard().clear()
        event.accept()

排序功能

截止時間ddl排序

def sort_by_ddl(self):
        if self.sort_value == "asc":
            self.sort_value = "desc"
        else:
            self.sort_value = "asc"
        # 按 DDL 排序
        items = []
        for i in range(self.to_do_list.count()):
            item = self.to_do_list.item(i)
            if item:
                todo_item = item.data(Qt.UserRole)
                items.append(todo_item)
        # 根據self.sort_value決定排序方向
        if self.sort_value == "asc":
            items.sort(key=self.sort_key)
        else:
            items.sort(key=self.sort_key, reverse=True)
        # 清空列表
        self.to_do_list.clear()
        # 重新添加排序后的任務
        for item in items:
            self.add_item(item.title, item.description, item.deadline_time, item.is_completed)
    
    def sort_key(self, item):
        item.deadline_time.replace(":",":")
        if item.deadline_time == "未知":
            return datetime.datetime.max
        else:
            return datetime.datetime.strptime(item.deadline_time.replace(":",":"), "%Y-%m-%d %H:%M")

自定義排序規(guī)則

在Python中自定義排序規(guī)則,你可以使用內置的sorted()函數或者列表對象的sort()方法,并通過key參數指定一個函數來定義排序規(guī)則。這個函數會對每個元素進行處理,并返回一個值,排序將根據這個返回值進行。

按字符串長度排序:

strings = ["apple", "banana", "cherry", "date"]
sorted_strings = sorted(strings, key=len)
print(sorted_strings)  # 輸出: ['date', 'apple', 'banana', 'cherry']

使用lambda函數按字符串的最后一個字符排序:

strings = ["apple", "banana", "cherry", "date"]
sorted_strings = sorted(strings, key=lambda x: x[-1])
print(sorted_strings)  # 輸出: ['banana', 'apple', 'date', 'cherry']

復雜排序規(guī)則,先按字符串長度排序,再按字母順序排序:

strings = ["apple", "banana", "cherry", "date"]
sorted_strings = sorted(strings, key=lambda x: (len(x), x))
print(sorted_strings)  # 輸出: ['date', 'apple', 'banana', 'cherry']

使用cmp_to_key將傳統(tǒng)比較函數轉換為key函數:

from functools import cmp_to_key

def compare(x, y):
    if x < y:
        return -1
    elif x > y:
        return 1
    else:
        return 0

numbers = [3, 2, 5, 4, 1]
sorted_numbers = sorted(numbers, key=cmp_to_key(compare))
print(sorted_numbers)  # 輸出: [1, 2, 3, 4, 5]

優(yōu)化條目顯示

添加一個標題布局,顯示列表的標題 => 放一個水平布局在QListWidget上對齊就可以

分離顯示與數據(QlistWidget):

  • 不再直接使用 QListWidgetItem(text),而是通過 setItemWidget 綁定自定義Widget
  • 數據仍存儲在 ToDoItem 對象中,界面僅負責展示

自定義Widget布局控制:

  • 使用 QHBoxLayout 實現水平分列
  • setAlignment 控制對齊方向
  • setContentsMargins 調整內容間距

Bug解析

文字出現了上下截斷的情況,嘗試過設置延伸策略,給item設置固定寬高都不能根治

發(fā)現隨著高度的變大,顯示的內容越來越多,所以猜測是QLabel有默認的padding,所以截斷了文字

最后設置QStyleSheet成功解決

# TODO 優(yōu)化時間顯示居右
# 創(chuàng)建 ToDoItem 實例
todo_item = ToDoItem(title, description,deadline_time,is_completed)
# 創(chuàng)建新的列表項  創(chuàng)建自定義Widget
item_widget = QWidget()
layout = QHBoxLayout()

# 標題部分
title_label = QLabel(todo_item.title)
title_label.setStyleSheet("QLabel{padding:0px}")
title_label.setAlignment(Qt.AlignmentFlag.AlignLeft| Qt.AlignmentFlag.AlignVCenter)

# 時間部分
time_label = QLabel(todo_item.deadline_time)
time_label.setStyleSheet("QLabel{padding:0px}") # 添加padding設置,Qlabel有默認padding,不設置話,會將文字截斷
time_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)

# 添加控件到布局
layout.addWidget(title_label)
layout.addWidget(time_label)
item_widget.setLayout(layout)

# 創(chuàng)建ListWidgetItem
item = QListWidgetItem()
item.setSizeHint(item_widget.sizeHint())  # 設置每一項的寬高
item.setToolTip(todo_item.description) # 設置懸浮提示
item.setData(Qt.UserRole, todo_item)  # 保存任務對象
item.setFlags(item.flags() | Qt.ItemIsSelectable | Qt.ItemIsEnabled |Qt.ItemIsUserCheckable)
if todo_item.is_completed:
    item.setCheckState(Qt.CheckState.Checked)  
else:
    item.setCheckState(Qt.CheckState.Unchecked)
    self.to_do_list.addItem(item)
    self.to_do_list.setItemWidget(item, item_widget)

    # 清空輸入框
    self.title_input.clear()
    self.description_input.clear()
    self.deadline_input.clear()

綁定自定義widget后,點擊無法改變itemcheckState

解決方法有很多種,這里采用連接父ListWidget的雙擊信號

self.to_do_list.doubleClicked.connect(self.on_double_clicked)

def on_double_clicked(self, index: QModelIndex):
    print(index.row())  # 打印行號
    print(index.column())  # 打印列號(通常為 0)
    item = self.to_do_list.itemFromIndex(index)  # 獲取 QListWidgetItem
    if item.checkState() == Qt.CheckState.Unchecked:
        item.setCheckState(Qt.CheckState.Checked)
    elif item.checkState() == Qt.CheckState.Checked :
        item.setCheckState(Qt.CheckState.Unchecked)
    print(item.text())  # 打印項的文本

最終代碼

https://github.com/0zxm/ToDoApp/tree/master

以上就是使用PyQt編寫一個簡單的待辦程序的詳細內容,更多關于PyQt待辦程序的資料請關注腳本之家其它相關文章!

相關文章

  • 淺談Python Pygame圖像的基本使用

    淺談Python Pygame圖像的基本使用

    今天給大家?guī)淼氖顷P于Python Pygame的相關知識,文章圍繞著Pygame圖像的基本使用展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • pandas?groupby?用法實例詳解

    pandas?groupby?用法實例詳解

    在日常數據分析過程中,經常有分組的需求。具體來說,就是根據一個或者多個字段,將數據劃分為不同的組,然后進行進一步分析,比如求分組的數量,分組內的最大值最小值平均值等,下面我們就來看看pandas中的groupby怎么使用,需要的朋友可以參考下
    2022-11-11
  • Python PyQt5整理介紹

    Python PyQt5整理介紹

    PyQt5 是Digia的一套Qt5應用框架與python的結合,同時支持2.x和3.x。這篇文章給大家整理了關于Python PyQt5的相關知識,感興趣的朋友一起看看吧
    2020-04-04
  • 解決python3在anaconda下安裝caffe失敗的問題

    解決python3在anaconda下安裝caffe失敗的問題

    下面小編就為大家?guī)硪黄鉀Qpython3在anaconda下安裝caffe失敗的問題。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • numpy.std() 計算矩陣標準差的方法

    numpy.std() 計算矩陣標準差的方法

    今天小編就為大家分享一篇numpy.std() 計算矩陣標準差的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • Python 爬蟲多線程詳解及實例代碼

    Python 爬蟲多線程詳解及實例代碼

    這篇文章主要介紹了Python 爬蟲多線程詳解及實例代碼的相關資料,需要的朋友可以參考下
    2016-10-10
  • Python 獲取指定文件夾下的目錄和文件的實現

    Python 獲取指定文件夾下的目錄和文件的實現

    這篇文章主要介紹了Python 獲取指定文件夾下的目錄和文件的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • Tensorflow的常用矩陣生成方式

    Tensorflow的常用矩陣生成方式

    今天小編就為大家分享一篇Tensorflow的常用矩陣生成方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • Python通過keyboard庫實現模擬和監(jiān)聽鍵盤

    Python通過keyboard庫實現模擬和監(jiān)聽鍵盤

    這篇文章主要為大家詳細介紹了Python如何通過keyboard庫實現模擬和監(jiān)聽鍵盤,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2024-10-10
  • 一波神奇的Python語句、函數與方法的使用技巧總結

    一波神奇的Python語句、函數與方法的使用技巧總結

    這篇文章主要介紹了一波神奇的Python函數與方法的使用技巧總結,包括裝飾器和with語句等的不常見用法,需要的朋友可以參考下
    2015-12-12

最新評論