使用 PySide 并从 QtGui.QColorDialog 获取“实时更新”

Posted

技术标签:

【中文标题】使用 PySide 并从 QtGui.QColorDialog 获取“实时更新”【英文标题】:Using PySide and getting a "live update" from QtGui.QColorDialog 【发布时间】:2013-09-04 15:19:02 【问题描述】:

我有一个 QMainWindow 应用程序,我想在其中使用 PySide 和 QtGui.QColorDialog 实时更改 QGraphicsView 的背景颜色。

我设计了一个示例布局和程序如下;

Qt Designer 中的布局...

生成的布局 XML...

<?xml version="1.0" encoding="UTF-8"?>

<ui version="4.0">
 <class>ColourChanger</class>
 <widget class="QMainWindow" name="ColourChanger">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>486</width>
    <height>558</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QGraphicsView" name="graphicsView">
    <property name="geometry">
     <rect>
      <x>110</x>
      <y>150</y>
      <width>256</width>
      <height>192</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>150</x>
      <y>75</y>
      <width>171</width>
      <height>28</height>
     </rect>
    </property>
    <property name="text">
     <string>Change Background</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>486</width>
     <height>25</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>pushButton</sender>
   <signal>clicked()</signal>
   <receiver>ColourChanger</receiver>
   <slot>buttonPressed()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>235</x>
     <y>113</y>
    </hint>
    <hint type="destinationlabel">
     <x>242</x>
     <y>278</y>
    </hint>
   </hints>
  </connection>
 </connections>
 <slots>
  <slot>buttonPressed()</slot>
 </slots>
</ui>

代码...

#!/usr/bin/env python3.3

from PySide import QtGui, QtCore
from ColourChangerMainWindow import Ui_ColourChanger


class MainWindow(QtGui.QMainWindow, Ui_ColourChanger):
    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
        QtGui.QMainWindow.__init__(self, parent, f)
        self.setupUi(self)


    def setupStuff(self):
        self.view = self.graphicsView
        self.scene = QtGui.QGraphicsScene()
        self.scene.setSceneRect(QtCore.QRectF(self.view.viewport().rect()))
        self.view.setScene(self.scene)
        brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        self.view.setBackgroundBrush(brush)
        self.colour_chooser = QtGui.QColorDialog()
        self.colour_chooser.blockSignals(True)
        self.colour_chooser.currentColorChanged.connect(self.liveColor)
        self.colour_chooser.blockSignals(False)

    def buttonPressed(self):
        print("buttonPressed colour_chooser= ", self.colour_chooser)
        self.colour_chooser.open()

    def liveColor(self):
        value = self.colour_chooser.currentColor()
        print(value)
        print("liveColor colour_chooser= ", self.colour_chooser)



if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.setupStuff()
    window.show()
    app.exec_()
    app.deleteLater()
    sys.exit()

问题

运行时,setupStuff 函数基本上设置了一些东西,比如图形场景和视图,还设置了一个名为 color_chooser 的 QtGui.QColor 对象,其 currentColorChanged 信号连接到 liveColor 函数.

我现在只是将值打印到终端,而不是更新背景...

问题 1:为什么当我更改颜色选择时,self.colour_chooser.currentColor() 的值始终是静态的,直到我在颜色选择对话框中单击 OK

问题 2:这是对话框的限制,还是我错误地实现了这个以达到我的目标?

【问题讨论】:

【参考方案1】:

currentColorChanged 信号将当前选择的颜色作为参数传递,因此您可以使用它:

...

def liveColor(self, color):
    print(color)
    ...

对话框的curentColor 属性只有在对话框被确认后才会更新。

【讨论】:

谢谢!完美的!事后看来,阅读 PySide 文档: def currentColorChanged (color) 显然,我完全错过了这一点。 ;)【参考方案2】:

感谢上面的@mata 回答问题。

这是更新后的代码,它现在更新了 QGraphicsView 中的背景。我还在设置例程中为 colour_chooser 添加了初始黑色...

#!/usr/bin/env python3.3

from PySide import QtGui, QtCore
from ColourChangerMainWindow import Ui_ColourChanger


class MainWindow(QtGui.QMainWindow, Ui_ColourChanger):
    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
        QtGui.QMainWindow.__init__(self, parent, f)
        self.setupUi(self)


    def setupStuff(self):
        self.view = self.graphicsView
        self.scene = QtGui.QGraphicsScene()
        self.scene.setSceneRect(QtCore.QRectF(self.view.viewport().rect()))
        self.view.setScene(self.scene)
        self.brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
        self.brush.setStyle(QtCore.Qt.SolidPattern)
        self.view.setBackgroundBrush(self.brush)
        self.colour_chooser = QtGui.QColorDialog()
        self.colour_chooser.setCurrentColor(QtGui.QColor(0, 0, 0))
        self.colour_chooser.blockSignals(True)
        self.colour_chooser.currentColorChanged.connect(self.liveColor)
        self.colour_chooser.blockSignals(False)


    def buttonPressed(self):
        self.colour_chooser.open()

    def liveColor(self, color):
        self.view.setBackgroundBrush(color)




if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.setupStuff()
    window.show()
    app.exec_()
    app.deleteLater()
    sys.exit()

【讨论】:

奖励:将 self.colour_chooser.open() 更改为 self.colour_chooser.exec_() ,以便在选择颜色后继续在同一函数中执行。

以上是关于使用 PySide 并从 QtGui.QColorDialog 获取“实时更新”的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 QItemDelegate 更改 QTableView 文本颜色?

QTableWidget - 更改行颜色

在场景中执行修改并从 Maya 中的 QThread 更新自定义窗口

使用 PySide / PyQt 的问题

使用 PySide2 开发 Maya 插件系列 总览

PySide和PySide2之间的QKeySequence区别