您好,我是python的新手(直到第3课和MIT 6001计算机科学与编程入门
在Python中),我仍然开始使用PyQt5和Designer(在Linux上为Python3,PyQt5)玩。
我读了一些有关PyQt5的内容,但是对面向对象编程和Qt的了解不多
文档也像克林贡一样。无法弄清楚为什么此脚本test.py无法打开第二个
窗口,实际上它确实打开了它,我可以在第一个窗口前短暂看到它消失了
当我按下退出按钮时?有什么帮助吗?以及任何容易找到
逻辑的资源Qt的不同类和app循环像我这样的未受过教育的人。
test.py
!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 8 14:25:12 2020
@author: Pietro
"""
import sys
from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QDesktopWidget
def main():
class quitto(QtWidgets.QMainWindow):
def __init__(self):
super(quitto, self).__init__()
uic.loadUi('exitmain.ui', self)
self.center()
self.show()
print('inside quitting2 ' *5)
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
class menu(QtWidgets.QMainWindow):
def __init__(self):
super(menu, self).__init__()
uic.loadUi('main.ui', self)
self.ButtonQ.clicked.connect(self.QPushButtonQPressed)
self.center()
self.show()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def QPushButtonQPressed(self):
#This is executed when the button is pressed
print('buttonB pressed' *5)
pippo=quitto()
pippo.show()
app = QtWidgets.QApplication(sys.argv)
window=menu()
app.exec_()
if __name__ == '__main__':
和main.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>520</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="windowIcon">
<iconset resource="resource001.qrc">
<normaloff>:/main/python.png</normaloff>
<normalon>:/main/python.png</normalon>
<disabledoff>:/main/python.png</disabledoff>
<disabledon>:/main/python.png</disabledon>
<activeoff>:/main/python.png</activeoff>
<activeon>:/main/python.png</activeon>
<selectedoff>:/main/python.png</selectedoff>
<selectedon>:/main/python.png</selectedon>:/main/python.png</iconset>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
background-color: #9de650;
}
QPushButton:hover{
background-color: green;
}
QPushButton#ButtonQ{
background-color: orange;
}
QPushButton#ButtonQ:hover{
background-color: red;
}</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>20</x>
<y>0</y>
<width>471</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
<underline>true</underline>
</font>
</property>
<property name="text">
<string>House-Buying-Menu</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPushButton" name="ButtonA">
<property name="geometry">
<rect>
<x>170</x>
<y>100</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>A</string>
</property>
</widget>
<widget class="QPushButton" name="ButtonB">
<property name="geometry">
<rect>
<x>170</x>
<y>210</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>B</string>
</property>
</widget>
<widget class="QPushButton" name="ButtonC">
<property name="geometry">
<rect>
<x>170</x>
<y>320</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>C</string>
</property>
</widget>
<widget class="QPushButton" name="ButtonQ">
<property name="geometry">
<rect>
<x>170</x>
<y>450</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>QUIT</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>520</width>
<height>29</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources>
<include location="resource001.qrc"/>
</resources>
<connections/>
</ui>
和mainexit.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>631</width>
<height>496</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>200</x>
<y>310</y>
<width>174</width>
<height>33</height>
</rect>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>631</width>
<height>29</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
答案 0 :(得分:1)
该行为的原因是您正在创建的quitto
实例是“垃圾收集”。像许多高级语言一样,Python具有一个自动管理内存的系统,并负责释放它“认为”不再有用的对象的内存。
在函数中创建的任何局部变量总是会在函数返回后立即删除,除非以某种方式引用了持久对象。
以下示例以一种更简单的方式对其进行了解释:在function
中创建了“ my_variable”,但是一旦完成(返回),python就会删除该变量,这很好,因为如果不这样做, t您将很容易耗尽内存:
class DeletingObject(object):
'''
A basic class that prints a message whenever any of its instances
is going to be deleted.
'''
def __del__(self):
print('Goodbye cruel world...')
def function():
my_variable = DeletingObject()
print(my_variable)
>>> function()
<__main__.DeletingObject object at 0xb593a46c>
Goodbye cruel world...
在您的情况下,也会发生同样的事情:您创建了quitto
,但没有持久引用,因此创建它的函数返回后,就会将其删除。
在类中创建对象时,最避免这种情况的方法是将新对象设置为 instance属性:
def QPushButtonQPressed(self):
self.pippo = quitto()
self.pippo.show()
现在不再删除新对象,并且不再破坏窗口。
由于您刚刚开始研究所有这些内容,因此我想分享一些有关您的示例的建议:
from PyQt5 import QtWidgets
)或您将要使用的单个类,就像您在第二次导入(from PyQt5.QtWidgets import QDesktopWidget
)中所做的一样;第二种方法通常适用于简单的情况,但是如果代码增长很多,您可能会发现自己需要手动导入数十个类,并且尽管可以执行from PyQt5.QtWidgets import *
,但通常最好导入子模块,从那里访问课程:from PyQt5 import QtWidgets
# ...
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
答案 1 :(得分:0)
@musicamante感谢您冗长而详细的帖子(我投了赞成票,但不算对不起),不确定我是否必须就下一个问题发表另一篇文章,但与上面的问题有关。我一直试图使我的脚本正常工作,但最终得到了:
test2.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 8 14:25:12 2020
@author: Pietro
"""
import sys
from PyQt5 import QtWidgets, uic
#import resource
def main():
class Quitto(QtWidgets.QDialog):
def quitbuttonboxquit(self):
print('system exit')
app.quit()
def quitbuttonboxnonquit(self):
print('return to main')
window.show()
self.close()
def __init__(self):
super(Quitto, self).__init__()
uic.loadUi('exitdialog2.ui', self)
self.center()
self.show()
print('inside quitting2 ' *5)
self.QuitbuttonBox.accepted.connect(self.quitbuttonboxquit)
self.QuitbuttonBox.rejected.connect(self.quitbuttonboxnonquit)
def center(self):
qr = self.frameGeometry()
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def closeEvent(self, event):
event.ignore()
class Menu(QtWidgets.QMainWindow):
def __init__(self):
super(Menu, self).__init__()
uic.loadUi('main.ui', self)
self.ButtonQ.clicked.connect(self.qpushbuttonqpressed)
self.center()
self.show()
def center(self):
qr = self.frameGeometry()
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def qpushbuttonqpressed(self): #This is executed when the button is pressed
print('buttonB pressed' *5)
window.hide()
pippo=Quitto()
pippo.exec_()
def closeEvent(self, event): #Your desired functionality here
event.ignore()
app = QtWidgets.QApplication(sys.argv)
sshFile="coffee.qss"
with open(sshFile,"r") as fh:
app.setStyleSheet(fh.read())
window=Menu()
app.exec_()
if __name__ == '__main__':
main()
和exitdialog.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>586</width>
<height>522</height>
</rect>
</property>
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<widget class="QDialogButtonBox" name="QuitbuttonBox">
<property name="geometry">
<rect>
<x>40</x>
<y>460</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
background-color: #17eb3e;
}
QPushButton:hover{
background-color: red;
}
</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>50</x>
<y>30</y>
<width>491</width>
<height>341</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">image: url(:/main/alert.png);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>170</x>
<y>400</y>
<width>271</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>75</weight>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QLabel {
color : red
}</string>
</property>
<property name="text">
<string>Are you sure to Quit ?!?</string>
</property>
</widget>
</widget>
<resources>
<include location="resource001.qrc"/>
</resources>
<connections>
<connection>
<sender>QuitbuttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>QuitbuttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
稍后,我将尝试拆分函数和类(首先我需要弄清楚类) 尽管如此,我还是将类Quitto更改为:
class Quitto(QtWidgets.QDialog)
并更改:
def qpushbuttonqpressed(self): #This is executed when the button is pressed
print('buttonB pressed' *5)
window.hide()
pippo=Quitto()
pippo.exec_()
在上一个脚本中使用:
-window.hide()在短暂显示两个窗口后关闭了所有程序
使用
时-pippo.exec()而不是pippo.show()在
顶部显示了新的第二个窗口其他,关闭它们后,我得到了:
AttributeError: 'quitto' object has no attribute 'exec_'
在第二个脚本中使用pippo.show()都不起作用,但是pippo.exe_()起作用了
把戏。它如何绕过垃圾收集???
为什么将类Quitto()更改为QtWidgets.QMainWindow却出现属性错误?
答案 2 :(得分:0)
在我的项目中,我使用它从主窗口打开另一个窗口。我粘贴了具有额外中心功能的全功能脚本,该脚本将主窗口置于屏幕中间。在Designer中,创建两个文件“ UIMain.ui”(主窗口)和第二个窗口“ notes.ui”并保存。
# Open Second Window/Dialog/Form from Main Window
from PyQt5 import uic
from PyQt5.QtWidgets import (
QMainWindow,
QApplication,
QDesktopWidget
)
form_2, base_2 = uic.loadUiType('notes.ui')
class MainNotes(base_2, form_2):
def __init__(self, parent=None):
super(base_2, self).__init__(parent)
self.setupUi(self)
class MainApp(QMainWindow):
""" Main Class
"""
def __init__(self):
super(MainApp, self).__init__()
self.mainnotes = MainNotes()
self.ui = uic.loadUi('UIMain.ui', self)
self.initapp()
def initapp(self):
self.ui.bt_notes.clicked.connect(self.notes)
def notes(self):
"""
Put your code here
"""
self.mainnotes.show()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def main():
import sys
try:
myapp = QApplication([])
mywindow = MainApp()
mywindow.center()
mywindow.show()
myapp.exec_()
except SystemExit:
sys.exit(0)
if __name__ == '__main__':
main()