質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

タブ

コンテンツの上下左右に参照用のメニューを設けることで、複数の要素やページの表示を可能にするユーザーインターフェイスパターンのこと。メニューをクリックすると、一つの要素が可視化され、他の要素は見えなくなる。

Qt Creator

Qt Creatorは、Qtアプリケーションを開発するための開発統合環境(IDE)です。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

2866閲覧

Qtでタブを横に配置したときに文字が縦になるのを横にしたいのと、背景画像を設定したい

micchi

総合スコア36

CSS3

CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

タブ

コンテンツの上下左右に参照用のメニューを設けることで、複数の要素やページの表示を可能にするユーザーインターフェイスパターンのこと。メニューをクリックすると、一つの要素が可視化され、他の要素は見えなくなる。

Qt Creator

Qt Creatorは、Qtアプリケーションを開発するための開発統合環境(IDE)です。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2020/04/06 09:48

Qtでフォーム上にタブを配置し、
タブ位置をtabPositionをWestに設定することで左横にしました
またスタイルシートを設定することでタブを巨大化させました

そうしたところ、文字が縦になってしまいました(タブとしてはノーマルな動きかとは思いますが)
やりたいのは
その文字は横方向に文字を表示したいのと、背景画像を設定し、
画像と文字を重なるようにしたいです

//tabW:タブウィジェット //tab:index=0のタブ ui->tab->setStyleSheet("QWidget{background-image: url(C:/work/bottomBlue.png);transform: rotate( -45deg )}"); //全然効かない ui->tabW->setTabText(0,"テストタブ1"); ui->tabW->setStyleSheet("QTabBar::tab { height: 100px; width: 100px; }"); //タブ巨大化成功

としたところ、イメージ説明
と言うような画像になってしまいました

やりたいのは“テストタブ1”,"Tab2"となっているところを横方向に文字を表示し、背景画像と文字を重ねたいのですが何か方法は無いでしょうか

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

横書きに修正

幾つか方法があります。

  • QProxyStyleを使う (paintControl) PyQt5 の場合は注意点有り (PySideは未テスト)
  • QTabBar の paintEvent をオーバーライドする (自分で描画処理を書く)
  • QTabBar.setTabButton を使う

背景画像について

diff

1- `QWidget{background-image: url(C:/work/bottomBlue.png);` 2+ `QTabBar::tab{background-image: url(C:/work/bottomBlue.png);`

QWidgetは多くのウィジェットが継承しているクラスなので、
ボタンなども影響を受けてしまいます。
タブ部分のスタイルを設定するなら、QWidget ではなく QTabBar::tab に記述。
また、Qt の スタイルシートでは transform はサポートされてなかったはずです。

イメージ説明

※↑色を変えただけみたいになってますが、壁紙画像を指定してます。

Qt5 Stylesheet reference


横書きに修正

追記: C++で動作確認したときのコードです。(QProxyStyleを利用して横書きに修正)

cpp

1 2#include <QApplication> 3#include <QMainWindow> 4#include <QTabWidget> 5#include <QTabBar> 6#include <QLabel> 7 8#include <QProxyStyle> 9#include <QStyleOption> 10#include <QtCore> 11 12 13class CustomTabStyle : public QProxyStyle { 14public: 15 QSize sizeFromContents(ContentsType type, const QStyleOption* option, 16 const QSize& size, const QWidget* widget) const { 17 18 QSize s = QProxyStyle::sizeFromContents(type, option, size, widget); 19 if (type == QStyle::CT_TabBarTab) { 20 s.transpose(); 21 } 22 return s; 23 } 24 25 void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const { 26 if (element == CE_TabBarTabLabel) { 27 if (const QStyleOptionTab* tab = qstyleoption_cast<const QStyleOptionTab*>(option)) { 28 QStyleOptionTab opt(*tab); 29 opt.shape = QTabBar::RoundedNorth; 30 QProxyStyle::drawControl(element, &opt, painter, widget); 31 return; 32 } 33 } 34 QProxyStyle::drawControl(element, option, painter, widget); 35 } 36}; 37 38int main(int argc, char *argv[]) 39{ 40 QApplication app(argc, argv); 41 QMainWindow win; 42 QTabWidget tab(&win); 43 QLabel labelA("Hello", &tab); 44 QLabel labelB("Hello", &tab); 45 CustomTabStyle style; 46 47 tab.addTab(&labelA, "日本語"); 48 tab.addTab(&labelB, "OK"); 49 tab.setTabPosition(QTabWidget::West); 50 tab.tabBar()->setStyle(&style); 51 52 win.setWindowTitle("Test"); 53 win.setCentralWidget(&tab); 54 win.show(); 55 56 return app.exec(); 57} 58

イメージ説明
イメージ説明

応用すれば、縦書きも可能です。

参考: 13293-QTabWidget-customization


簡単な方法

追記: 以下はPythonのコードでした。

コードは参考になりませんが、
アプローチ自体はC++でも同様の方法で可能です。

tab.addTab(widget, "") tab.tabBar().setTabButton(0, QTabBar.LeftSide, QLabel("日本語", tab))

QTabBar のサブクラスで描画する方法

追記: 以下はPythonのコードでした。

PyQt5 メモ tab2.py

paintEvent() をオーバーライドして、自分で描画処理を書きます。

QProxyStyleを使う方法

こちらも自分で描画処理を書けますが、
描画オプションだけ変更して、元の描画処理に任せるとコードは少なく済みます。

python

1class FixTabStyle(QProxyStyle): 2 def sizeFromContents(self, content_type, option, size, widget=None): 3 size = QProxyStyle.sizeFromContents(self, content_type, option, size, widget) 4 if content_type == QStyle.CT_TabBarTab: 5 size.transpose() 6 return size 7 8 def drawControl(self, element, option, painter, widget=None): 9 if element == QStyle.CE_TabBarTabLabel: 10 option.shape = QTabBar.RoundedNorth 11 QProxyStyle.drawControl(self, element, option, painter, widget)

PyQt5 の QTabWidget で QTabBarに QProxyStyleを適用する場合の注意点

tab = QTabWidget(parent) tab.setTabPosition(QTabWidget.West) tab.setTabBar(QTabBar(tab)) # <- 必要 tab.tabBar().setStyle(FixTabStyle())

詳しい説明は省きますが、
C++のクラスに対してPythonの関数を設定しても呼ばれないので、
PyQtの提供する PythonのQTabBar を設定してます。(ここはC++であれば不要)

投稿2020/04/06 19:54

編集2020/04/08 14:03
teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teamikl

2020/04/06 19:57

すいません、Pythonのカテゴリだと勘違いしてました。コード修正します
micchi

2020/04/07 04:49

ありがとうございます。上手く行くには行ったのですが・・・ フォームのコンストラクタ内でデザイン済のタブにスタイルの変更を実行するとクラッシュしてしまい、回避は出来ないようでした(あるんでしょうかね・・・) メモリにロードする前に完了していないとダメなのかもしれませんが・・・ デザイナー上に使用出来ないようだと、画面の設計などで他のパーツの配置がたいへんになってしまうのでせっかく教えていただいたのに、申し訳ないのですが 今回は取りあえずボタンを並べてタブっぽく見せかけてやってみます もしかしたらタブウィジェットのコントロールをどこかのクラスで作成してから継承するという方法があったりするのかもしれませんが・・・
teamikl

2020/04/07 13:00

もう一点失念してました、デザイナ上だったんですね。 > メモリにロードする前に完了していないとダメなのかもしれませんが・・・ コードを見ないとわかりませんが、コンストラクタ内で setStyle?された場合、 変数(style)の寿命に注意です。上記サンプルではmain関数に置いてるので(main関数が終了する迄)問題有りませんが、 コンストラクタでは、staticにする、メンバ変数等にしておく、動的に確保する等の対処が必要です。 プレビューに反映させるためには、プラグイン化する必要があります。 手間を考えると、(タブ数が固定か少ない場合で)代用可能なら そちらが良いかもしれないですね。
micchi

2020/04/08 07:26

重ね重ねありがとうございます。変数がスコープを外れて消えたので、クラッシュしたみたいです。とりあえずCustomtabStyleをstatic で宣言したら上手く行きました。 タブを新しいウィジェットとして継承したら(Qtでは格上げと言ってるみたいですが)今のところですが特に問題なく動いています(デザイナー上には反映されていないですが特に問題はなさそうです)
micchi

2020/04/08 07:28

タブに個別に背景画像を指定するスタイルシートがまだわからないので完全解決というわけではないですが・・・
teamikl

2020/04/08 13:59

スタイルシートの QTabBar::tab で出来ませんでしたか?
teamikl

2020/04/08 14:21

タブに壁紙を設定したキャプチャ画像を追加しました。 QTabWidget は、複数の部品で構成されるウィジェットなので、 個々のパーツに対してスタイルを設定する必要があります。 デザイナ上で配置できる部品にはありませんが、タブ部分はQTabBar。 デザイナーからとなると、 独自に作ったウィジェットを「格上げ」によって配置する方法もあるようです。 http://nukesaq88.hatenablog.com/entry/2013/04/11/194433 (但し、イベント関連(タブ切り替え)は自分で処理することになるので、 リストにボタンを並べるのとあまり変わらなくなると思います。レイアウトは自由度が高くなる。) QProxyStyleの場合、デザイナー上への反映には、やはりプラグイン化が必須みたいで、 デザイナーがビルドされたのと同じ環境(コンパイラとライブラリのバージョン)、 もしくは、自分でデザイナー自体をビルドする必要がでてきます。
micchi

2020/04/08 17:13 編集

たびたびありがとうございます。 こちらの意図が正しく伝わっていませんでした タブに個別に背景画像を設定するというのは、タブ1とタブ2では違う画像を配置したいのです(タブ3とか4とかあったら全部違う画像で) 教えていただいた方法だと、タブ1もタブ2も同じ画像になってしまうので解決出来ないと言っていました ----------------------------------------------------------------- それはそれとして・・・ スタイルシートに高さと幅を設定するときに横長にしたいなと思っても縦横が入れ替わっているので height=120px;width=60 のように縦横を入れ替えて値を設定しなければならないのと(これはまあ何とかなるのですが) 背景に指定した画像が画像の見える方向は正しいのだけど、 画像が縦長に展開されて、下のタブの文字を潰してしまうと言う問題が発生しました 試しにbackground-imageではなくborder-imageを使うと画像は正しく出るけど文字がQProxyStyleの設定が消え去ってしまったりと言う動作もしました QProxyStyleに更に何かすればいいのかもしれないですがちょっと時間が無いのと タブの数は多くないのでとりあえず今回はラベルとフレームでなんとか逃げるようにします いっそのこと文字を含めてボタン画像を作ろうとしたのですが個別のタブで画像を指定出来ないので今回は楽な方に逃げることにしました 色々調べれば出てくるのかもしれないですが時間切れなので・・・すいません
teamikl

2020/04/08 20:28

個別でというのは、それぞれのタブでということだったのですね。 個別スタイルシートは プロパティの accessibleName を使ってセレクターで判別できますが、 QTabBar 内の各タブには割り当てることはできない為、 setTabButtonで他のウィジェットを配置して指定する事になります。 QTabBar::tab:first :middle :last という記述で、最初と最後だけは個別に指定できます。 3つ迄は個別指定可能。タブ数が固定ならですが、要件が合わなさそう。 残念ながら、CSS3 にあるような nth-child で指定はサポートされていませんでした。 > 個別のタブで画像を指定 これはラベルを空文字にして、QTabBar へ setTabIcon, setTabIconSize で出来ました。 個別でサイズで違ったりしないなら、使えるかもしれませんが… > ラベルとフレームでなんとか逃げるようにします デザインの自由度やその後の拡張性を考えると、その方が手軽で確実そうですね。
micchi

2020/04/09 12:44

いろいろありがとうございます。 なんだかこちらの能力不足のせいでお手数ばっかり掛けて申し訳ないです 個別のスタイルシート無理なんですか・・・だったらもうしょうが無いです それと画像ですが煮詰まりすぎててちょっと目的を見失ってました そもそも「自前のフォントを使いたいお客がいる」ので横のタブにわざわざ横書きできるか調べてたのに 文字まで画像にするとかちょっと自分がアホすぎでした 今になって「やっぱダメ」とは言えないのでラベルとフレームでこのまま行くようにします 本当にありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問