如何使用PyQt

时间:2015-04-24 19:27:11

标签: python python-2.7 pyqt pyqt4

我正在开发一些应用。我想创建一个工具栏,单击后将打开“设置”窗口。但是我不知道该怎么做。现在的方式是我有一个工具栏图标连接到 ShowSettings 功能。每次单击图标时,此函数都会创建一个新的设置实例(我知道它不应该每次都创建新实例,而只是在开始时只创建一个实例,然后对其进行处理。我不知道该怎么做)然后显示与此实例关联的设置窗口。但是,通过这种方式,设置窗口仅闪烁一秒钟然后消失。我不知道什么是错的希望你可以帮助我:))

import sys
import time
from PyQt4 import QtCore, QtGui
from ui import Ui_MainWindow
from ui import Ui_SettingsWindow

#Aplikacja obslugujaca bramki LF
#zamiana pliku .ui na kod pythona
#pyuic4 untitled.ui -o output.py
class timerThread(QtCore.QThread):
    timeElapsed = QtCore.pyqtSignal(float)

    def __init__(self, parent=None):
        super(timerThread, self).__init__(parent)
        self.timeStart = None

    def start(self, timeStart):
        self.timeStart = timeStart

        return super(timerThread, self).start()

    def run(self):
        while self.parent().isRunning():
            self.timeElapsed.emit(time.time() - self.timeStart)
            time.sleep(0.1)


class myThread(QtCore.QThread):
    timeElapsed = QtCore.pyqtSignal(float)
    def __init__(self, parent=None):
        super(myThread, self).__init__(parent)

        self.timerThread = timerThread(self)
        self.timerThread.timeElapsed.connect(self.timeElapsed.emit)

    def run(self):
        self.timerThread.start(time.time())

        iterations = 10000000000
        while iterations:
            print "Running {0}".format(self.__class__.__name__)
            iterations -= 1
            time.sleep(10)   

class SettingsWindow(QtGui.QMainWindow):
    #Constructor:
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui_settigns = Ui_SettingsWindow()
        self.ui_settigns.setupUi(self)

class MainWindow(QtGui.QMainWindow):

    #Constructor:
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)


        self.myThread = myThread(self)
        self.myThread.timeElapsed.connect(self.on_myThread_timeElapsed)
        self.myThread.finished.connect(self.on_myThread_finished)

        #Nie wiem jak przerzucic to do pliku UI bez errorow
        #Toolbar
        settingsAction = QtGui.QAction(QtGui.QIcon('tools.jpg'), 'Ustawienia', self)
        settingsAction.setShortcut('Ctrl+U')
        settingsAction.triggered.connect(self.ShowSettings)

        self.toolbar = self.addToolBar('Settings')
        self.toolbar.addAction(settingsAction)

    def UpdateList(self):
        contest_name = self.ui.comboBox.currentText()

        #jakis try-catch tutaj sie przyda gdyby nie plik nie istnial
        #zczytuje z pliku liste robotow
        with open('database\%s.txt' % contest_name) as f:
                robots_list = f.read().splitlines()

        self.ui.listWidget.clear()
        self.ui.listWidget.addItems(robots_list)

    def Search(self):
        text = self.ui.lineEdit.text()
        self.ui.lineEdit.clear() 
        item = self.ui.listWidget.findItems(text, QtCore.Qt.MatchExactly)

        #jakiegos try-catcha trzeba tutaj walnac
        self.ui.listWidget.setItemSelected(item[0], True)

    def ShowSettings(self):
        settings = SettingsWindow() #creates settings instance
        settings.show()

    @QtCore.pyqtSlot()
    def on_button_clicked(self):
        self.myThread.start()

    @QtCore.pyqtSlot(int)
    def on_myThread_timeElapsed(self, seconds):
        self.ui.lcdNumber.display(seconds)

    @QtCore.pyqtSlot()
    def on_myThread_finished(self):
        self.myThread.terminate()
        print "Done"


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = MainWindow()
    settings = SettingsWindow()
    myapp.show()
    settings.show()

    sys.exit(app.exec_())

这是UI文件

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'untitled.ui'
#
# Created: Fri Apr 24 08:04:20 2015
#      by: PyQt4 UI code generator 4.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_SettingsWindow(object):
    def setupUi(self, SettingsWindow):
        SettingsWindow.setObjectName(_fromUtf8("Ustawienia"))
        SettingsWindow.resize(686, 556)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(686, 556)

        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.groupBox = QtGui.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 341, 491))
        self.groupBox.setObjectName(_fromUtf8("groupBox"))
        self.pushButton = QtGui.QPushButton(self.groupBox)
        self.pushButton.setGeometry(QtCore.QRect(10, 460, 231, 23))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.label = QtGui.QLabel(self.groupBox)
        self.label.setGeometry(QtCore.QRect(10, 80, 90, 16))
        self.label.setObjectName(_fromUtf8("label"))
        self.lineEdit = QtGui.QLineEdit(self.groupBox)
        self.lineEdit.setGeometry(QtCore.QRect(130, 77, 191, 20))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.listWidget = QtGui.QListWidget(self.groupBox)
        self.listWidget.setGeometry(QtCore.QRect(10, 110, 321, 341))
        self.listWidget.setObjectName(_fromUtf8("listWidget"))
        item = QtGui.QListWidgetItem()
        self.listWidget.addItem(item)
        item = QtGui.QListWidgetItem()
        self.listWidget.addItem(item)
        item = QtGui.QListWidgetItem()
        self.listWidget.addItem(item)
        self.label_2 = QtGui.QLabel(self.groupBox)
        self.label_2.setGeometry(QtCore.QRect(10, 50, 111, 16))
        self.label_2.setObjectName(_fromUtf8("label_2"))
        self.comboBox = QtGui.QComboBox(self.groupBox)
        self.comboBox.setGeometry(QtCore.QRect(130, 50, 191, 22))
        self.comboBox.setObjectName(_fromUtf8("comboBox"))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.groupBox_2 = QtGui.QGroupBox(self.centralwidget)
        self.groupBox_2.setGeometry(QtCore.QRect(360, 10, 311, 491))
        self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
        self.lcdNumber = QtGui.QLCDNumber(self.groupBox_2)
        self.lcdNumber.setGeometry(QtCore.QRect(10, 20, 281, 151))
        self.lcdNumber.setSmallDecimalPoint(True)
        self.lcdNumber.setObjectName(_fromUtf8("lcdNumber"))
        self.pushButton_2 = QtGui.QPushButton(self.groupBox_2)
        self.pushButton_2.setGeometry(QtCore.QRect(20, 340, 75, 23))
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.pushButton_3 = QtGui.QPushButton(self.groupBox_2)
        self.pushButton_3.setGeometry(QtCore.QRect(200, 340, 75, 23))
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        MainWindow.setCentralWidget(self.centralwidget)


        self.retranslateUi(MainWindow)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.lineEdit.clear)
        QtCore.QObject.connect(self.lineEdit, QtCore.SIGNAL("returnPressed()"), MainWindow.Search) #connected to Search method in class MainWindow
        QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(QString)")), MainWindow.UpdateList)
        QtCore.QObject.connect(self.pushButton_2, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.on_button_clicked)
        QtCore.QObject.connect(self.pushButton_3, QtCore.SIGNAL(_fromUtf8("clicked()")), MainWindow.on_myThread_finished)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "LF Timer", None))
        self.groupBox.setTitle(_translate("MainWindow", "Wybierz robota", None))
        self.pushButton.setText(_translate("MainWindow", "Uruchom Aplikację Pomiaru Czasu", None))
        self.label.setText(_translate("MainWindow", "Wyszukaj robota:", None))
        self.lineEdit.setText(_translate("MainWindow", "cos tam", None))
        __sortingEnabled = self.listWidget.isSortingEnabled()
        self.listWidget.setSortingEnabled(False)
        item = self.listWidget.item(0)
        item.setText(_translate("MainWindow", "Robot 1", None))
        item = self.listWidget.item(1)
        item.setText(_translate("MainWindow", "Robot 2", None))
        item = self.listWidget.item(2)
        item.setText(_translate("MainWindow", "Robot 3", None))
        self.listWidget.setSortingEnabled(__sortingEnabled)
        self.label_2.setText(_translate("MainWindow", "Wybierz Konkurencje:", None))
        self.comboBox.setItemText(0, _translate("MainWindow", "", None))
        self.comboBox.setItemText(1, _translate("MainWindow", "LF", None))
        self.comboBox.setItemText(2, _translate("MainWindow", "TURBO LF", None))
        self.comboBox.setItemText(3, _translate("MainWindow", "LEGO LF", None))
        self.groupBox_2.setTitle(_translate("MainWindow", "Pomiar Czasu", None))
        self.pushButton_2.setText(_translate("MainWindow", "Start", None))
        self.pushButton_3.setText(_translate("MainWindow", "Stop", None))

2 个答案:

答案 0 :(得分:3)

设置窗口的实例是MainWindow.ShowSettings方法的本地实例。因此,它很快被垃圾收集,因为没有任何东西保持对窗口的引用。

您可以通过两种方式解决此问题。第一种是在实例化时指定设置窗口的父级。第二种是将其存储为MainWindow的实例属性(例如self.settings = ...)。

答案 1 :(得分:0)

感谢 three_pineapples 的帮助。我使用了你所描述的第二种方式。它就像一个梦想:)如果有人需要它,这就是代码。

import sys
import time
from PyQt4 import QtCore, QtGui
from ui import Ui_MainWindow
from ui import Ui_SettingsWindow

#Aplikacja obslugujaca bramki LF
#zamiana pliku .ui na kod pythona
#pyuic4 untitled.ui -o output.py

#py to exe
#python setup.py py2exe --includes sip
class timerThread(QtCore.QThread):
    timeElapsed = QtCore.pyqtSignal(float)

    def __init__(self, parent=None):
        super(timerThread, self).__init__(parent)
        self.timeStart = None

    def start(self, timeStart):
        self.timeStart = timeStart

        return super(timerThread, self).start()

    def run(self):
        while self.parent().isRunning():
            self.timeElapsed.emit(time.time() - self.timeStart)
            time.sleep(0.1)


class myThread(QtCore.QThread):
    timeElapsed = QtCore.pyqtSignal(float)
    def __init__(self, parent=None):
        super(myThread, self).__init__(parent)

        self.timerThread = timerThread(self)
        self.timerThread.timeElapsed.connect(self.timeElapsed.emit)

    def run(self):
        self.timerThread.start(time.time())

        iterations = 10000000000
        while iterations:
            print "Running {0}".format(self.__class__.__name__)
            iterations -= 1
            time.sleep(10)   

class SettingsWindow(QtGui.QMainWindow):
    #Constructor:
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui_settigns = Ui_SettingsWindow()
        self.ui_settigns.setupUi(self)

class MainWindow(QtGui.QMainWindow):

    #Constructor:
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.settings = SettingsWindow()# Creates and stores SettingsWindow instance, MainWindow manages SettingsWindow

        self.myThread = myThread(self)
        self.myThread.timeElapsed.connect(self.on_myThread_timeElapsed)
        self.myThread.finished.connect(self.on_myThread_finished)

        #Nie wiem jak przerzucic to do pliku UI bez errorow
        #Toolbar
        settingsAction = QtGui.QAction(QtGui.QIcon('tools.jpg'), 'Ustawienia', self)
        settingsAction.setShortcut('Ctrl+U')
        settingsAction.triggered.connect(self.ShowSettings)

        self.toolbar = self.addToolBar('Settings')
        self.toolbar.addAction(settingsAction)

    def UpdateList(self):
        contest_name = self.ui.comboBox.currentText()

        #jakis try-catch tutaj sie przyda gdyby nie plik nie istnial
        #zczytuje z pliku liste robotow
        with open('database\%s.txt' % contest_name) as f:
                robots_list = f.read().splitlines()

        self.ui.listWidget.clear()
        self.ui.listWidget.addItems(robots_list)

    def Search(self):
        text = self.ui.lineEdit.text()
        self.ui.lineEdit.clear() 
        item = self.ui.listWidget.findItems(text, QtCore.Qt.MatchExactly)

        #jakiegos try-catcha trzeba tutaj walnac
        self.ui.listWidget.setItemSelected(item[0], True)

    def ShowSettings(self):
        self.settings.show()

    @QtCore.pyqtSlot()
    def on_button_clicked(self):
        self.myThread.start()

    @QtCore.pyqtSlot(int)
    def on_myThread_timeElapsed(self, seconds):
        self.ui.lcdNumber.display(seconds)

    @QtCore.pyqtSlot()
    def on_myThread_finished(self):
        self.myThread.terminate()
        print "Done"


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = MainWindow()
    myapp.show()

    sys.exit(app.exec_())