Merhaba, PyQt5 ile tamsayılarla çarpma ve bölme üzerine bir tür arayüz oyunu tasarlamaya çalışıyorum
Süre sayacı için QLCDNumber bağlantısını bir yerden bulduğum kod ile yaptım. oluşturduğum thread içindeki döngü ile 10’dan geriye sorunsuz sayıp döngü bitince istediğim işlemi yapıp thread kayboluyor. Ama ben her soru seçiminden sonra süre sayacını tekrar 10’dan başlatmak istiyorum. Ama görüyorum ki ya döngüyü başa alabilmem ya da döngüyü kırıp var olan thread’i öldürmem gerek ki arkadan gelen yeni thread sorunsuz şekilde sayacı tekrar 10 'dan başlatabilsin ama halihazırda önceki thread’in varlığı sanırsam buna engel oluyor. döngüyü kırıp çıksam da bu kez yine arkdan gelen yeni thread sayacı devralamıyor.
Kodlar şu şekilde
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5 import QtCore, Qt
import time
import threading
from random import randint, choice, shuffle
from PyQt5.QtCore import *
from math import sqrt
from Tam_Sayilarda_Carpma_Bolme_Oyunu_python import Ui_MainWindow
class TamSayiCarpmaBolmeOyunu(QMainWindow):
counter_x = pyqtSignal(int)
counting = False
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.timer = QTimer()
self.ui.setupUi(self)
self.counter_x.connect(self.update_lcd)
self.skor = 0 # Skor başlangıç değeri
self.sayac = 0 # sayaç başlangıç değeri
self.numberOfWrongAnswers = 0 # yanlış cevap sayacı başlangıç değeri
self.generateRandomValues() # Ekrana işlem oluşturup basar.
self.UIComponentSettings()
self.show()
def mainActionBoard(self, optionChoise):
"""
A,B, C butonlarından biri basılıp seçim yapılınca, eğer yapılan seçim işlem sonucu ile aynı ise veya farklı ise
bir takım işlemler yerine getirir.
:param optionChoise:
:return:
"""
self.continueSignal = False
if self.result == optionChoise: # sonuç seçimle aynı ise...
self.skor += 10 # skor 10 arttır
self.ui.label_tepki.setStyleSheet("image: url(:/DogruYanlis/images/DogruYanlis/dogru.png);") # doğru cevap tepki resmi
self.timer.singleShot(2000, self.backEmojiFace) # 2 saniye sonra tekrar emojiye geri dön.
self.counter() # her tur için sayac işlemleri
print(self.sayac, ".soruyu doğru bildiniz. skor:", self.skor)
else:
self.wrongAnswerCounter() # yanlış cevap sayacına bağlan ve bir canı azalt
self.ui.label_tepki.setStyleSheet("image: url(:/DogruYanlis/images/DogruYanlis/yanlis.png);")
self.timer.singleShot(2000, self.backEmojiFace)
self.counter()
print(self.sayac, ".soruyu yanlış yaptınız")
def UIComponentSettings(self):
"""
butonları seçeneklerdeki değer ile birlikte işlem fonksiyonuna bağlar
:return:
"""
self.ui.pushButton_A_secenek.clicked.connect(lambda optionChoise: self.mainActionBoard(optionChoise=int(self.ui.label_secenek_A.text())))
self.ui.pushButton_B_secenek_.clicked.connect(lambda optionChoise: self.mainActionBoard(optionChoise=int(self.ui.label_secenek_B.text())))
self.ui.pushButton_C_secenek.clicked.connect(lambda optionChoise: self.mainActionBoard(optionChoise=int(self.ui.label_secenek_C.text())))
def generateRandomValues(self):
"""
Üretilen rastgele sayılarla tamsayılarla çarpma
veya bölme işlemi oluşturup bunu ekrandaki label'lara basar.Şıkları
beirleyen ayrı bir metoda (self.displayOptions) bağlanır.
:return:None
"""
self.num1 = randint(-10, 11)
self.num2 = randint(-10, 11)
self.kat = randint(1, 7)
self.multiplyDivision = choice(["x", ":"])
if self.multiplyDivision == "x":
self.ui.label_birinciDeger.setText(f"({self.num1})" if self.num1 < 0 else f"{self.num1}")
self.ui.label_CarpmaBolme.setText("x")
self.ui.label_ikinciDeger.setText(f"({self.num2})" if self.num2 < 0 else f"{self.num2}")
self.result = self.num1 * self.num2
self.displayOptions()
else:
while (self.num2 == 0):
self.num2 = randint(-10, 11)
self.num1 = self.num2 * self.kat
self.ui.label_birinciDeger.setText(f"({self.num1})" if self.num1 < 0 else f"{self.num1}")
self.ui.label_CarpmaBolme.setText(":")
self.ui.label_ikinciDeger.setText(f"({self.num2})" if self.num2 < 0 else f"{self.num2}")
self.result = int(self.num1 / self.num2)
self.displayOptions()
self.startCounting() # Tüm işlemlerden sonra sayacı başlatmak için
def update_lcd(self, value): #QLCDNumber için güncelleme
if value == 1:
self.ui.lcdNumber_sureSayaci.display(value)
self.timeEndingMessage() #
else:
self.ui.lcdNumber_sureSayaci.display(value)
def startCounting(self): # QLCDNumber sayacı için thread oluştur ve self.countDown'a bağlan
if not self.counting:
self.counting = True
self.thread_count = threading.Thread(target=self.countDown, daemon=True)
self.thread_count.start()
def countDown(self): # QLCDNumber sayacını 10'dan geriye doğru sayılması
for i in range(10,0,-1):
self.counter_x.emit(int(i))
time.sleep(1)
self.counting = False
def displayOptions(self):
if self.multiplyDivision == "x" and (self.num1 == 0 or self.num2 == 0):
self.wrongOption_1 = self.result + 1
self.wrongOption_2 = self.result + 2
else:
self.wrongOption_1 = self.result * 2
self.wrongOption_2 = self.result * 3
self.options = [self.wrongOption_1, self.wrongOption_2, self.result]
shuffle(self.options)
self.ui.label_secenek_A.setText(str(self.options[0]))
self.ui.label_secenek_B.setText(str(self.options[1]))
self.ui.label_secenek_C.setText(str(self.options[2]))
def counter(self):
"""
Kullanıcı cevabından sonra sayacın arttırılması
ve sayac ile yanlış cevap sayacının durumlarına başlı olarak
oyun turunun nasıl sona erdirileceğinden sorumlu.
:return: None
"""
self.sayac += 1
if self.sayac < 5 and self.numberOfWrongAnswers < 3:
self.generateRandomValues()
elif self.sayac < 5 and self.numberOfWrongAnswers == 3:
self.wrongCounterEndingMessage()
elif self.sayac == 5 and self.numberOfWrongAnswers < 3:
self.counterEndingMessage()
def counterEndingMessage(self):
"""
5 soru sonunda oyunun bitirilmesi durumunda ekranda skoru gösteren
bitirme mesajı
Kullanıcı devam etmek isterse oyunu sıfırlar, aksi takdirde pencereyi kapatır.
:return: None
"""
m_box = QMessageBox.question(self, "SKOR SONUCU",
"Oyun bitti! Skorunuz:" f"{self.skor}/50"
"\nTekrar Oynamak ister misiniz?", QMessageBox.Yes | QMessageBox.No )
if m_box == QMessageBox.Yes:
self.resetUi()
else:
window.close()
def wrongCounterEndingMessage(self):
"""
Kullanıcı geçerli tur içinde 3 yanlış cevap verirse oyunu
tükenen canlar üzerinden bitirir. Skor gösterilmez, kullanıcı başarısız sayılır.
Kullanıcı tekrar oynamak isterse oyunu resetler tekrar başlatır, istemezse kapatır.
:return: none
"""
m_box = QMessageBox.question(self, "OYUNU BİTTİ",
"HİÇ CANINIZ KALMADI :("
"\nTekrar Oynamak ister misiniz?", QMessageBox.Yes | QMessageBox.No)
if m_box == QMessageBox.Yes:
self.resetUi()
else:
window.close()
def timeEndingMessage(self):
m_box = QMessageBox.question(self, "SÜRE BİTTİ!",
"Malesef Süreniz Bitti!"
"\nTekrar Oynamak ister misiniz?", QMessageBox.Yes | QMessageBox.No)
if m_box == QMessageBox.Yes:
self.resetUi()
else:
window.close()
def wrongAnswerCounter(self):
"""
Yanlış cevap verildiğinde yanlış cevap sayacını 1 arttrır ve
3 candan birini siler.
:return: None
"""
self.numberOfWrongAnswers += 1
if self.numberOfWrongAnswers == 1:
self.ui.label_canlar.setStyleSheet("image: url(:/Canlar/images/CanBari/2_kalp.png);")
elif self.numberOfWrongAnswers == 2:
self.ui.label_canlar.setStyleSheet("image: url(:/Canlar/images/CanBari/1_kalp.png);")
elif self.numberOfWrongAnswers == 3:
self.ui.label_canlar.setStyleSheet("image: url(:/Canlar/images/CanBari/0_kalp.png);")
def backEmojiFace(self):
# Tekrar öylece durma tepkisi veren emojiyi çağırır.
self.ui.label_tepki.setStyleSheet("image: url(:/DogruYanlis/images/DogruYanlis/selamYuz.png);")
def resetUi(self):
"""
Oyun turu bittiğinde kullanıcı tekrar oynamak isterse oyun
parametrelerini başlangıç durumuna getirir. Yani oyunu resetler/sıfırlar
ve yeni baştan bir tur başlatır.
:return: None
"""
self.ui.label_canlar.setStyleSheet("image: url(:/Canlar/images/CanBari/3_kalp.png);")
self.skor = 0
self.numberOfWrongAnswers = 0
self.sayac = 0
self.generateRandomValues()
app = QApplication(sys.argv)
window = TamSayiCarpmaBolmeOyunu()
sys.exit(app.exec())
qt designer ile tasarlandı. import dosyalar gerekli olursa paylaşabilirim.
İlginiz ve yardımlarınız için şimdiden teşekürlr