2014-06-05 4 views
0

QCheckBox에 문제가 있습니다.Python2 PyQt4 bool 변수를 QCheckBox 항목에 연결하십시오.

boolean 변수를 변경하면 부울 변수를 변경할 때 부울 변수를 QCheckBox에 연결하려고하면 QCheckBox가 자동으로 선택되거나 선택 취소됩니다.

내 질문은 아래의 질문과 유사하지만 반대입니다.

question: Python3 PyQt4 Creating a simple QCheckBox and changing a Boolean variable

난 그냥 여기에 그 질문에서 하나 개의 솔루션을 복사합니다.

import sys 

from PyQt4.QtGui import * 
from PyQt4.QtCore import * 

class SelectionWindow(QMainWindow): 
    def __init__(self, parent=None): 
     super().__init__(parent) 

     self.ILCheck = False 

     ILCheckbox = QCheckBox(self) 
     ILCheckbox.setCheckState(Qt.Unchecked) 

     ILCheckbox.stateChanged.connect(self.ILCheckbox_changed) 

     MainLayout = QGridLayout() 
     MainLayout.addWidget(ILCheckbox, 0, 0, 1, 1) 

     self.setLayout(MainLayout) 

    def ILCheckbox_changed(self, state): 
     self.ILCheck = (state == Qt.Checked) 

     print(self.ILCheck) 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    window = SelectionWindow() 

    window.show() 
    window.ILCheck = True 
    sys.exit(app.exec_()) 

이 경우 ILCheck를 True로 설정하면 QCheckBox가 선택됩니다.

도움이 될 것입니다!

감사합니다 !!!!


업데이트 : 내 프로젝트에 MVC를 사용하고

는, 단지 예 위의 코드는 내가 필요로하는 것을 보여줍니다. bool 값 ILCheck은 다른 곳에서 사용되며, 내 모델에는 ILCheckBox으로 전화하고 싶지 않습니다.

나는 ILCheck의 값을 수정하면 ILCheckBox이 correctlly 반응 할 것으로 기대합니다.


업데이트 : 모든 응답과 도움을

감사합니다. 모든 솔루션은 훌륭합니다! 필요한 방식은 Modeling-View 솔루션과 유사하여 모델링 파트를 gui 파트와 분리 할 수 ​​있습니다. 업데이트 할 때 업데이트 모델링이 필요하고 GUI가 어떻게 보이는지주의를 기울일 필요가 없습니다. 이 솔루션을 사용할 수 없도록 뷰 클래스에서이 Bool 속성을 설정할 수 없습니다.

MVC가 PyQT에 적합하지 않은 것으로 확신합니다. 아래에 문제가있는 가까운 해결책이 있습니다.

from PyQt4 import QtGui, QtCore, uic 
import sys 
class CellList(QtGui.QStandardItemModel): 
    def __init__(self, cells = [], parent = None): 
     QtGui.QStandardItemModel.__init__(self, parent) 
     self.__cells = cells 
     self.add(cells) 

    def headerData(self, section, orientation, role): 
     if role == QtCore.Qt.DisplayRole: 
      return QtCore.QString("Cell id List") 
    def flags(self, index): 
     return QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable 

    def add(self, cells): 
     for i in xrange(0, len(cells)): 
      item = QtGui.QStandardItem('Cell %s' % cells[i][0]) 
      if (cells[i][1]): 
       item.setCheckState(QtCore.Qt.Checked) 
      else: 
       item.setCheckState(QtCore.Qt.Unchecked) 

      item.setCheckable(True) 
      self.appendRow(item) 
    def update(self, cells = None): 
     # TODO: Making this working with out clean all old Cell 
     self.clear() 
     if cells is None: 
      cells = self.__cells 
     else: 
      print "hi" 
      self.__cells = cells 
     print cells 
     self.add(cells) 

if __name__ == '__main__': 

    app = QtGui.QApplication(sys.argv) 
    listView = QtGui.QListView() 
    listView.show() 

    data = [[85, True], (105, True), (123, False)] 
    model = CellList(data) 
    listView.setModel(model) 

    data[0][1] = False 
    model.update(data) 

    sys.exit(app.exec_()) 

이 해결 방법에는 문제가 있으며 해결할 수 없습니다. 나는보기 만이 모델을 설정할 수 있다고 생각한다. 모델을 단일 QCheckBox으로 설정할 수 있는지 확실하지 않습니다. .

+0

당신이 할 수의 끝에 추가 된 @의 property'하지만 당신이 필요 왜 내가 볼 수없는'와. 체크 박스를 드러내고 변수에 할당하는 대신'setChecked'를 사용하십시오. – Avaris

+0

@Avaris 귀하의 도움에 감사드립니다. MVC를 사용하고 있으므로 ModelBox에'checkBox'를 노출하고 싶지는 않습니다. – NewPlayerX

+0

답변을 작성 하겠지만 여전히 올바른 방법이라고 생각하지 않습니다. 그러나 유스 케이스를 이해하지 않고는 (QDataWidgetMapper) 다른 것을 제안 할 수는 없습니다. – Avaris

답변

1

=이 문제를 해결하기위한 좋은 시작 연산자의 오버로드를 모방, 그/그녀의 대답에 보여줍니다. 그러나 여전히 코드 인 문제는 SelectionWindow 클래스에 추가되었습니다.

그러나 우리는 Qt을 사용하고 있으므로 값을 변경하면 신호를 방출하는 "스마트"부울 변수를 나타내는 사용자 정의 QObject을 구현할 수 있습니다.

self.ILCheck = False 

로 :

이 라인 교체 :

class SmartBool(QObject): 

    valueChanged = pyqtSignal(bool)   # Signal to be emitted when value changes. 

    def __init__(self): 
     super(SmartBool, self).__init__() # Call QObject contructor. 
     self.__value = False    # False initialized by default. 

    @property 
    def value(self): 
     return self.__value 

    @value.setter 
    def value(self, value): 
     if self.__value != value: 
      self.valueChanged.emit(value) # If value change emit signal. 
      self.__value = value 

지금 코드가 변경 불과 몇 필요

self.ILCheck = SmartBool() 

을하고, 신호와 슬롯을 연결, 추가 위의 줄 다음에 _ _ init _ _ 행을 추가하십시오. 당신의 "주"에

window.ILCheck.value = True 

당신은 체크 박스가 체크 표시됩니다 중요 , 당신은 추가 결과를 테스트하기위한 SelectionWindow 클래스

self.connect(self.ILCheck, SIGNAL("valueChanged(bool)"), ILCheckbox, SLOT("setChecked(bool)")) 

내에서 연결을 결합되지 않습니다 다음에 예제를 실행합니다.

전체 코드 예제

는 stetical 이유

import sys 
from PyQt4.QtGui import * 
from PyQt4.QtCore import * 

class SmartBool(QObject): 

    valueChanged = pyqtSignal(bool)   # Signal to be emitted when value changes. 

    def __init__(self, value=False): 
     super(SmartBool, self).__init__() # Call QObject contructor. 
     self.__value = value    # False initialized by default. 

    @property 
    def value(self): 
     return self.__value 

    @value.setter 
    def value(self, value): 
     if self.__value != value: 
      self.valueChanged.emit(value) # If value change emit signal. 
      self.__value = value 


class SelectionWindow(QMainWindow): 
    def __init__(self, parent=None): 
     super().__init__(parent) 
     self.ILCheck = SmartBool()   # Your steroides bool variable. 
     ILCheckbox = QCheckBox(self) 
     self.connect(self.ILCheck, SIGNAL("valueChanged(bool)"), ILCheckbox, SLOT("setChecked(bool)")) 
     ILCheckbox.setCheckState(Qt.Unchecked) 
     ILCheckbox.stateChanged.connect(self.ILCheckbox_changed) 
     MainLayout = QGridLayout() 
     MainLayout.addWidget(ILCheckbox, 0, 0, 1, 1) 
     self.setLayout(MainLayout) 

    def ILCheckbox_changed(self, state): 
     self.ILCheck = (state == Qt.Checked) 
     print(self.ILCheck) 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    window = SelectionWindow() 
    window.show() 
    window.ILCheck.value = True 
    sys.exit(app.exec_()) 
+0

감사합니다 !!! 이것은 내가 원하는 것입니다 !!!! – NewPlayerX

0

ILCheck를 호출 한 후 ILCheckbox.setCheckState(Qt.Checked)을 사용하면됩니다.

직접 슬롯을 호출 할 수 있으므로 여기에 신호를 보내지 마십시오.

이 기능을 두 번 이상 사용하려면 self.ILCheck 상태를 변경하고 신호를내는 설정기를 작성하는 것이 좋습니다. 당신의 설명 후

편집 :

  • 당신은 세터 방식을 사용할 수 있지만 대신 ILCheckbox의 값을 설정, 당신은 your_properly_named_anddefine_signal.emit()를 호출해야합니다. 신호 정의에 대한 자세한 내용은 예를 들어를 참조하십시오.http://www.pythoncentral.io/pysidepyqt-tutorial-creating-your-own-signals-and-slots/.
  • 신호를 슬롯에 연결해야 확인란이 올바르게 설정됩니다. 이 연결은 컨트롤러 클래스의 __init__()에서 이루어질 수 있습니다.
+0

도움 주셔서 감사합니다. 나는 분명히 설명하지 못해 죄송합니다. 내 업데이트를 확인하실 수 있습니다 – NewPlayerX

+0

그에 따라 답변을 업데이 트 ... 그게 도움이되기를 바랍니다 ... – OBu

1

property은 할당/액세스시 추가 작업을 수행하는 변수를 정의하는 방법입니다. 아래는 그 목적을 위해 수정 된 코드입니다. ILCheck은 할당시 확인란을 업데이트하는 속성으로 변경됩니다. .setter에 대한 올바른 오류 검사는 생략되었지만 가장 필요할 것입니다. 아바리스로

import sys 

from PyQt4.QtGui import * 
from PyQt4.QtCore import * 

class SelectionWindow(QWidget): 
    def __init__(self, parent=None): 
     super(SelectionWindow, self).__init__(parent) 

     self._ILCheck = False 

     self.ILCheckbox = QCheckBox(self) 
     self.ILCheckbox.setCheckState(Qt.Unchecked) 

     self.ILCheckbox.stateChanged.connect(self.ILCheckbox_changed) 

     MainLayout = QGridLayout() 
     MainLayout.addWidget(self.ILCheckbox, 0, 0, 1, 1) 

     self.setLayout(MainLayout) 

    def ILCheckbox_changed(self, state): 
     self._ILCheck = (state == Qt.Checked) 

     print(self.ILCheck) 

    @property 
    def ILCheck(self): 
     return self._ILCheck 

    @ILCheck.setter 
    def ILCheck(self, value): 
     self._ILCheck = value 
     self.ILCheckbox.setChecked(value) 


if __name__ == '__main__': 
    app = QApplication(sys.argv) 
    window = SelectionWindow() 

    window.show() 
    window.ILCheck = True 
    sys.exit(app.exec_()) 
+0

답장을 보내 주셔서 감사합니다. 당신의 솔루션은 훌륭합니다! 필자가 필요로하는 방식은 Modeling-View 솔루션과 비슷하므로 GUI 파트와 모델링 파트를 분리 할 수 ​​있습니다. 업데이트 할 때 업데이트 모델링이 필요하고 GUI가 어떻게 보이는지주의를 기울일 필요가 없습니다. 이 솔루션을 사용할 수 없도록 뷰 클래스에서이 Bool 속성을 설정할 수 없습니다. – NewPlayerX