最近はアプリを作ってみようと試行錯誤しており、なかなかブログ記事を書くことができませんでした。
しかし、時間をかけて色々やっていると、kivyのGUIのプラグラムを作って、buildozerでAPKまで作れました。
しかし、エミュレーターに入れて動作しようと試みましたが、エミュレータにインストールしても、アプリ作動せず。
これがコードです。
# -*- coding: utf-8 -*-
import os
import random
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path
# フォントのパスを追加します。Pythonスクリプトと同じディレクトリにあるのであれば、”.”を指定します。
resource_add_path(‘.’)
# デフォルトのフォントを日本語対応のものに変更します。ダウンロードしたフォントファイルの名前に変更してください。
LabelBase.register(DEFAULT_FONT, ‘NotoSansJP-Regular.otf’)
# カレントディレクトリをスクリプトの場所にセット
os.chdir(os.path.dirname(os.path.abspath(__file__)))
# フォルダから画像を読み込む
image_extensions = [“.png”, “.jpg”, “.jpeg”, “.gif”]
season_images = {season: [img for img in os.listdir(os.path.join(“.”, season)) if any(img.endswith(ext) for ext in image_extensions)] for season in [“春”, “夏”, “秋”, “冬”]}
# スコアに応じた画像名
score_images = {range(1, 4): “4.png”, range(4, 7): “3.png”, range(7, 10): “2.png”, range(10, 11): “1.png”}
class QuizApp(App):
def build(self):
self.seasons = [‘春’, ‘夏’, ‘秋’, ‘冬’]
self.correct_answer = None
self.current_image = None
self.score = 0
self.questions_asked = 0
self.main_layout = BoxLayout(orientation=”vertical”)
self.image = Image(size_hint=(1, 0.7)) # 画像サイズの変更
self.main_layout.add_widget(self.image)
self.image_label = Label(size_hint=(1, 0.1), font_size=’20sp’) # フォントサイズの変更
self.main_layout.add_widget(self.image_label)
self.result_label = Label(size_hint=(1, 0.1), font_size=’20sp’) # フォントサイズの変更
self.main_layout.add_widget(self.result_label)
self.answer_layout = BoxLayout(orientation=”horizontal”, size_hint_y=0.1)
for season in self.seasons:
button = Button(text=season)
button.bind(on_press=self.check_answer)
self.answer_layout.add_widget(button)
self.main_layout.add_widget(self.answer_layout)
self.next_button = Button(text=”次へ”, size_hint_y=0.1)
self.next_button.bind(on_press=self.next_question)
self.main_layout.add_widget(self.next_button)
self.reset_button = Button(text=”リセット”, size_hint_y=0.1)
self.reset_button.bind(on_press=self.reset)
self.main_layout.add_widget(self.reset_button)
self.next_question()
return self.main_layout
def next_question(self, *args):
if self.questions_asked == 10:
self.image_label.text = f”スコア: {self.score} / 10″
for score_range, image_name in score_images.items():
if self.score in score_range:
self.image.source = os.path.join(“.”, “スコア”, image_name)
break
return
self.result_label.text = “”
while True:
self.correct_answer = random.choice(self.seasons)
if season_images[self.correct_answer]: # リストが空でないことを確認
self.current_image = random.choice(season_images[self.correct_answer])
break
self.image.source = os.path.join(“.”, self.correct_answer, self.current_image)
self.image_label.text = f”{self.current_image.split(‘.’)[0]}” # ファイル名から拡張子を除いた部分を取得
self.questions_asked += 1
def check_answer(self, button):
if button.text == self.correct_answer:
self.result_label.text = “正解!”
self.score += 1
else:
self.result_label.text = f”残念、正解は{self.correct_answer}でした。”
def reset(self, *args):
self.score = 0
self.questions_asked = 0
self.next_question()
if __name__ == “__main__”:
QuizApp().run()
悲しみに暮れながら、Kivy→Androidアプリの流れは一旦断念しました。
buildozerでAPKを作るところまでに結構な時間を要したので、涙目です。
気を取り直して、Javaのコードに直してみたらといいのかと考えmChat GPTに頼んで先ほどのコードを置き換えてみました。
javaで似たようなの作って
先ほどのコードの文末にjavaで似たようなの作って、と添えて入力しました。
簡単にChat GPTは直してくれました。
最終コードはこんな感じ。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Random;
public class QuizApp {
private JFrame frame;
private JLabel imageLabel;
private JLabel titleLabel;
private JLabel resultLabel;
private JButton nextButton;
private JButton resetButton;
private JPanel buttonPanel;
private int score = 0;
private int questionsAsked = 0;
private String correctAnswer;
private String[] seasons = {“春”, “夏”, “秋”, “冬”};
private Random random = new Random();
public QuizApp() {
frame = new JFrame(“Quiz App”);
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
imageLabel = new JLabel();
imageLabel.setHorizontalAlignment(JLabel.CENTER);
titleLabel = new JLabel();
titleLabel.setHorizontalAlignment(JLabel.CENTER);
titleLabel.setFont(new Font(“Arial”, Font.BOLD, 24));
resultLabel = new JLabel();
resultLabel.setHorizontalAlignment(JLabel.CENTER);
resultLabel.setFont(new Font(“Arial”, Font.BOLD, 24));
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(imageLabel, BorderLayout.CENTER);
centerPanel.add(resultLabel, BorderLayout.SOUTH);
frame.add(titleLabel, BorderLayout.NORTH);
frame.add(centerPanel, BorderLayout.CENTER);
buttonPanel = new JPanel();
for (String season : seasons) {
JButton button = new JButton(season);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
checkAnswer(e.getActionCommand());
}
});
buttonPanel.add(button);
}
nextButton = new JButton(“次へ”);
nextButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
nextQuestion();
}
});
buttonPanel.add(nextButton);
resetButton = new JButton(“リセット”);
resetButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
reset();
}
});
buttonPanel.add(resetButton);
frame.add(buttonPanel, BorderLayout.SOUTH);
nextQuestion();
frame.setVisible(true);
}
private void nextQuestion() {
if (questionsAsked == 10) {
displayScoreImage();
return;
}
correctAnswer = seasons[random.nextInt(seasons.length)];
String currentImagePath = getRandomImageFromSeason(correctAnswer);
if (currentImagePath != null) {
File imageFile = new File(currentImagePath);
String imageTitle = imageFile.getName().replace(“.png”, “”);
ImageIcon originalIcon = new ImageIcon(currentImagePath);
Image scaledImage = originalIcon.getImage().getScaledInstance(600, 400, Image.SCALE_SMOOTH);
ImageIcon scaledIcon = new ImageIcon(scaledImage);
imageLabel.setIcon(scaledIcon);
titleLabel.setText(imageTitle);
} else {
imageLabel.setText(“画像が見つかりません”);
}
questionsAsked++;
}
private String getRandomImageFromSeason(String season) {
File folder = new File(“季節/” + season);
FilenameFilter filter = (dir, name) -> name.toLowerCase().endsWith(“.png”) ||name.toLowerCase().endsWith(“.jpg”);
File[] files = folder.listFiles(filter);
if (files != null && files.length > 0) {
return files[random.nextInt(files.length)].getAbsolutePath();
} else {
return null;
}
}
private void checkAnswer(String answer) {
if (answer.equals(correctAnswer)) {
resultLabel.setText(“正解!”);
score++; // ここでスコアをインクリメント
} else {
resultLabel.setText(“残念、正解は” + correctAnswer + “でした。”);
}
}
private void reset() {
score = 0;
questionsAsked = 0;
nextQuestion();
}
private void displayScoreImage() {
String imagePath;
String title;
if (score == 10) {
imagePath = “スコア/1.png”;
title = “満点です!”;
} else if (score >= 7 && score <= 9) {
imagePath = “スコア/2.png”;
title = “非常に良くできました!”;
} else if (score >= 4 && score <= 6) {
imagePath = “スコア/3.png”;
title = “もう一息です!”;
} else {
imagePath = “スコア/4.png”;
title = “もう少し頑張ろう!”;
}
ImageIcon scoreIcon = new ImageIcon(imagePath);
imageLabel.setIcon(scoreIcon);
titleLabel.setText(title);
resultLabel.setText(“あなたのスコア: ” + score + ” / 10″);
}
public static void main(String[] args) {
new QuizApp();
}
出来上がったクイズ
クイズアプリで10問ランダムに出る感じになっています。
四季を答えるクイズになっていて、ミッドジャーニーで画像を作成しています。
ミッドジャーニーを使っているので、画像のレベルはそこそこかなと思います。
ラベンダーで入れただけですが、なぜか女性の絵が出力されています。
なべ、意外と日本文化の画像も結構出力してくれます。
最後は点数に合わせて出る画像が違う表示になっています。
結構いい出来と自画自賛してい他のですが、
しかし、結局Androidアプリを作成するのにjava swingのGUIを作ってもまた移植しなければならないことがわかりました。
また1から出直しです。笑
まとめ
Kivyからjavaの変更はChat GPTに頼めば簡単にやってくれます。
僕自身はコードが書けないので、完全に頼りきっています。
コード知らんくても、頼めば簡単なアプリは作成できます。
Androidアプリを作成するのにjava swingのGUIを作ってもまた移植しなければならないことがわかりました、完全に無知でした笑
一応デスクアップアプリは作成できたのでよしとします。
以上参考になれば幸いです。
コメント