Slot触发自己的信号

时间:2016-04-05 07:23:28

标签: python qt pyqt

我正在尝试设置一个QTableWidget,用户在更改后将红色标记为红色。

table.itemChanged.connect(flag_cell_unsaved)

@pyqtSlot(QtGui.QTableWidgetItem)
def flag_cell_unsaved(item):
    item.setForeground(Qt.red)

但是,将项目文本更改为红色会导致发出另一个itemChanged信号。

我可以通过在插槽功能期间断开信号来解决这个问题,但我觉得应该有更好/更简单的方法来解决这个问题。

3 个答案:

答案 0 :(得分:2)

对发出信号的QObject使用blockSignals

from scrapy.spiders import Spider
from scrapy.selector import Selector

from second_hotel.items import Website


class secondhotelSpider(Spider):
    name = "second_hotel_spider.py"
    allowed_domains = ["uk.hotels.com"]
    start_urls = [
        "https://uk.hotels.com/hotel/details.html?FPQ=6&WOE=1&q-localised-check-out=10/04/2017&WOD=1&q-room-0-children=0&pa=1&tab=description&JHR=9&q-localised-check-in=03/04/2017&hotel-id=128604&q-room-0-adults=2&YGF=14&MGT=7&ZSX=0&SYE=3",
        "https://uk.hotels.com/hotel/details.html?FPQ=6&WOE=1&q-localised-check-out=04/04/2016&WOD=7&q-room-0-children=0&pa=1&tab=description&JHR=8&q-localised-check-in=03/04/2016&hotel-id=424807&q-room-0-adults=2&YGF=2&MGT=1&ZSX=0&SYE=3",
    ]

    def parse(self, response):

        sel = Selector(response)
        sites = sel.xpath('//ul[@class="directory-url"]/li')
        items = []

        for site in sites:
            item = Website()
            item['name'] = site.xpath('a/text()').extract()
            item['link'] = site.xpath('a/@href').extract()
            item['description'] = site.xpath('text()').re('-\s[^\n]*\\r')
            items.append(item)

        print items
        return items

答案 1 :(得分:2)

这是正确的行为:毕竟你的项目确实发生了变化。只要您不必要地修改项目,这不是问题:

@pyqtSlot(QtGui.QTableWidgetItem)
def flag_cell_unsaved(self, item):
    if item.foreground() != Qt.red:
        item.setForeground(Qt.red)

答案 2 :(得分:1)

添加到Zlatomir's答案,将其包含在上下文管理器中可以帮助防止它在blockSignals调用之间发生异常时无意中使所有信号静音。它还允许您进行嵌套操作,这些操作需要阻止信号,并确保在嵌套块的中间不重新启用信号。

import contextlib

@contextlib.contextmanager
def block_signals(obj):
    orig = obj.signalsBlocked()
    obj.blockSignals(True)
    yield obj
    obj.blockSignals(orig)

...

with block_signals(table_widget):
    item.setForeground(Qt.red)
    with block_signals(table_widget):
        pass
    # Signals are still blocked here.