I have a next part of code:
main.py
class VerticalGame(Widget):
...
def update(self, dt):
...
if self.player1.score >= 8 or self.player2.score >= 8:
return StartScreen()
class StartScreen(Screen):
vertical_button = ObjectProperty(None)
horizontal_button = ObjectProperty(None)
exit_button = ObjectProperty(None)
name_of_project = ObjectProperty(None)
def remove(self):
self.ids.layout.remove_widget(self.ids.vertical_button)
self.ids.layout.remove_widget(self.ids.horizontal_button)
self.ids.layout.remove_widget(self.ids.exit_button)
self.ids.layout.remove_widget(self.ids.name_of_project)
def start_vertical(self):
game = VerticalGame()
game.serve_ball()
Clock.schedule_interval(game.update, 1.0/60.0)
self.game_id.add_widget(game)
def start_horizontal(self):
game = HorizontalGame()
game.serve_ball()
Clock.schedule_interval(game.update, 1.0/60.0)
self.game_id.add_widget(game)
(Here's full code: https://github.com/Greenboyisyourdream/Ping-pong)
How i can call class StartScreen if construction return StartScreen() doesn't work?
You can use get_screen(name_screen). The same way you would change a label from another screen like here.
Related
I write a simple window, when cursor in QLineEdit and press Enter Key, I want the QGraphicsRectItem, QGraphicsScene, QGraphicsView and QWidget also accept QKeyEvent or MyEvent(customize event).I have no idea to do it,Could someone have good method to do this?
Code Sample
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class MyEvent(QEvent):
Type = QEvent.registerEventType()
def __init__(self):
super().__init__(MyEvent.Type)
self._data = "test"
class Item(QGraphicsRectItem):
def __init__(self):
super().__init__()
self.setRect(0 ,0, 100, 100)
self.setBrush(Qt.red)
self.setFlags(QGraphicsItem.ItemIsFocusable)
def keyPressEvent(self, event: QKeyEvent) -> None:
print("Item KeyPress", event.key())
return super().keyPressEvent(event)
class Scene(QGraphicsScene):
def keyPressEvent(self, event: QKeyEvent) -> None:
print("Scene KeyPress", event.key())
return super().keyPressEvent(event)
class View(QGraphicsView):
def keyPressEvent(self, event: QKeyEvent) -> None:
print("View KeyPress", "do something work here", event.key())
return super().keyPressEvent(event)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
lay = QVBoxLayout()
view = View()
scene = Scene()
scene.addItem(Item())
view.setScene(scene)
lay.addWidget(view)
lay.addWidget(QLineEdit("Cursor In here, post Enter Event to QGraphicsView"))
self.setLayout(lay)
self.show()
self.view = view
def keyPressEvent(self, e: QKeyEvent) -> None:
print("QWidget KeyPress", e.key())
# myEvent = MyEvent()
# QApplication.postEvent(myEvent)
return super().keyPressEvent(e)
app = QApplication([])
m = MainWindow()
app.exec()
How let others item also get the event?
I'm working on Pyside2, python 3.8, windows 10
I have an app that parses a file and show data in QtableView. What I'm trying to implement is a Dialog Window with only one button, the only purpose of this dialog window is to give a minimalistic and simple view to the user, where he can first select the file to be parsed and have a Loading progress barwhile the LoadData() function is runned. The Home Dialog should only be hidden/closed when the parsing is done.
Here's what I've tried so far:
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, file_name,parent=None):
"""
..
__init__ code lines
"""
self.change_val = QtCore.Signal(int)
self.change_val[int].connect(self.set_progress_val)
self.progress = QtWidgets.QProgressDialog('loading...', 'cancel', 0, 100, self)
self.progress.show()
self.LoadData(d.path)
#QtCore.Slot(int)
def set_progress_val(self, val):
self.progress.setValue(val)
def LoadData(self, file_path):
"""
Parsing lines of code
..
self.change_val.emit(30)
..
..
self.change_val.emit(60)
..
..
"""
self.progress.hide()
#Parsing finished -> show the mainWindow
self.show()
class HomeDialog(QtWidgets.QDialog, home_dialog.Ui_Dialog):
def __init__(self, parent=None):
super(HomeDialog, self).__init__(parent)
self.setupUi(self)
self.openB6.clicked.connect(self.get_file_name)
def get_file_name(self):
file_name = QtWidgets.QFileDialog.getOpenFileName(self, 'Open config file',
dir=path.join("/"),
filter="B6 (*.b6)")
if not file_name[0]:
return None
else:
self.path = file_name
self.accept()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setStyle(ProxyStyle())
d = HomeDialog()
if d.exec_():
mainWin = MainWindow(file_name=d.path)
mainWin.show()
sys.exit(app.exec_())
I'm getting the follwoing error on self.change_val[int].connect(self.set_progress_val) line :
'str' object has no attribute 'connect'
The signals are not declared in the class constructor or in the methods but in the static part:
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
change_val = QtCore.Signal(int)
def __init__(self, file_name,parent=None):
"""
..
__init__ code lines
"""
self.change_val[int].connect(self.set_progress_val)
self.progress = QtWidgets.QProgressDialog('loading...', 'cancel', 0, 100, self)
self.progress.show()
self.LoadData(d.path)
The bool is currently updated when I click on and off the checkbox however when I click the button it will always print the default value I define at the start. How can I update a bool that is outside the class, so that when I click the button and call the function, it updates the bool?
Also, how can I call a function like this when clicking the button, that is outside of the class?
Thanks
someBool = False
def someFunction():
print(someBool)
class MyGridLayout(GridLayout):
def __init__(self, **kwargs):
#grid layout constructor
super(MyGridLayout, self).__init__(**kwargs)
#set columns for the layout
self.cols = 2
self.add_widget(Label(text="checkbox"))
self.checkbox= CheckBox(active = False)
self.add_widget(self.checkbox)
#this will bind the label and checkbox
self.checkbox.bind(active = self.checkboxActive)
self.button= Button(text="Button")
self.button.bind(on_press=someFunction)
self.add_widget(self.button)
def checkboxActive(self, checkbox, value):
if value:
someBool = True
else:
someBool = False
class MyApp(App):
def build(self):
return MyGridLayout()
if __name__ == '__main__':
MyApp().run()
If you want to change a value outside a function in python you have to specify its scope. It can be easily done with global variable.
Then for the button you have to pass an anonymous function to kivy on_press method linking it to the function you want. That way the press will trigger the function passed. So we will have to use lambda for this.
Try this code:
someBool = False
def someFunction():
global someBool
print(someBool)
class MyGridLayout(GridLayout):
def __init__(self, **kwargs):
# grid layout constructor
super(MyGridLayout, self).__init__(**kwargs)
# set columns for the layout
self.cols = 2
self.add_widget(Label(text="checkbox"))
self.checkbox = CheckBox(active=False)
self.add_widget(self.checkbox)
# this will bind the label and checkbox
self.checkbox.bind(active=self.checkboxActive)
self.button = Button(text="Button")
self.button.bind(on_press=lambda x: someFunction())
self.add_widget(self.button)
def checkboxActive(self, checkbox, value):
global someBool
if value:
someBool = True
else:
someBool = False
class MyApp(App):
def build(self):
return MyGridLayout()
if __name__ == '__main__':
MyApp().run()
i have a page containing two tabs.i want to add a fadeIn effect when i change the tabs.Is that possible?
import sys
from PyQt4.QtCore import QTimeLine
from PyQt4.QtGui import *
class FaderWidget(QWidget):
def __init__(self, old_widget, new_widget):
QWidget.__init__(self, new_widget)
self.old_pixmap = QPixmap(new_widget.size())
old_widget.render(self.old_pixmap)
self.pixmap_opacity = 1.0
self.timeline = QTimeLine()
self.timeline.valueChanged.connect(self.animate)
self.timeline.finished.connect(self.close)
self.timeline.setDuration(333)
self.timeline.start()
self.resize(new_widget.size())
self.show()
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
painter.setOpacity(self.pixmap_opacity)
painter.drawPixmap(0, 0, self.old_pixmap)
painter.end()
def animate(self, value):
self.pixmap_opacity = 1.0 - value
self.repaint()
class StackedWidget(QStackedWidget):
def __init__(self, parent = None):
QStackedWidget.__init__(self, parent)
def setCurrentIndex(self, index):
self.fader_widget = FaderWidget(self.currentWidget(), self.widget(index))
QStackedWidget.setCurrentIndex(self, index)
def setPage1(self):
self.setCurrentIndex(0)
def setPage2(self):
self.setCurrentIndex(1)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = QWidget()
stack = StackedWidget()
stack.addWidget(QCalendarWidget())
editor = QTextEdit()
editor.setPlainText("Hello world! "*100)
stack.addWidget(editor)
page1Button = QPushButton("Page 1")
page2Button = QPushButton("Page 2")
page1Button.clicked.connect(stack.setPage1)
page2Button.clicked.connect(stack.setPage2)
layout = QGridLayout(window)
layout.addWidget(stack, 0, 0, 1, 2)
layout.addWidget(page1Button, 1, 0)
layout.addWidget(page2Button, 1, 1)
window.show()
sys.exit(app.exec_())
this is code that shows some fade effect but i m getting nothing from it and how it works and how to implement on tabs. it will be really appreciable if someone could help me implement it on tabs as well.
thanks in advance.
With the same logic as the code you show, each widget will be placed inside a QStackedWidget, where one of them will be the widget that will be displayed and the other will be the FaderWidget.
class FaderWidget(QWidget):
def __init__(self, *args, **kwargs):
QWidget.__init__(self, *args, **kwargs)
self.pixmap_opacity = None
self.timeline = QTimeLine(333, self)
self.timeline.valueChanged.connect(self.animate)
self.timeline.finished.connect(self.close)
def start(self, old_widget, new_widget):
self.pixmap_opacity = 1.0
self.old_pixmap = QPixmap(new_widget.size())
old_widget.render(self.old_pixmap)
self.timeline.start()
self.resize(new_widget.size())
self.show()
def paintEvent(self, event):
if self.pixmap_opacity:
QWidget.paintEvent(self, event)
painter = QPainter(self)
painter.setOpacity(self.pixmap_opacity)
painter.drawPixmap(0, 0, self.old_pixmap)
def animate(self, value):
self.pixmap_opacity = 1.0 - value
self.update()
class FaderTabWidget(QTabWidget):
def __init__(self, parent=None):
QTabWidget.__init__(self, parent)
self.currentChanged.connect(self.onCurrentIndex)
self.last = -1
self.current = self.currentIndex()
def onCurrentIndex(self, index):
self.last = self.current
self.current = self.currentIndex()
if self.widget(self.last):
self.widget(self.last).setCurrentIndex(1)
old_widget = self.widget(self.last).widget(0)
current_widget = self.widget(self.current).widget(0)
fade = self.widget(self.current).widget(1)
fade.start(old_widget, current_widget)
def addTab(self, widget, text):
stack = QStackedWidget(self)
stack.addWidget(widget)
fade = FaderWidget(self)
fade.timeline.finished.connect(lambda: stack.setCurrentIndex(0))
stack.addWidget(fade)
stack.setCurrentIndex(0 if self.currentIndex() == -1 else 1)
QTabWidget.addTab(self, stack, text)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = QWidget()
tabWidget = FaderTabWidget()
tabWidget.addTab(QCalendarWidget(), "Tab1")
editor = QTextEdit()
editor.setPlainText("Hello world! " * 100)
tabWidget.addTab(editor, "Tab2")
layout = QVBoxLayout(window)
layout.addWidget(tabWidget)
window.show()
sys.exit(app.exec_())
I am trying to embed a button per row inside a tableview. My botton are drawing correctly but are not reacting to any clicks.. Should I be setting flags for this column? so far I have something like:
if index.column() == 14:
flags |= QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable | Qt.ItemIsEnabled
return flags
And this is the delegate:
class AButton(QtGui.QStyledItemDelegate):
mouse_isPressed = False
def __init__(self, parent = None):
QtGui.QStyledItemDelegate.__init__(self, parent)
def boundingRect(self):
return QtCore.QRectF(0, 0, 40, 40)
def paint(self, painter, option, widget = 0):
opt = QtGui.QStyleOptionButton()
opt.state = ((QtGui.QStyle.State_Sunken if self.mouse_isPressed else QtGui.QStyle.State_Raised) | QtGui.QStyle.State_Enabled)
opt.text = self.text()
opt.icon = self.icon()
opt.rect = option.rect
opt.palette = option.palette
QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_PushButton, opt, painter)
def text(self):
return QtCore.QString("hi")
def icon(self):
return QtGui.QIcon()
def mousePressEvent(self, event):
self.mouse_isPressed = True
print "HELLO"
self.update()
def mouseReleaseEvent(self, event):
self.mouse_isPressed = False
self.update()
Is there any example out there I could look at?
thanks in advance,
Cris
Qt delegates doesn't provide specific events handlers (like mousePressEvent, mouseReleaseEvent, ...) as QWidget does.
If you want to react to user actions you should reimplement the editorEvent method.
By the way, there is no such 'update' method defined in QStyledItemDelegate