nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

QtのQCombBoxの使い方

作成環境について

Qt Creator 4.3.1で、以下の設定で、プロジェクトを作成しております。以下の設定でクラス名、cppファイル名、hファイル名はすべてデフォルトを使用しています。

  • Qtウィジェットアプリケーション
  • 基底クラスは、QMainWindows
  • フォームを生成する

ComboBoxを設置して、実際に使ってみる

  • mainwindow.uiに、ComboBoxとPushButtonを設置
  • PushButtonを選択して、右クリックして、スロットへ移動を選択して、clicked()を選択

f:id:nprogram:20170803072412p:plain

  • mainwindow.cppにコードを記載します。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    ui->comboBox->addItem("Fox1");
    ui->comboBox->addItem("Fox2");
    ui->comboBox->addItem("Fox3");
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    QString strIndex = QString::number(ui->comboBox->currentIndex());   // This property holds the index of the current item in the combobox.
    
    QMessageBox::information(this, "title", strIndex);
}
  • 最初のComboBoxの値を選択したときに、ボタンを押したときのメッセージ表示

f:id:nprogram:20170803073154p:plain

  • 2番目のComboBoxの値を選択したときに、ボタンを押したときのメッセージ表示

f:id:nprogram:20170803073231p:plain

  • 3番目のComboBoxの値を選択したときに、ボタンを押したときのメッセージ表示

f:id:nprogram:20170803073214p:plain

以下の動画を参考に本記事を記載しました。

www.youtube.com

ComboBoxにおいて、指定した箇所にアイテムを挿入する

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    ui->comboBox->addItem("Fox1");
    ui->comboBox->addItem("Fox2");
    ui->comboBox->addItem("Fox3");

    ui->comboBox->insertItem(1, "homing missile");
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    QString strIndex = QString::number(ui->comboBox->currentIndex());   // This property holds the index of the current item in the combobox.

    QMessageBox::information(this, "title", strIndex);
}

f:id:nprogram:20170803073816p:plain

Qtで、画像をLabelに埋め込む方法

作成環境について

Qt Creator 4.3.1で、以下の設定で、プロジェクトを作成しております。以下の設定でクラス名、cppファイル名、hファイル名はすべてデフォルトを使用しています。

  • Qtウィジェットアプリケーション
  • 基底クラスは、QMainWindows
  • フォームを生成する

Labelに画像を埋め込む

  • mainwindow.uiに、Labelを設置したのみです f:id:nprogram:20170803060843p:plain

  • mainwindow.cppでQPixmpをインクルードしています。

#include <QPixmap>

f:id:nprogram:20170803060949p:plain

表示結果は以下のようになります。

f:id:nprogram:20170803061602p:plain

Labelに埋め込む画像を拡大表示する

以下のように書き換えます。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPixmap>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QPixmap pix("C:/StudyQt/img/login.jpg");
    ui->label->setPixmap(pix.scaled(100, 100));
}

MainWindow::~MainWindow()
{
    delete ui;
}

表示結果は以下のようになりました。

f:id:nprogram:20170803062120p:plain

以下の動画の内容を参考に記載しました。

www.youtube.com

Labelのサイズを考慮して、縦横比を維持しながら、画像を拡大表示する

  • enum Qt::AspectRatioMode
    • Qt::KeepAspectRatio ⇒ サイズは、アスペクト比を維持し、所定の矩形内部できるだけ大きい矩形にスケーリングされます。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPixmap>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QPixmap pix("C:/StudyQt/img/login.jpg");
    int w = ui->label->width();
    int h = ui->label->height();
    ui->label->setPixmap(pix.scaled(w, h, Qt::KeepAspectRatio));
}

MainWindow::~MainWindow()
{
    delete ui;
}

Qt Creator ショートカット

以下の環境で、便利なショートカットを記載します。

便利なショートカット
  • 実行 ⇒ 実行させるときに使用します。ただし、qmakeも一緒にされるわけではないため、注意

    • Ctrl + R
  • ソース/フォームの切り替え ⇒ Qt Designerを使用していると、コードとデザインを交互に見る機会が増えるため、重宝します

    • Shift + F4
  • コメントアウト ⇒ 複数行を選択していれば、複数行まとめて、スラッシュスラッシュでコメントアウトされます。

    • Ctrl + /

Qt5 Designer学習

youtubeのこの動画の説明が非常にわかりやすいです。

英語ですが、動画で丁寧に説明しており、以下が丁寧に説明されています。

以下の動画は、Qt5 Designerを使用した内容となっています。

  • UIの配置方法
  • 編集モード(Edit Mode)とデザインモードの変更方法

www.youtube.com

  • SIGNALとSLOTの設定

www.youtube.com

  • QMessageBoxの使い方の説明

www.youtube.com

  • レイアウトの説明
    • horizontal layout
    • vertical layout
    • form layout
    • grid layout

www.youtube.com

  • スペーサー、スプリッター、バディ、タブの説明

www.youtube.com

  • How to Show Another Window From MainWindow in QT

www.youtube.com

<スタック領域に別画面の情報を持たせる方法>

void MainWindow::on_pushButton_clicked()
{
    Dialog secDialog;
    secDialog.setModal(true);
    secDialog.exec();
}

<ヒープに別画面の情報を持たせる方法> mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "dialog.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    Dialog *secDialog;
};

#endif // MAINWINDOW_H

mainwindow.cpp

void MainWindow::on_pushButton_clicked()
{
      secDialog = new Dialog(this);
      secDialog->show();
}

品質を向上させるために、テストクラスを記載しよう

このように記載すれば、製品のソースコードと、テストクラスのソースコードを分離できます。

#include "box.h"
#include <climits>
#include <cassert>
#include <iostream>

class Test {

public:
        Test() {
            Run();
        }
        static void Run() {
          // 正常ケース
            assert(Test(0,0,0,0));
          // 異常ケース
            assert(Test(2,2,2,100));
          // 例外がスローされるケース
            assert(Test(INT_MAX, INT_MAX, INT_MAX, INT_MAX));
        }
        static bool Test(int x, int y, int z, int r) {
          try {
                //検証したいコードをここに記載する
          } catch (std::exception& ex) {
            return false;
          }
        }
};

static const Test test;

Qt Creator4.3 トラブルバスター

自分がQt Creator4.3を使用する際に直面した問題の対処方法について記録します。

エラー(LNK1158)が発生

<症状> fatal error LNK1158: cannot run ‘rc.exe’が発生する

<解決策> C:\Program Files (x86)\Windows Kits\8.0\bin\x64 の rc.exe と rcdll.dll を C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64 にコピーする

以下のページを参考にさせていただきました。

http://motchy99.blog.fc2.com/blog-entry-97.html

LNK2005が発生

<症状> fatal error LNK2005 * mainwindow.obj:-1: エラー: LNK2005: “class QDataStream & __cdecl operator<<(class QDataStream &,class Person const &)” (??6@YAAEAVQDataStream@@AEAV0@AEBVPerson@@@Z) は既に main.obj で定義されています。

<解決策> * 多重インクルードが発生していることが問題 * 多重インクルードを回避すること

Qt SIGNALとSLOTについて

SIGNALの説明やSLOTの説明は、以下のサイトに記載してあります。 https://blog.qt.io/jp/2010/07/20/create-signals-and-slots-2/

connect 関数

  • connect(sender, SIGNAL(signal), receiver, SLOT(slot) );
    • sender : 信号が発生する部品のアドレスを渡す
    • SIGNAL(signal) : signal に信号とする関数を渡す
    • receiver : 信号を受け取る部品のアドレスを渡す
    • SLOT(slot) : 信号を受け取った際に呼び出す関数を渡す

connect関数の使い方

#include "mainwindow.h"
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QPushButton* button = new QPushButton("Quit");
    QObject::connect(button, SIGNAL( clicked() ),
            &app, SLOT(quit()) );
    button->show();
    return app.exec();
}