Qt メモ2019年8月16日 | |
はじめにGUI ライブラリ Qt のメモ。 環境
Qt を用いたプログラムのコンパイルプロジェクトのディレクトリを用意し、その中にソースコードを置く。 $ mkdir window $ mv window.cxx window $ cd window qmake を実行。 $ qmake -project プロジェクトファイル window.pro ができる。 window.pro TEMPLATE = app TARGET = window INCLUDEPATH += . # Input SOURCES += window.cxx 以下の内容を追記。 QT += widgets CONFIG += c++11 1 行目は Qt のウィジットを使うためのモジュールを追加している。2 行目は C++11 を使うための設定である。 オプションなしで qmake を実行。 $ qmake Makefile ができる。make でコンパイル。 $ make ウインドウウインドウを表示するプログラム。 window.cxx #include <QtWidgets> class Main : public QMainWindow { public: Main(void) { setWindowTitle("window"); resize(320, 240); centerOnScreen(); show(); } void centerOnScreen() { auto res = QDesktopWidget().screenGeometry(); move((res.width()/2.) - (frameSize().width()/2.), (res.height()/2.) - (frameSize().height()/2.)); } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() マウスmouse.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QMainWindow { public: Main() { setMouseTracking(true); setWindowTitle("mouse"); resize(320, 240); show(); } void mouseButtonKind(Qt::MouseButtons buttons) { if(buttons & Qt::LeftButton){ cout << "LEFT" << endl; } if(buttons & Qt::MidButton){ cout << "MIDDLE" << endl; } if(buttons & Qt::RightButton){ cout << "RIGHT" << endl; } } void mousePressEvent(QMouseEvent *e) override { cout << "BUTTON PRESS" << endl; mouseButtonKind(e->buttons()); } void mouseReleaseEvent(QMouseEvent *e) override { cout << "BUTTON RELEASE" << endl; mouseButtonKind(e->buttons()); } void wheelEvent(QWheelEvent *e) override { cout << "wheel" << endl; cout << "(" << e->angleDelta().x() << " " << e->angleDelta().y() << ")" << endl; } void mouseMoveEvent(QMouseEvent *e) override { cout << "(" << e->x() << " " << e->y() << ")" << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() キー入力key.cxx #include <iostream> #include <algorithm> #include <QtWidgets> using namespace std; class Main : public QMainWindow { public: Main() { setWindowTitle("key"); resize(320, 240); show(); } bool isPrintable(Qt::Key key) { auto printable = { Qt::Key_Space, Qt::Key_Exclam, Qt::Key_QuoteDbl, Qt::Key_NumberSign, Qt::Key_Dollar, Qt::Key_Percent, Qt::Key_Ampersand, Qt::Key_Apostrophe, Qt::Key_ParenLeft, Qt::Key_ParenRight, Qt::Key_Asterisk, Qt::Key_Plus, Qt::Key_Comma, Qt::Key_Minus, Qt::Key_Period, Qt::Key_Slash, Qt::Key_0, Qt::Key_1, Qt::Key_2, Qt::Key_3, Qt::Key_4, Qt::Key_5, Qt::Key_6, Qt::Key_7, Qt::Key_8, Qt::Key_9, Qt::Key_Colon, Qt::Key_Semicolon, Qt::Key_Less, Qt::Key_Equal, Qt::Key_Greater, Qt::Key_Question, Qt::Key_At, Qt::Key_A, Qt::Key_B, Qt::Key_C, Qt::Key_D, Qt::Key_E, Qt::Key_F, Qt::Key_G, Qt::Key_H, Qt::Key_I, Qt::Key_J, Qt::Key_K, Qt::Key_L, Qt::Key_M, Qt::Key_N, Qt::Key_O, Qt::Key_P, Qt::Key_Q, Qt::Key_R, Qt::Key_S, Qt::Key_T, Qt::Key_U, Qt::Key_V, Qt::Key_W, Qt::Key_X, Qt::Key_Y, Qt::Key_Z, Qt::Key_BracketLeft, Qt::Key_Backslash, Qt::Key_BracketRight, Qt::Key_AsciiCircum, Qt::Key_Underscore, Qt::Key_QuoteLeft, Qt::Key_BraceLeft, Qt::Key_Bar, Qt::Key_BraceRight, Qt::Key_AsciiTilde, }; auto ib = printable.begin(); auto ie = printable.end(); if(::find(ib, ie, key) != ie){ return true; }else{ return false; } } void keyPressEvent(QKeyEvent *e) override { auto control = false; if(e->modifiers() & Qt::ControlModifier){ cout << "Control" << endl; control = true; } if(e->modifiers() & Qt::ShiftModifier){ cout << "Shift" << endl; } if(e->modifiers() & Qt::AltModifier){ cout << "Alt" << endl; } if(e->key() == Qt::Key_Delete){ cout << "Delete" << endl; }else if(e->key() == Qt::Key_Backspace){ cout << "Backspace" << endl; }else if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter){ cout << "Enter" << endl; }else if(e->key() == Qt::Key_Escape){ cout << "Escape" << endl; }else if(e->key() == Qt::Key_Right){ cout << "Right" << endl; }else if(e->key() == Qt::Key_Left){ cout << "Left" << endl; }else if(e->key() == Qt::Key_Up){ cout << "Up" << endl; }else if(e->key() == Qt::Key_Down){ cout << "Down" << endl; } if(!control && isPrintable((Qt::Key)e->key())){ cout << qPrintable(e->text()) << endl; } } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() メニューmenu.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QMainWindow { public: Main() { auto exitAction = new QAction("&Exit", this); exitAction->setShortcut(tr("Ctrl+Q")); connect(exitAction, &QAction::triggered, this, qApp->quit); auto doAction = new QAction("&Do", this); connect(doAction, &QAction::triggered, this, &Main::doSubmenu); auto menubar = menuBar(); auto fileMenu = menubar->addMenu("&File"); auto subMenu = fileMenu->addMenu("&Sub"); subMenu->addAction(doAction); fileMenu->addSeparator(); fileMenu->addAction(exitAction); setWindowTitle("menu"); show(); } void doSubmenu() { cout << "Do" << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() ポップアップメニューpopup.cxx #include <QtWidgets> class Main : public QMainWindow { public: Main() { setWindowTitle("popup"); resize(320, 240); show(); } void contextMenuEvent(QContextMenuEvent *e) override { QMenu menu(this); auto aQuit = menu.addAction("Quit"); auto action = menu.exec(e->globalPos()); if(action == aQuit){ qApp->quit(); } } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() ファイルの選択#include <iostream> #include <QtWidgets> using namespace std; class Main : public QMainWindow { public: Main() { auto exitAction = new QAction("&Exit", this); exitAction->setShortcut(tr("Ctrl+Q")); connect(exitAction, &QAction::triggered, this, qApp->quit); auto openAction = new QAction("&Open", this); openAction->setShortcut(tr("Ctrl+O")); connect(openAction, &QAction::triggered, this, &Main::open); auto saveAction = new QAction("&Save", this); saveAction->setShortcut(tr("Ctrl+S")); connect(saveAction, &QAction::triggered, this, &Main::save); auto menubar = menuBar(); auto fileMenu = menubar->addMenu("&File"); fileMenu->addAction(openAction); fileMenu->addAction(saveAction); fileMenu->addSeparator(); fileMenu->addAction(exitAction); setWindowTitle("file select"); show(); } void open() { auto filename = QFileDialog::getOpenFileName(this, "Open File", nullptr, "C++ Files (*.cxx)"); if(filename != ""){ cout << qPrintable(filename) << endl; } // auto path = QFileDialog::getExistingDirectory(this, "Open Directory", // "", QFileDialog::DontUseNativeDialog); // if(path != ""){ // cout << qPrintable(path) << endl; // } } void save() { // auto filename = QFileDialog::getSaveFileName(this, "Save File", // nullptr, "C++ Files (*.cxx)"); // if(filename != ""){ // cout << qPrintable(filename) << endl; // } QFileDialog dialog(this); dialog.setWindowTitle("Save File"); dialog.setNameFilters({"C++ Files (*.cxx)", "All Files (*)"}); if(dialog.exec()){ auto filenames = dialog.selectedFiles(); cout << qPrintable(filenames[0]) << endl; } } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() ツールバーtool_bar.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QMainWindow { public: Main() { auto toolbar = addToolBar(""); auto aButtonIcon = new QAction( style()->standardIcon(QStyle::SP_DirOpenIcon), "button", this); //aButtonIcon->setCheckable(true); connect(aButtonIcon, &QAction::triggered, this, &Main::buttonIconPress); toolbar->addAction(aButtonIcon); setWindowTitle("tool bar"); resize(320, 240); show(); } void buttonIconPress(bool active) { if(active){ cout << "Active: TRUE" << endl; }else{ cout << "Active: FALSE" << endl; } } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() ボタンbutton.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { public: Main() { auto button = new QPushButton("Button"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(button); setLayout(layout); setWindowTitle("button"); show(); } void buttonClicked() { auto obj = (QPushButton *)sender(); cout << qPrintable(obj->text()) << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() メッセージボックスmessage_box.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { public: Main() { auto button = new QPushButton("Show message box"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(button); setLayout(layout); setWindowTitle("message box"); show(); } void buttonClicked() { auto reply = QMessageBox::question(this, "Message", "Yes/No?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if(reply == QMessageBox::Yes){ cout << "Yes" << endl; }else{ cout << "No" << endl; } } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() チェックボックスcheck_box.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { private: QCheckBox *check1; QCheckBox *check2; public: Main() { check1 = new QCheckBox("Check1"); check2 = new QCheckBox("Check2"); check1->setChecked(true); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(check1); layout->addWidget(check2); layout->addWidget(button); setLayout(layout); setWindowTitle("check box"); show(); } void buttonClicked() { cout << "Check1: " << check1->isChecked() << endl; cout << "Check2: " << check2->isChecked() << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() ラジオボタンradio_button.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { private: QButtonGroup *group; public: Main() { auto radio1 = new QRadioButton("Radio1"); auto radio2 = new QRadioButton("Radio2"); group = new QButtonGroup(); group->addButton(radio1, 1); group->addButton(radio2, 2); radio1->toggle(); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(radio1); layout->addWidget(radio2); layout->addWidget(button); setLayout(layout); setWindowTitle("radio button"); show(); } void buttonClicked() { cout << "Radio: " << group->checkedId() << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() コンボボックスcombo_box.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { private: QComboBox *combo; public: Main() { auto label = new QLabel("Select"); combo = new QComboBox(this); combo->addItem("apple"); combo->addItem("banana"); combo->addItem("lemon"); combo->addItem("orange"); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(label); layout->addWidget(combo); layout->addWidget(button); setLayout(layout); setWindowTitle("combo box"); show(); } void buttonClicked() { cout << "Combo: " << combo->currentIndex() << " " << qPrintable(combo->currentText()) << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() 入力input.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { private: QLineEdit *edit; public: Main() { auto label = new QLabel("Input"); edit = new QLineEdit(); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(label); layout->addWidget(edit); layout->addWidget(button); setLayout(layout); setWindowTitle("input"); show(); } void buttonClicked() { cout << qPrintable(edit->text()) << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() テキスト#include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { private: QTextEdit *text; public: Main() { text = new QTextEdit(); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(text); layout->addWidget(button); setLayout(layout); setWindowTitle("text"); show(); } void buttonClicked() { cout << qPrintable(text->toPlainText()) << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() テーブルtable.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { private: QTableWidget *table; public: Main() { table = new QTableWidget(2, 3); QStringList header = {"A", "B", "C"}; QStringList data[3] = {{"apple", "1", "100"}, {"banana", "2", "200"}}; table->setHorizontalHeaderLabels(header); for(int i = 0; i < data->size(); i++){ for(int j = 0; j < data[i].size(); j++){ table->setItem(i, j, new QTableWidgetItem(data[i][j])); } } auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(table); layout->addWidget(button); setLayout(layout); setWindowTitle("table"); show(); } void buttonClicked() { for(int i = 0; i < table->rowCount(); i++){ for(int j = 0; j < table->columnCount(); j++){ cout << qPrintable(table->item(i, j)->text()) << " "; } cout << endl; } } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() リストlist.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { private: QListWidget *listWidget; public: Main() { listWidget = new QListWidget(); listWidget->addItem("apple"); listWidget->addItem("banana"); listWidget->addItem("lemon"); listWidget->addItem("orange"); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(listWidget); layout->addWidget(button); setLayout(layout); setWindowTitle("list"); show(); } void buttonClicked() { for(int i = 0; i < listWidget->count(); i++){ cout << qPrintable(listWidget->item(i)->text()) << endl; } } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() ツリーtree.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { private: QTreeWidget *treeWidget; public: Main() { treeWidget = new QTreeWidget(); treeWidget->setAlternatingRowColors(true); auto branch1 = new QTreeWidgetItem(); branch1->setText(0, "branch1"); auto branch2 = new QTreeWidgetItem(); branch2->setText(0, "branch2"); addItem(branch1, "apple", 1, 100); addItem(branch1, "banana", 2, 100); addItem(branch2, "lemon", 3, 100); addItem(branch2, "orange", 4, 100); treeWidget->addTopLevelItem(branch1); treeWidget->addTopLevelItem(branch2); treeWidget->setColumnCount(3); treeWidget->setHeaderLabels({"A", "B", "C"}); branch1->setExpanded(true); branch2->setExpanded(true); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(treeWidget); layout->addWidget(button); setLayout(layout); setWindowTitle("tree"); show(); } void addItem(QTreeWidgetItem *branch, string name, int num, int num2) { auto item = new QTreeWidgetItem(branch); item->setFlags(item->flags() | Qt::ItemIsEditable); item->setText(0, QString::fromStdString(name)); item->setText(1, QString::number(num)); item->setText(2, QString::number(num2)); } void buttonClicked() { for(int i = 0; i < treeWidget->topLevelItemCount(); i++){ auto branch = treeWidget->topLevelItem(i); cout << qPrintable(branch->text(0)) << endl; for(int j = 0; j < branch->childCount(); j++){ auto item = branch->child(j); cout << " "; for(int k = 0; k < item->columnCount(); k++){ cout << qPrintable(item->text(k)) << " "; } cout << endl; } } cout << "find: lemon" << endl; auto items = treeWidget->findItems("lemon", Qt::MatchRecursive); auto item = items[0]; cout << " "; for(int k = 0; k < item->columnCount(); k++){ cout << qPrintable(item->text(k)) << " "; } cout << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() チェックボックス付きツリーcheck_tree.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { private: QTreeWidget *treeWidget; public: Main() { treeWidget = new QTreeWidget(); treeWidget->setAlternatingRowColors(true); treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); connect(treeWidget, &QTreeWidget::customContextMenuRequested, this, &Main::contextMenu); auto branch1 = new QTreeWidgetItem(); branch1->setData(0, Qt::CheckStateRole, Qt::Checked); branch1->setText(0, "branch1"); auto branch2 = new QTreeWidgetItem(); branch2->setData(0, Qt::CheckStateRole, Qt::Checked); branch2->setText(0, "branch2"); addItem(branch1, "apple", 1, 100); addItem(branch1, "banana", 2, 100); addItem(branch2, "lemon", 3, 100); addItem(branch2, "orange", 4, 100); treeWidget->addTopLevelItem(branch1); treeWidget->addTopLevelItem(branch2); treeWidget->setColumnCount(3); treeWidget->setHeaderLabels({"A", "B", "C"}); connect(treeWidget, &QTreeWidget::itemClicked, this, &Main::selectItem); connect(treeWidget, &QTreeWidget::itemChanged, this, &Main::changedItem); branch1->setExpanded(true); branch2->setExpanded(true); auto layout = new QVBoxLayout(); layout->addWidget(treeWidget); setLayout(layout); setWindowTitle("check tree"); show(); } void addItem(QTreeWidgetItem *branch, string name, int num, int num2) { auto item = new QTreeWidgetItem(branch); item->setData(0, Qt::CheckStateRole, Qt::Checked); item->setText(0, QString::fromStdString(name)); item->setText(1, QString::number(num)); item->setText(2, QString::number(num2)); } void selectItem() { if(treeWidget->selectedItems().size() == 0){ return; } auto item = treeWidget->selectedItems()[0]; cout << qPrintable(item->text(0)) << endl; } void changedItem(QTreeWidgetItem *item) { if(item->childCount() > 0){ checkBranch(item, item->checkState(0)); } for(int i = 0; i < treeWidget->topLevelItemCount(); i++){ auto branch = treeWidget->topLevelItem(i); cout << qPrintable(branch->text(0)); for(int j = 0; j < branch->childCount(); j++){ auto item = branch->child(j); if(item->checkState(0)){ cout << " "; for(int k = 0; k < item->columnCount(); k++){ cout << qPrintable(item->text(k)) << " "; } cout << endl; } } } } void checkBranch(QTreeWidgetItem *branch, Qt::CheckState check=Qt::Checked){ for(int i = 0; i < branch->childCount(); i++){ auto item = branch->child(i); item->setCheckState(0, check); } } void checkAll(Qt::CheckState check=Qt::Checked){ for(int i = 0; i < treeWidget->topLevelItemCount(); i++){ auto branch = treeWidget->topLevelItem(i); branch->setCheckState(0, check); checkBranch(branch, check); } } void contextMenu(const QPoint &point){ QMenu menu; auto check_all = menu.addAction("Check all"); auto uncheck_all = menu.addAction("Uncheck all"); auto action = menu.exec(mapToGlobal(point)); if(action == check_all){ checkAll(); }else if(action == uncheck_all){ checkAll(Qt::Unchecked); } } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() タブtab.cxx #include <iostream> #include <QtWidgets> using namespace std; class RadioWidget : public QWidget { QButtonGroup *group; public: RadioWidget(QWidget *parent) : QWidget(parent) { auto radio1 = new QRadioButton("Radio1"); auto radio2 = new QRadioButton("Radio2"); group = new QButtonGroup(); group->addButton(radio1, 1); group->addButton(radio2, 2); radio1->toggle(); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &RadioWidget::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(radio1); layout->addWidget(radio2); layout->addWidget(button); setLayout(layout); } void buttonClicked(){ cout << "Radio: " << group->checkedId() << endl; } }; class CheckWidget : public QWidget { QCheckBox *check1; QCheckBox *check2; public: CheckWidget(QWidget *parent) : QWidget(parent) { check1 = new QCheckBox("Check1"); check2 = new QCheckBox("Check2"); check1->setChecked(true); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &CheckWidget::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(check1); layout->addWidget(check2); layout->addWidget(button); setLayout(layout); } void buttonClicked(){ cout << "Check1: " << check1->isChecked() << endl; cout << "Check2: " << check2->isChecked() << endl; } }; class ComboWidget : public QWidget { QComboBox *combo; public: ComboWidget(QWidget *parent) : QWidget(parent) { auto label = new QLabel("Select"); combo = new QComboBox(this); combo->addItem("apple"); combo->addItem("banana"); combo->addItem("lemon"); combo->addItem("orange"); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &ComboWidget::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(label); layout->addWidget(combo); layout->addWidget(button); setLayout(layout); } void buttonClicked(){ cout << "Combo: " << combo->currentIndex() << ", " << qPrintable(combo->currentText()) << endl; } }; class Main : public QWidget { public: Main() { auto widget1 = new RadioWidget(this); auto widget2 = new CheckWidget(this); auto widget3 = new ComboWidget(this); auto tab = new QTabWidget(); tab->addTab(widget1, "radio"); tab->addTab(widget2, "check"); tab->addTab(widget3, "combo"); auto layout = new QHBoxLayout(this); layout->addWidget(tab); setWindowTitle("tab"); show(); } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() ウインドウの分割splitter.cxx #include <iostream> #include <QtWidgets> using namespace std; class RadioFrame : public QFrame { QButtonGroup *group; public: RadioFrame(QWidget *parent) : QFrame(parent) { auto radio1 = new QRadioButton("Radio1"); auto radio2 = new QRadioButton("Radio2"); group = new QButtonGroup(); group->addButton(radio1, 1); group->addButton(radio2, 2); radio1->toggle(); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &RadioFrame::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(radio1); layout->addWidget(radio2); layout->addWidget(button); setLayout(layout); } void buttonClicked(){ cout << "Radio: " << group->checkedId() << endl; } }; class CheckFrame : public QFrame { QCheckBox *check1; QCheckBox *check2; public: CheckFrame(QWidget *parent) : QFrame(parent) { check1 = new QCheckBox("Check1"); check2 = new QCheckBox("Check2"); check1->setChecked(true); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &CheckFrame::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(check1); layout->addWidget(check2); layout->addWidget(button); setLayout(layout); } void buttonClicked(){ cout << "Check1: " << check1->isChecked() << endl; cout << "Check2: " << check2->isChecked() << endl; } }; class ComboFrame : public QFrame { QComboBox *combo; public: ComboFrame(QWidget *parent) : QFrame(parent) { auto label = new QLabel("Select"); combo = new QComboBox(this); combo->addItem("apple"); combo->addItem("banana"); combo->addItem("lemon"); combo->addItem("orange"); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &ComboFrame::buttonClicked); auto layout = new QVBoxLayout(); layout->addWidget(label); layout->addWidget(combo); layout->addWidget(button); setLayout(layout); } void buttonClicked(){ cout << "Combo: " << combo->currentIndex() << ", " << qPrintable(combo->currentText()) << endl; } }; class Main : public QWidget { public: Main() { auto hbox = new QHBoxLayout(this); auto frame1 = new RadioFrame(this); frame1->setFrameShape(QFrame::Panel); auto frame2 = new CheckFrame(this); frame2->setFrameShape(QFrame::Panel); auto splitter1 = new QSplitter(Qt::Horizontal); splitter1->addWidget(frame1); splitter1->addWidget(frame2); splitter1->setHandleWidth(10); auto frame3 = new ComboFrame(this); frame3->setFrameShape(QFrame::Panel); auto splitter2 = new QSplitter(Qt::Vertical); splitter2->addWidget(splitter1); splitter2->addWidget(frame3); hbox->addWidget(splitter2); setLayout(hbox); setWindowTitle("splitter"); show(); } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() グリッドレイアウトgrid_layout.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QDialog { QLineEdit *edit; public: Main() { auto label = new QLabel("Input"); edit = new QLineEdit(); auto button = new QPushButton("Check"); connect(button, &QPushButton::clicked, this, &Main::buttonClicked); auto layout = new QGridLayout(); layout->setSpacing(10); layout->addWidget(label, 0, 0); layout->addWidget(edit, 0, 1); layout->addWidget(button, 1, 0, 1, 2); setLayout(layout); setWindowTitle("grid layout"); show(); } void buttonClicked() { cout << qPrintable(edit->text()) << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() 絵の描画draw.cxx #include <QtWidgets> class Main : public QMainWindow { public: Main() { setWindowTitle("draw"); resize(320, 240); centerOnScreen(); show(); } void centerOnScreen() { auto res = QDesktopWidget().screenGeometry(); move((res.width()/2.) - (frameSize().width()/2.), (res.height()/2.) - (frameSize().height()/2.)); } void paintEvent(QPaintEvent *e) override { (void)e; auto w = frameSize().width(); auto h = frameSize().height(); QPainter painter(this); painter.setPen(Qt::white); painter.setBrush(Qt::white); painter.drawRect(0, 0, w, h); QPen pen(Qt::black); pen.setWidth(2); painter.setPen(pen); for(int y = 0; y < (int)(240./5.); y++){ painter.drawPoint(20, y*5); } painter.setPen(Qt::red); painter.setBrush(Qt::red); painter.drawRect(50, 50, 100, 50); painter.setPen(QColor(0, 0, 255)); painter.setBrush(QColor(0, 0, 255, 128)); painter.drawRect(80, 80, 100, 60); QPen pen2(Qt::DashLine | Qt::black); pen2.setWidth(2); painter.setPen(pen2); painter.setBrush(QColor(0, 0, 0, 0)); painter.drawEllipse(130, 156, 100, 50); painter.setPen(Qt::black); painter.setFont(QFont("SansSerif", 24)); painter.drawText(200, 100, "Text"); } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() タイマーtimer.cxx #include <iostream> #include <QtWidgets> using namespace std; class Main : public QMainWindow { QTimer *timer; public: Main() { timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &Main::update); timer->start(1000); // msec setWindowTitle("timer"); resize(320, 240); show(); } void update() { cout << "*" << endl; } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } matplotlib の利用Python モジュール matplotlib を使いたい。そのために、Python の呼び出しを行う。Qt の GUI に組み込む方法としては、グラフの絵を作ってそれを貼り付ける方法をとる。 plot.pro に Python の設定を追加。 INCLUDEPATH += /home/xxxx/anaconda3/include/python3.6m LIBS += -L/home/xxxx/anaconda3/lib -lpython3.6m plot.cxx #include <iostream> #include <vector> #include <Python.h> #include <QtWidgets> using namespace std; PyObject* getString(const string str) { return PyUnicode_FromString(str.c_str()); } PyObject* getFloat(double v) { return PyFloat_FromDouble(v); } PyObject* getArray(const vector<double> array) { auto ret = PyList_New(array.size()); for(int i = 0; i < (int)array.size(); i++){ PyList_SetItem(ret, i, getFloat(array[i])); } return ret; } PyObject* importModule(const string name) { auto module = PyImport_ImportModule(name.c_str()); if(!module){ throw runtime_error("Error loading module " + name); } return module; } PyObject* getAttr(PyObject* obj, const string name) { auto attr = PyObject_GetAttrString(obj, name.c_str()); if(!attr){ throw runtime_error("Error get " + name); } return attr; } PyObject* callFunction( PyObject* obj, const string name, PyObject* args = Py_BuildValue("()"), PyObject* keywords = nullptr ) { auto func = getAttr(obj, name); auto res = PyObject_Call(func, args, keywords); if(!res){ throw runtime_error("Error call function " + name); } Py_DECREF(args); if(keywords){ Py_DECREF(keywords); } return res; } class Main : public QDialog { public: Main() { Py_Initialize(); PyObject *res; auto mod_plt = importModule("matplotlib.pyplot"); auto mod_seaborn = importModule("seaborn"); res = callFunction(mod_seaborn, "set"); Py_DECREF(res); auto mod_io = importModule("io"); res = callFunction(mod_plt, "figure", Py_BuildValue("()"), Py_BuildValue("{s:(i, i), s:i}", "figsize", 8, 6, "dpi", 80)); Py_DECREF(res); vector<double> x; vector<double> y; for(double v = 0.; v <= 2.*M_PI; v += 0.1){ x.push_back(v); y.push_back(sin(v)); } res = callFunction(mod_plt, "plot", Py_BuildValue("(N, N)", getArray(x), getArray(y)), Py_BuildValue("{s:s}", "label", "sin")); Py_DECREF(res); res = callFunction(mod_plt, "xlabel", Py_BuildValue("(s)", "x")); Py_DECREF(res); res = callFunction(mod_plt, "ylabel", Py_BuildValue("(s)", "y")); Py_DECREF(res); res = callFunction(mod_plt, "legend"); Py_DECREF(res); auto output = callFunction(mod_io, "BytesIO"); res = callFunction(mod_plt, "savefig", Py_BuildValue("(O)", output), Py_BuildValue("{s:s}", "format", "png")); Py_DECREF(res); auto data = callFunction(output, "getvalue"); unsigned char *s; Py_ssize_t len; PyBytes_AsStringAndSize(data, (char **)&s, &len); auto image = new QImage(); image->loadFromData(s, len, "png"); auto label = new QLabel(); label->setPixmap(QPixmap::fromImage(*image)); auto layout = new QVBoxLayout(); layout->addWidget(label); setLayout(layout); setWindowTitle("plot"); show(); } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } ![]() VTK の利用VTK ライブラリは別途コンパイルしておく。VTK を用いたプログラムのコンパイルには、cmake を用いる。そのために CMakeLists.txt を用意する。 CMakeLists.txt cmake_minimum_required(VERSION 2.8) find_package(VTK REQUIRED) include(${VTK_USE_FILE}) find_package(Qt5Widgets REQUIRED) file(GLOB CXX_FILES *.cxx) add_executable(qvtk ${CXX_FILES}) target_link_libraries(qvtk ${VTK_LIBRARIES} ${Qt5Widgets_LIBRARIES}) qvtk.cxx #include <QtWidgets> #include <QVTKOpenGLWidget.h> #include <vtkSmartPointer.h> #include <vtkCylinderSource.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkProperty.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkCamera.h> #include <vtkRenderWindowInteractor.h> class Main : public QMainWindow { public: Main() { // source auto cylinder = vtkSmartPointer<vtkCylinderSource>::New(); cylinder->SetResolution(20); // mapper auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection(cylinder->GetOutputPort()); // actor auto actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); actor->GetProperty()->SetColor(1., .3882, .2784 ); actor->RotateX(30.); actor->RotateY(-45.); // renderer auto ren = vtkSmartPointer<vtkRenderer>::New(); ren->AddActor(actor); ren->SetBackground(0.1, 0.2, 0.4); // QVTK widget auto qvtk = new QVTKOpenGLWidget(); auto renWin = qvtk->GetRenderWindow(); renWin->AddRenderer(ren); auto inter = qvtk->GetInteractor(); ren->ResetCamera(); ren->GetActiveCamera()->Zoom(1.5); renWin->Render(); inter->Initialize(); auto layout = new QVBoxLayout(); layout->addWidget(qvtk); auto frame = new QFrame(); frame->setLayout(layout); setCentralWidget(frame); setWindowTitle("qvtk"); resize(320, 240); centerOnScreen(); show(); } void centerOnScreen() { auto res = QDesktopWidget().screenGeometry(); move((res.width()/2.) - (frameSize().width()/2.), (res.height()/2.) - (frameSize().height()/2.)); } }; int main(int argc, char **argv) { QApplication app(argc, argv); Main win; return app.exec(); } コンパイル $ mkdir build $ cd build $ cmake .. $ make ![]() | |
PENGUINITIS |