Opening a QDialog and saving last state

2020-04-16 04:33发布

I am trying to open a QDialog from a QMainWindow, and after closing the `QDialog, if I need to open it again, it has to open and show the same information that had when I close it.

Here is the code of the QMainWindow:

class A (QMainWindow):
  def __init__(self):
    QMainWindow.__init__(self)

    #I create a QPushButton to open the QDialog
    self.axes1 = self.figure_canvas.figure.add_axes ([0.8, 0.01, 0.19, 0.05])
    self.button = QPushButton(self.axes1,"Open Dialog")
    self.button.on_clicked(self.OpenDialog)

    #This is the method to open the QDialog which is in another module
  def OpenDialog(self, event):
    text = configurePort.ConfigurePort.retrieve_data(self)
    print text

What this code does is create a button in my QMainWindow and when I click it, it opens a QDialog, which is created in another module. And this is the code of the QDialog:

class ConfigurePort(QDialog):
  def __init__(self, parent = None):
     QDialog.__init__(self, parent)
     uic.loadUi("configurePort.ui", self)

    #I create a button to check active ports and show them
    self.connect(self.btn_checkconn, SIGNAL("clicked()"), self.check_ports)

    #This method calls another class which opens another QDialog
    #and I select the port that I want
  def check_ports(self):
     self.check_serial = CheckPorts(self)
     self.check_serial.exec_()

    #After selecting the port, when I close the QDialog of the class named above
    #the port´s name appears in the first QDialog
  @classmethod
  def retrieve_data(cls, parent = None):
     dlg = cls(parent)
     dlg.exec_()
     text = dlg.getPortText()
     return text

  def closeEvent(self, event):
     #Here is where I need to write the code to close the QDialog 
     #and it does not has to be an event

In the method, closeEvent, I need to write the necessary code, so I can close the window, and using the same button that I use to open it, open it again with the last information that it showed when I closed it.

I have tried to use QSettings but it did not worked (maybe I used it wrong). And I tried the show() and hide() classes of PyQt too, but it did not work. Hope you can help me.

----- EDIT -----

I edited the code of above. and I added some methods for a better understanding. So, i open the QDialog called ConfigurePort and it shows this:

enter image description here

The red circle, surrounds the port´s name. It is shown in a QLabel,and I take this text from the QDialog and then print it when I close the QDialog. I acomplish this thanks to a question I asked before, wich is in this link:

Getting data from child using PyQt

The check_port method shown in the code above, opens another QDialog that works great. With this I can select the ports that I need in my pc. So, this does not matter.

So, after closing the QDialog(and selecting for example "COM3", as you can see in the picture), I need to open it again, and see the same information that was shown before I closed it.

I tried to add this lines, using QSettings :

self.settings = QSettings("MyCompany", "MyApp")
  if not self.settings.value("windowsState") == None:
    self.restoreState(self.settings.value("windowState"))

But as I said before, I think that I did not use it right, but I hope that I solve this using something simpler.

----- EDIT 2 -----

Thank to the help of @Brendan Abel I have this code:

class ConfigurePort(QDialog):
  def __init__(self, parent):
    super(ConfigurePort, self).__init__(parent)
    uic.loadUi("configurePort.ui", self)

    self.myValue = 10
    self.restoreSettings()

    self.connect(self.btn_checkconn, SIGNAL("clicked()"), self.check_ports)
    self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(self.close)
    self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.closeEvent)

    self.iniUi()

  def check_ports(self):
    pass

  def iniUi(self):
    pass #I just create some QLabels in here

  @classmethod
  def retrieve_data(cls, parent = None):
    dlg = cls(parent)
    dlg.exec_()
    text = dlg.getPortText()
    return text

  def closeEvent(self, event):
    self.saveSettings()
    super(QDialog,self).closeEvent(event)

  def saveSettings(self):
    settings = QSettings("MyOrg", "MyApp")
    settings.setValue("myValue", self.myValue)

  def restoreSettings(self):
    settings = QSettings("MyOrg", "MyApp")
    self.myValue = settings.value("myValue", self.myValue)

This gives me this error: TypeError: QWidget.closeEvent(QCloseEvent): argument 1 has unexpected type 'bool' I know that I am missing something, but I can not see it.

2条回答
聊天终结者
2楼-- · 2020-04-16 05:02

There are a couple ways you could persist this data Generally, to persist data across sessions, you use QSettings and load the data in the __init__ and save it in the closeEvent method

Generally it looks something like this. This also assumes your using the v2 version of the QVariant api; otherwise, the results returned from QSettings.value is going to be a QVariant and you'll need to cast it to the appropriate python type. If you're using a recent version of PyQt then you should be on v2, but if not you can force it by sticking this at the top of your file

import sip
sip.setapi('QVariant', 2)
sip.setapi('QString', 2)


class MyDialog(QDialog):

    def __init__(self, parent):
        super(MyDialog, self).__init__(parent)
        self.myvalue = 10
        self.restoreSettings()

    def closeEvent(self, event):
        self.saveSettings()
        super(MyDialog, self).closeEvent(event)

    def saveSettings(self):
        settings = QSettings('myorg', 'myapp')
        settings.setValue('myvalue', self.myvalue)

    def restoreSettings(self):
        settings = QSettings('myorg', 'myapp')
        self.myvalue = settings.value('myvalue', self.myvalue)

EDIT:

The error in your code is caused by this:

self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.closeEvent)

You shouldn't be calling or connecting to closeEvent directly. Instead, you should connect to .close or .accept

self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.accept)
查看更多
Melony?
3楼-- · 2020-04-16 05:28

You need to instantiate the ConfigurePort class then the self.configurePortDialog object should keep consistent. You will need to make sure if you have the user enter data that a cancel does not store the data and that an "ok" stores the data, but I not sure what you are putting in your dialog.

class A (QMainWindow):
  def __init__(self):
    QMainWindow.__init__(self)

    #I create a QPushButton to open the QDialog
    self.button = QPushButton("Open Dialog")
    self.button.on_clicked(self.OpenDialog)
    self.configurePortDialog = configurePort.ConfigurePort(parent=self)
    self.configurePortDialog.accepted.connect(self.get_data)

    #This is the method to open the QDialog which is in another module
  def OpenDialog(self, event):
     self.configurePortDialog.show()

  @QtCore.Slot()
  def get_data(self)
    text = self.configurePortDialog.retrieve_data()
    print text
查看更多
登录 后发表回答