From ad45dfa2051ffe2bbbc7a76a420f3a2f3c39ae95 Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Sun, 5 Jan 2025 17:12:20 -0500 Subject: [PATCH] Deployed d47e188 with MkDocs version: 1.6.1 --- 404.html | 23 + _auto_images/CmapCatalogComboBox.png | Bin 3452 -> 5684 bytes _auto_images/QCollapsible.png | Bin 58281 -> 1694 bytes _auto_images/QColorComboBox.png | Bin 2216 -> 1581 bytes _auto_images/QEnumComboBox.png | Bin 4410 -> 5244 bytes _auto_images/QIconifyIcon.png | Bin 0 -> 6154 bytes _auto_images/QQuantity.png | Bin 4070 -> 4069 bytes faq/index.html | 23 + index.html | 23 + objects.inv | Bin 3390 -> 3438 bytes search/search_index.json | 2 +- sitemap.xml | 4 + sitemap.xml.gz | Bin 451 -> 458 bytes utilities/cmap/index.html | 23 + utilities/code_syntax_highlight/index.html | 23 + utilities/error_dialog_contexts/index.html | 23 + utilities/fonticon/index.html | 25 +- utilities/iconify/index.html | 1649 ++++++++++++++++++ utilities/index.html | 47 + utilities/qmessagehandler/index.html | 25 +- utilities/signal_utils/index.html | 23 + utilities/thread_decorators/index.html | 23 + utilities/threading/index.html | 23 + utilities/throttling/index.html | 23 + widgets/colormap_catalog/index.html | 23 + widgets/index.html | 23 + widgets/qcollapsible/index.html | 23 + widgets/qcolorcombobox/index.html | 23 + widgets/qcolormap/index.html | 23 + widgets/qdoublerangeslider/index.html | 23 + widgets/qdoubleslider/index.html | 23 + widgets/qelidinglabel/index.html | 23 + widgets/qenumcombobox/index.html | 23 + widgets/qflowlayout/index.html | 23 + widgets/qlabeleddoublerangeslider/index.html | 23 + widgets/qlabeleddoubleslider/index.html | 23 + widgets/qlabeledrangeslider/index.html | 23 + widgets/qlabeledslider/index.html | 23 + widgets/qlargeintspinbox/index.html | 23 + widgets/qquantity/index.html | 43 +- widgets/qrangeslider/index.html | 23 + widgets/qsearchablecombobox/index.html | 23 + widgets/qsearchablelistwidget/index.html | 23 + widgets/qsearchabletreewidget/index.html | 23 + 44 files changed, 2449 insertions(+), 13 deletions(-) create mode 100644 _auto_images/QIconifyIcon.png create mode 100644 utilities/iconify/index.html diff --git a/404.html b/404.html index f7ae4e7..c627417 100644 --- a/404.html +++ b/404.html @@ -273,6 +273,8 @@ + + @@ -406,6 +408,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/_auto_images/CmapCatalogComboBox.png b/_auto_images/CmapCatalogComboBox.png index f3de51c53ebb34f2eab3c6bd66d85b6586451df7..8b3b41ba52108fe4068b0501eda25a1ebc7adccf 100644 GIT binary patch literal 5684 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 akN*cI;bd?ne}ilQ0000`Iml(h#yVUX!R~CmF_w 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 RXkdlI;OXk;vd$@?2>?+dZuI~F literal 58281 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 diff --git a/_auto_images/QColorComboBox.png b/_auto_images/QColorComboBox.png index 6ad39ca46980abc7d35373828865e662a440bb08..0e4511504e5de1d223b72c21385c63cd20a1aa29 100644 GIT binary patch literal 1581 zcmb7EdobGFEVXSNlDpq>*9>nfbO34kxV zE{A26+q$6kx~4f-pj;r0Z>NXMsl5)3MHcDp3R+lXII36(GbCFElQMPS(45O0Wnkt! z5e9=nGnx}7RVx~jW+1@xUssHdjzS@+TrSsUWD6XccrrW>Wop_oH8oYr5`Ia*XreOc zAsL6Fu-Rs_$&CryAZgp02~?RV9?`}1mf7XD21iF5Wl^+JQ&Tx^y?W-IC^TAXkLkP8 zWpg4U<53a{sZR4_n(9oL!8h=99ZN%g6t=wmVRO=|2kvH4zvG4Uu!&Pp6kgG@@Kx4t) z=LeOClc_WCnRt4-S9esUqcK&^S#L&#PohlB=spUWll- zX$t(+Zm|r5bAaunf@|02pD7O)*T#@=+>CdR5!DM*Q)VKHUG#K-YXx~bf)hfD_8a?T zYb(Bl|L*XV2jFnP%btGaQ6i)CnzQbwFMEvh4lJ|N3JhG{Guo#eAOr}T&d>XE`%y^i zj74C3yLjYAnF-T}x0kM4+{jLECh&3=W6`>^$&CE*aln-i_*4LWsk9X<;G9}^by4c81{WkR z6)I-?UZVuH&eS)LxnCS$N2hgU_4=q5&!EM|yuw)Pn3()#5TH^cF1a0mXYAuN&A*P= z#PIIzsH)oFfH^N=$cNfT1^9EA{YdNYO<*tBSA!59VGvz*=SFx+divwV1$@yRnk?}J zpF@(hsV>IHKABO}`KtyFReD&e$MSdF3@to!?#Ry}B$>ZI-EL}ZfcK&E>)5-mHyI7WwYxd$4|B+$<#udu*Q7*~goTDX_I({|nxB|uYi%ENIrh`QU0I&M z$D^6%*vjzJ52(`#XgDzG!}J*iTU4r!5>@i{sQFobp}p}L@UXI3FZl4Txi(ns`*y_D${>GGn`5y4yWszhw6I zwN;XVC{ErQ%aRgBB-5(Iz^i?w~fREnwDppnRR z&%)!CnSIZR0>pJML7c21dD;G&Mi`&#fL^|Qu|YacrT&O3ra@0PY2$rUv%|(GCazRh zSIg&EELNB3(S;t3&P=*;7k>y^Nkl+i%;}9ml`tkd#E3zDRa# z*O%GD;LJfA8_9}p9lBu;1-gd~-GX^bv%cB^w5-S!rRc;C_xpe_V2PI_;)CDsTzC%I%74lV z2%_2WgDwCOPDm_53M3XG1rm#p0*OUPfy5%DKw=S6Ah8H3kXVEi)bf8U8@Dn%wazw8 zIO3p+L>y8WLrg_Hf^I_$Cd82z!Px#gdqX;zO?LG&ey{M5N=ZEGB;zSnY@oE)(EeX)xJuzze^{fw+48ew*c{r3~a5tVU^1Gtr;3`jK2opm;O zN2&Ob14ym!Uk4+I0L(72#f?1{aR8g<0TqV`5mR?qc|PO-^(+ug;EOG`d~Y{ssXn{D z_@sURhlN6+P$(3OMcc0OEfFRdV_>`>v@gu)r)$yme2x86YpmNSMJYeADt|Cdb8BnM zFpOj}8I49Gkx0WOCLRv=wbkmwwr$6;x3{;Gxm-_lIh{9dF6ln`?QSku#45jlX_~64 z4i67&n)X12CFE1?leq7bAh_L9ilQirqG=JsXzl8Q}9?To_`+1sbd)Fga8yb zdI=A1qk@V$>FEXlSUuLJEEEc@t*zAhJN$SF&Jnm*z|Y^po72tdo^%BMF@s-R z!o5N%r26RU8=fqhDan* zEEavr<0qD7S+Q8G*>`}Dg4+O`TfyI_Aw=`Hi_@4}fg?)MQPZ@>BbE??^5Ege%Y#J+ zZ%(7=ND*uIjm|x{x2vN1Wf;eorwJTfTy%Zd2SATgg1zW%o;0$GbUe&2% zNQXGIxOuSXAf0{CVH_XQSrnb!Z0HY(6$adhRdnj^uc`~n-VrOn&Lmc-kQc7%g~SRE zjw7*x3desWP|TID~AjP)u|e12o8xADr$};UtiqgmS@$k-^QzxwGR&t zi4`h*vY59`rtyP6@7A{f{OWDIG8yRD;EyDbSmA*Mh*<76mB#buOK$!05?=Wz=z+nZ z?uL-y#($FF_3Ozr2G2HfAs#Ghkys&tF>oe*NGG6GAhE&(W75}m3I5zCi4_JIN)t_0 zMdBk_acyTtYk-|etdQWQ!oF6_ugSVZudy?2H2{9CLdKY7Sd%Kx8fRKQfo>Yz(#(w}-qxZbA4Gd?-q3$f=U|E*`L>oV` zR8`I8a!tMsgd7-y!Z6m0i6^9ltBEHt)>}%2xowfp=M|-LLECct#EL{BtE;Qcz5|35 z+*BA<@$$2Hs=vurJ=uqspG8!K%E1}Z>mrxSsj6QEy@puXY&M^-wL&0q(0B_EMHF3B*3lIZp{UrE-pl0$oK^MNCCh zg~kD3aYMZILB_JIWHNdGNpvmnQjv_Y{{H@dzw^$>$jI>UaQ#1)c&I2Gj)2C&wUQZz ztCX|5sGkqsa()Vj!l7}f914fR0AOy(x%A=PyUQy*Jv~(q*R^_QplDh7e12nN zBb&|Yx}HcR;_>)?dk-e|ip2vAUVp~paZS^uTwGi%7K={sS+T?;3+G%_RZY`e zrF@o$Ovc5Lmc3%N#*hurrJ!kAdwaXC>y~AaSpO$@V%1zJ?ZkknY!wc6h-^M+Qj0_) zv>F>x!Dx@Dc-1Ng@OZD&LaGprGSDGT4pcs@!vSatp8hiBHKGwlyPa=;rGLt+d+BB4 zM1v&b;>18@2J~R%9qX2jTN$2OXPYLy#E__jG3Xl8HPLN|!Gt){B7C}=7>(EvGN5^d zgcL|DLJA}nAq5hPkOGNCNP)y6q(EX3QXsJiDUeu%6i6&W3M3XG1rm#p0*OUP;eXLg WOfKVG0|o#9002ovPDHLkU;%=*ZXvkor;(gK1Y9g(I2(t8sWAumlq1VNgJH0hm?pj442Aib(cRq373rFRfi zO6UOs1|$#?+V>=$@BBC?*Om6{&g{(2eb3Bp^nC+udKwNI5C}vM(Yb2`0+DY3zwck9 z1U}zPSla?$)E+vIy+I&aX5yO+l$p&20$siZxvTLoAbV#%@a@!EM*E(-zjQWvA6G@! zlEBMrUOECy5|T`NuOC%8KQd!{s(0;m`t=T`D|S^+8(Ekbuh{*&(nS6IivB~*O0&+= z;y$L^@h_KOa>c*7Dxpfglv$Q=x`M*$Nq5<^6{cW{N?jHLk;qxhq;!btsTCi`TRovW z&BQ*Q@dFi+xUy8dY zP6a0mZXEA=2h0=L9IB>CPfAOxZ*a43CdV zO$;oY+|SsN>z(XPvd*BKaX03f6g$n%&uSEU$s+(_tWDB3k#RFo=LrWms>@W~_bSl< zft>!%rCs?u@+#S%{c)Lp*F<#ohTJ8M%E~eOkW@;&q;4V&vbSHbBn}nO*@WIA8A0hd zJw?Vf`qta#Hec|2ewl=JYh;wVXheu319SPS_#NAYtO^@fW9^&7*%L)+>Ko%XuAlFJtMK6NW-5|bBduqU601MPZ_DQExr13V*`21U*g`DgU{Nl! z;M6-OGJ>en(MSyJ&!>*_&#weI4M!VDHjUO#rsn(q21Nu`5LAofdC&1~jc*SiKI7yb zz1vuLc?-Q*bw11`z>Z&lQ*evmRlT&`l0R2+>csJoD35LQH)q0Dn|For=evp=m4E6O z+TWYfhtIIi7;cG_F5y#(M>J1O*Sb)Uw=%v{ zze)dms*7*KUoKp;qMGh-yByZ)0$!~RGozCWzTj%!j< zx`qjz+Vuz=u0Z_bs1vyZs;iNr*4MhPJPzH5BE?&YJuWw&;d*%aA+*9v)LpOnI(Trx)?wYAJ*rmCB)s%a z6jKw_VW0fO@q_MN&AhyAqao+KEfuVk2jLhirm0g5As?(ZFZCxg;~1wKDtK6_kUi5V zr>K6P?7Wg~`ZCqvy!Z}1lKpZG{SJA^3GE49KVXNup+G*CjjIMxMYdi}GhiQOphm)C zlCz9?=z=WOnWxSD1?a`~6J+#3S#hLgNSJC!*%uL2wka5gg<2#Ps$;1XOQ5B385D1$ z7_7grmIGbNXuBYNAbY&Xe@VfNy_@k%^$ZMyyp%?A!dKQj6pmgS6J>fAf-^t8fcJS^ zQMXjdU^1ObuSnD_4XEN`c>vdv^XHu*1=o%M=TG~8!sdVH`^7ilk60g~AB)?n? z46hps&3od#ow54)V(jVa$X>v;hJBUfdXIWHo;lBjCN0z4%L< zYHdCw43(OAg;cs%GR!214( zGixw@_hVV;ojpppWU-+@7-I8y(B+r~18EaSXbT?|l}`y_iEazPIC}NR$lmz1PY#B9 zp;iMitHq$JN?hstd*W!4&$>d%1@2JvWNvWnA#T9TLn50bM!*_4 zM?>RgVnU7Qq5iM%Ws`=ofB7hkDF8>4auXzOr68?Am#C(|c=Z33CJ7Cazzy>7597sA z-K6EFy0icLG(Ddr`HoC)j6{b4kkAHEm4H3yzjg0+bs_k6oG@#QWXM@?Qoq0zs{p?F zW`FlB67?Y3wxMT=en-2ug@$?H_U>qAeUhddVU6AYw@m)8Ex|&E`Mpmi7edZq=5;S1 zX}2sdMrii#BU$ME9-?<*H_(@@V#);LX?RX(M#x3>q~y>=-Q%spV~ zKd)tAU=X&_dicvl~DaUx9g!>AIi9+rKM#Kv$q#S zPk;IN`EzVJY{!K@9$#jC`bN=v{l1k|?xT>6F}^z2*&dPdmd^H9F`Dv=? z<4)fhOH)itM2d*1*QhG40CtJ2V{=D0?Uo>GOr>oXC5V!NM-SNw<2;!oA-FItkva%4 z(0?IN`1|+oKELNOoF)q;?FTM@MI4$p`Rxq6VG$|*`t><#Bqtbcf&BLXO4uyQP=(5Y zP6-Dq+UkT$E4>M*P}*BpIpV4uMtS61f88y6^koCt7V;~-?RXxOF6{sYsX`B*ZU3m8 z^X%n*60j8U%-+7z7ySr8Qa6B~hNVbOqf^N)IW-b9`7@sHZx=r8qB&xhD( zXlZ}8!jzA37>9$c@0TxM_W0e1DkR*psEgIll6&y@F~rkT()5WZ1+%chYTc}x-R@#X z%kl5#?b-T-(_>t6PEHQ%zBVtcJI8+kqNPOvXy-VVfw=#rCS^vW zStNEEJs<27{O#U~f9^~f+!;^WtYxRh1ME z4Ex}!PKCp8rWO!pvg@Lv&-&i-#d0gB0wLjnZc9co@EYu|55KZGKV&vkA-ip5#gm}& zN5>fwXlu)tX6eViAy0&{_EPLB41am`5mT3{bz&Q6cLk9X>s6ME0To<|T<&?dI8&v*_kQ~?mRWJWFc z$OFEgh1}ivm@rXguM3iMo71_L2wMEzj4=>I$yQZYXGqxo!^ovn?~9&(Xz}2|gVJCC zaxx9bV_|hXb^V+dt@_Cl!(?iv`&`4Nm#whlLO=|NchAw@%Bw|CV-xfnnnTw4A)*_R zpZ`(~MgUdV^~TrK`6FRhh<^)!>6CPA?Zpp1a&Y}kn}JeZlnCoKH~^prmX^cDhN|C) z0Qxf^!mi+PH6kK{KKG4P@^x}z>;Vc)Lkrh;WiK+#?T@PS>KKlRH!Oxy+BwhGi2>H> znp>Kfu*}xElIsXg(3i~Cd9K`RJ^ChISnFVK|49s1UItimyMm$h9>5P?_|cMQ@6Jp) z^1&=|uOJzM{LEOtonN00b4*Q4D&eO=)8*C-w+#%yrk1`e$g{)x%>@LsbhJ=E%V-S> zAhyBo#X?J?6%t4!K z&{iFOH@RHqk`W=KIx^)WC8t5vH#}@Vlr9P2Ei#OXp(^OW`RoLxzQ3O3&Xmxbq2zlL zcv=WMKEwiuS{qDbj=mdkve(O*9jKNGxL^I^r_{f?x;I2bl(%wLw6}g%3lC??^0UUs z27EJ*TV7s%_;dltq|EVXvz2?-E-mjJN%nqu3>PQ)7t9{0^W+WyGj=7P>i}Uc%Fp{S zGY$omThxP#^@CUT0>Y>Uxpn8+ahad6+NGaAuQsA`R}4c4##=8N*N3x;QWM+uN0hZ; z=b6oY=pH=Iar^^?LmuqVvlj*c|NM6)DUe0l_k=du&JN1)9SrbxAOl?&6ZfDRx>Q55XH9A1$_**$E9$_~pqwjq@AdF-yCP(oE zy^i9AE9_J>W_rrM_|ZOTsBT$~JlvTL1a^hY@p~x?fYIKwUE$*O`;GLRas|KL%Uys( zsPuIWgXxUu5x~|9}Eb$986mPx$kXSnzksb-R8unp-kDBKYzS{ zSGtT76OclH%v%6{Cn6$ZxAUu3#$`Ho`iq6Jkx}Ofem`*IebnoFA0L{UN;^#yOi3L* z`eHu*L5mjn(h3Yz6fylOzy+SHbG3N$=FQOx?|ENK;66wJmF<1Bmk^Tu<{;a9#CC7_ z8<$#e`u8$ZV<6>LKOZhGF17(44rMD!r|cSLNJUs7fEsvL)hye9>auK;4C%<3= zq(5Lcg?2dVb5)^Lj^o!#OH0kFpVI>^g^c?`HaQiz!edGE`EX{+q2Ra0juExejrvpVrMLKS!cSX5D zr5&oPszF#Apj6Ot$P_R1Z&FZD=w-^3Sb2eKi+X2HUI15Aid)hEG1p&F@#I_7yEz>I zI_97lgp=KLO9Bz~H>B-X=?KJDu6ra$8L0U5fD&OJn3)PsQ9(gCKe^^d*bEo&3W2X{Y(l1flvdjmCwf5t9WkZpl_sm z9avAW5Yyk=95qa5drcu&lhkxb&xvuQU21_K^Zo-I)53)IJK>dj6&G!-DWU1vhR?|ht*tn8 UC7yNx*NGsAmciYxnl_>T0lHpR?*IS* literal 4410 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 H1cm+^hZ&{# literal 0 HcmV?d00001 diff --git a/_auto_images/QQuantity.png b/_auto_images/QQuantity.png index 59c4e8ec4ac2cd60932f4172755da93232128f30..f144e567aacac71be19996754e9e0fe83490fb3f 100644 GIT binary patch delta 3889 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 delta 3888 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 + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/index.html b/index.html index 73fd4f8..5d9af3e 100644 --- a/index.html +++ b/index.html @@ -349,6 +349,8 @@ + + @@ -482,6 +484,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/objects.inv b/objects.inv index 6b830cb22c2cdc17591dce52e5c8f3d302d5dfae..f1f9d0bf8a32fb888527a1a2026e701fe799d6b1 100644 GIT binary patch delta 3348 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 delta 3299 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 repository aims to provide high-quality community-contributed Qt widgets and components for PyQt & PySide that are not provided in the native QtWidgets module.

    Components are tested on:

    • macOS, Windows, & Linux
    • Python 3.9 and above
    • PyQt5 (5.11 and above) & PyQt6
    • PySide2 (5.11 and above) & PySide6
    "},{"location":"#installation","title":"Installation","text":"
    pip install superqt\n
    conda install -c conda-forge superqt\n
    "},{"location":"#usage","title":"Usage","text":"

    See the Widgets and Utilities pages for features offered by superqt.

    "},{"location":"faq/","title":"FAQ","text":""},{"location":"faq/#sliders-not-dragging-properly-on-macos-12","title":"Sliders not dragging properly on MacOS 12+","text":"Details

    On MacOS Monterey, with Qt5, there is a bug that causes all sliders (including native Qt sliders) to not respond properly to drag events. See:

    • https://bugreports.qt.io/browse/QTBUG-98093
    • https://github.com/pyapp-kit/superqt/issues/74

    Superqt includes a workaround for this issue, but it is not perfect, and it requires using a custom stylesheet (which may interfere with your own styles). Note that you may not see this issue if you're already using custom stylesheets.

    To opt in to the workaround, do any of the following:

    • set the environment variable USE_MAC_SLIDER_PATCH=1 before importing superqt (note: this is safe to use even if you're targeting more than just MacOS 12, it will only be applied when needed)
    • call the applyMacStylePatch() method on any of the superqt slider subclasses (note, this will override your slider styles)
    • apply the stylesheet manually:
    from superqt.sliders import MONTEREY_SLIDER_STYLES_FIX\n\nslider.setStyleSheet(MONTEREY_SLIDER_STYLES_FIX)\n
    "},{"location":"utilities/","title":"Utilities","text":""},{"location":"utilities/#font-icons","title":"Font Icons","text":"Object Description addFont Add an OTF/TTF file at to the font registry. font Create QFont for a given font-icon font family key icon Create a QIcon for font-con glyph key setTextIcon Set text on a QWidget to a specific font & glyph. IconFont Helper class that provides a standard way to create an IconFont. IconOpts Options for rendering an icon Animation Base class for adding animations to a font-icon."},{"location":"utilities/#threading-tools","title":"Threading tools","text":"Object Description ensure_main_thread Decorator that ensures a function is called in the main QApplication thread. ensure_object_thread Decorator that ensures a QObject method is called in the object's thread. FunctionWorker QRunnable with signals that wraps a simple long-running function. GeneratorWorker QRunnable with signals that wraps a long-running generator. create_worker Create a worker to run a target function in another thread. thread_worker Decorator for create_worker, turn a function into a worker."},{"location":"utilities/#miscellaneous","title":"Miscellaneous","text":"Object Description QMessageHandler A context manager to intercept messages from Qt. CodeSyntaxHighlight A QSyntaxHighlighter for code syntax highlighting. draw_colormap Function that draws a colormap into any QPaintDevice."},{"location":"utilities/cmap/","title":"Colormap utilities","text":"

    See also:

    • superqt.QColormapComboBox
    • superqt.cmap.CmapCatalogComboBox
    "},{"location":"utilities/cmap/#superqt.cmap.draw_colormap","title":"superqt.cmap.draw_colormap(painter_or_device, cmap, rect=None, border_color=None, border_width=1, lighter=100, checkerboard_size=4)","text":"

    Draw a colormap onto a QPainter or QPaintDevice.

    Parameters:

    Name Type Description Default painter_or_device QPainter | QPaintDevice

    A QPainter instance or a QPaintDevice (e.g. a QWidget or QPixmap) onto which to paint the colormap.

    required cmap Colormap | Any

    cmap.Colormap instance, or anything that can be converted to one (such as a string name of a colormap in the cmap catalog). https://cmap-docs.readthedocs.io/en/latest/colormaps/#colormaplike-objects

    required rect QRect | QRectF | None

    A rect onto which to draw. If None, the painter.viewport() will be used. by default None

    None border_color QColor | str | None

    If not None, a border of color border_color and width border_width is included around the edge, by default None.

    None border_width int

    The width of the border to draw (provided border_color is not None), by default 2

    1 lighter int

    Percentage by which to lighten (or darken) the colors. Greater than 100 lightens, less than 100 darkens, by default 100 (i.e. no change).

    100 checkerboard_size bool

    Size (in pixels) of the checkerboard pattern to draw, by default 5. If 0, no checkerboard is drawn.

    4

    Examples:

    from qtpy.QtGui import QPixmap\nfrom qtpy.QtWidgets import QWidget\nfrom superqt.utils import draw_colormap\n\nviridis = \"viridis\"  # or cmap.Colormap('viridis')\n\n\nclass W(QWidget):\n    def paintEvent(self, event) -> None:\n        draw_colormap(self, viridis, event.rect())\n\n\n# or draw onto a QPixmap\npm = QPixmap(200, 200)\ndraw_colormap(pm, viridis)\n
    "},{"location":"utilities/cmap/#superqt.cmap.QColormapLineEdit","title":"superqt.cmap.QColormapLineEdit","text":"

    Bases: QLineEdit

    A QLineEdit that shows a colormap swatch.

    When the current text is a valid colormap name from the cmap package, a swatch of the colormap will be shown to the left of the text (if fractionalColormapWidth is less than .75) or behind the text (for when the colormap fills the full width).

    If the current text is not a valid colormap name, a swatch of the fallback colormap will be shown instead (by default, a gray colormap) if fractionalColormapWidth is less than .75.

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget.

    None fractional_colormap_width float

    The fraction of the widget width to use for the colormap swatch. If the colormap is full width (greater than 0.75), the swatch will be drawn behind the text. Otherwise, the swatch will be drawn to the left of the text. Default is 0.33.

    0.33 fallback_cmap Colormap | str | None

    The colormap to use when the current text is not a recognized colormap. by default \"gray\".

    'gray' missing_icon QIcon | StandardPixmap

    The icon to show when the current text is not a recognized colormap and fractionalColormapWidth is less than .75. Default is a question mark.

    MISSING checkerboard_size int

    Size (in pixels) of the checkerboard pattern to draw behind colormaps with transparency, by default 4. If 0, no checkerboard is drawn.

    4"},{"location":"utilities/cmap/#superqt.cmap.QColormapItemDelegate","title":"superqt.cmap.QColormapItemDelegate","text":"

    Bases: QStyledItemDelegate

    Delegate that draws colormaps into a QAbstractItemView item.

    Parameters:

    Name Type Description Default parent QObject

    The parent object.

    None item_size QSize

    The size hint for each item, by default QSize(80, 22).

    DEFAULT_SIZE fractional_colormap_width float

    The fraction of the widget width to use for the colormap swatch. If the colormap is full width (greater than 0.75), the swatch will be drawn behind the text. Otherwise, the swatch will be drawn to the left of the text. Default is 0.33.

    1 padding int

    The padding (in pixels) around the edge of the item, by default 1.

    1 checkerboard_size int

    Size (in pixels) of the checkerboard pattern to draw behind colormaps with transparency, by default 4. If 0, no checkerboard is drawn.

    4"},{"location":"utilities/code_syntax_highlight/","title":"CodeSyntaxHighlight","text":"

    A code highlighter subclass of QSyntaxHighlighter that can be used to highlight code in a QTextEdit.

    Code lexer and available styles are from pygments python library

    List of available languages are available here.

    List of available styles are available here.

    "},{"location":"utilities/code_syntax_highlight/#example","title":"Example","text":"
    from qtpy.QtGui import QColor, QPalette\nfrom qtpy.QtWidgets import QApplication, QTextEdit\n\nfrom superqt.utils import CodeSyntaxHighlight\n\napp = QApplication([])\n\ntext_area = QTextEdit()\n\nhighlight = CodeSyntaxHighlight(text_area.document(), \"python\", \"monokai\")\n\npalette = text_area.palette()\npalette.setColor(QPalette.Base, QColor(highlight.background_color))\ntext_area.setPalette(palette)\ntext_area.setText(\n    \"\"\"from argparse import ArgumentParser\n\ndef main():\n    parser = ArgumentParser()\n    parser.add_argument(\"name\", help=\"Your name\")\n    args = parser.parse_args()\n    print(f\"Hello {args.name}\")\n\n\nif __name__ == \"__main__\":\n    main()\n\"\"\"\n)\n\ntext_area.show()\ntext_area.resize(400, 200)\n\napp.exec_()\n
    "},{"location":"utilities/code_syntax_highlight/#qt-class","title":"Qt Class","text":"

    QSyntaxHighlighter

    "},{"location":"utilities/code_syntax_highlight/#methods","title":"Methods","text":"

    A syntax highlighter for code using Pygments.

    Parameters:

    Name Type Description Default parent QTextDocument | QObject | None

    The parent object. Usually a QTextDocument. To use this class with a QTextArea, pass in text_area.document().

    required lang str

    The language of the code to highlight. This should be a string that Pygments recognizes, e.g. 'python', 'pytb', 'cpp', 'java', etc.

    required theme KnownStyle | str

    The name of the Pygments style to use. For a complete list of available styles, use pygments.styles.get_all_styles().

    'default'

    Examples:

    from qtpy.QtWidgets import QTextEdit\nfrom superqt.utils import CodeSyntaxHighlight\n\ntext_area = QTextEdit()\nhighlighter = CodeSyntaxHighlight(text_area.document(), \"python\", \"monokai\")\n\n# then manually apply the background color to the text area.\npalette = text_area.palette()\nbgrd_color = QColor(self._highlight.background_color)\npalette.setColor(QPalette.ColorRole.Base, bgrd_color)\ntext_area.setPalette(palette)\n
    "},{"location":"utilities/code_syntax_highlight/#superqt.utils.CodeSyntaxHighlight.background_color","title":"background_color: str property","text":""},{"location":"utilities/code_syntax_highlight/#superqt.utils.CodeSyntaxHighlight.setLanguage","title":"setLanguage(lang: str) -> None","text":"

    Set the language for the syntax highlighting.

    This should be a string that Pygments recognizes, e.g. 'python', 'pytb', 'cpp', 'java', etc.

    "},{"location":"utilities/code_syntax_highlight/#superqt.utils.CodeSyntaxHighlight.setTheme","title":"setTheme(theme: KnownStyle | str) -> None","text":"

    Set the theme for the syntax highlighting.

    This should be a string that Pygments recognizes, e.g. 'monokai', 'solarized'. Use pygments.styles.get_all_styles() to see a list of available styles.

    "},{"location":"utilities/error_dialog_contexts/","title":"Error message context manager","text":""},{"location":"utilities/error_dialog_contexts/#superqt.utils.exceptions_as_dialog","title":"superqt.utils.exceptions_as_dialog","text":"

    Context manager that shows a dialog when an exception is raised.

    See examples below for common usage patterns.

    To determine whether an exception was raised or not, check the exception attribute after the context manager has exited. If use_error_message is False (the default), you can also access the dialog attribute to get/manipulate the QMessageBox instance.

    Parameters:

    Name Type Description Default exceptions type[BaseException] | tuple[type[BaseException], ...]

    The exception(s) to catch, by default Exception (i.e. all exceptions).

    Exception icon Icon

    The icon to show in the QMessageBox, by default QMessageBox.Icon.Critical

    Critical title str

    The title of the QMessageBox, by default \"An error occurred\".

    'An error occurred' msg_template str

    The message to show in the QMessageBox. The message will be formatted using three variables:

    • exc_value: the exception instance
    • exc_type: the exception type
    • tb: the traceback as a string

    The default template is the content of the exception: \"{exc_value}\"

    '{exc_value}' buttons StandardButton

    The buttons to show in the QMessageBox, by default QMessageBox.StandardButton.Ok

    Ok parent QWidget | None

    The parent widget of the QMessageBox, by default None

    None use_error_message bool | QErrorMessage

    Whether to use a QErrorMessage instead of a QMessageBox. By default False. QErrorMessage shows a checkbox that the user can check to prevent seeing the message again (based on the text of the formatted msg_template.) If True, the global QMessageError.qtHandler() instance is used to maintain a history of dismissed messages. You may also pass a QErrorMessage instance to use a specific instance. If use_error_message is True, or if you pass your own QErrorMessage instance, the parent argument is ignored.

    False

    Attributes:

    Name Type Description dialog QMessageBox | None

    The QMessageBox instance that was created (if use_error_message was False). This can be used, among other things, to determine the result of the dialog (e.g. dialog.result()) or to manipulate the dialog (e.g. dialog.setDetailedText(\"some text\")).

    exception BaseException | None

    Will hold the exception instance if an exception was raised and caught.

    Examples:

    from qtpy.QtWidgets import QApplication\nfrom superqt.utils import exceptions_as_dialog\n\napp = QApplication([])\n\nwith exceptions_as_dialog() as ctx:\n    raise Exception(\"This will be caught and shown in a QMessageBox\")\n\n# you can access the exception instance here\nassert ctx.exception is not None\n\n# with exceptions_as_dialog(ValueError):\n#     1 / 0  # ZeroDivisionError is not caught, so this will raise\n\nwith exceptions_as_dialog(msg_template=\"Error: {exc_value}\"):\n    raise Exception(\"This message will be inserted at 'exc_value'\")\n\nfor _i in range(3):\n    with exceptions_as_dialog(AssertionError, use_error_message=True):\n        assert False, \"Uncheck the checkbox to ignore this in the future\"\n\n# use ctx.dialog to get the result of the dialog\nbtns = QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel\nwith exceptions_as_dialog(buttons=btns) as ctx:\n    raise Exception(\"This will be caught and shown in a QMessageBox\")\nprint(ctx.dialog.result())  # prints which button was clicked\n\napp.exec()  # needed only for the use_error_message example to show\n
    "},{"location":"utilities/fonticon/","title":"Font icons","text":"

    The superqt.fonticon module provides a set of utilities for working with font icons such as Font Awesome or Material Design Icons.

    "},{"location":"utilities/fonticon/#basic-example","title":"Basic Example","text":"
    from fonticon_fa5 import FA5S\n\nfrom qtpy.QtCore import QSize\nfrom qtpy.QtWidgets import QApplication, QPushButton\n\nfrom superqt.fonticon import icon, pulse\n\napp = QApplication([])\n\nbtn2 = QPushButton()\nbtn2.setIcon(icon(FA5S.smile, color=\"blue\"))\nbtn2.setIconSize(QSize(225, 225))\nbtn2.show()\n\napp.exec()\n
    "},{"location":"utilities/fonticon/#font-icon-plugins","title":"Font Icon plugins","text":"

    Ready-made fonticon packs are available as plugins.

    A great way to search across most available icons libraries from a single search interface is to use glyphsearch: https://glyphsearch.com/

    If a font library you'd like to use is unavailable as a superqt plugin, please open a feature request

    "},{"location":"utilities/fonticon/#font-awesome-6","title":"Font Awesome 6","text":"

    Browse available icons at https://fontawesome.com/v6/search

    pip install fonticon-fontawesome6\n
    "},{"location":"utilities/fonticon/#font-awesome-5","title":"Font Awesome 5","text":"

    Browse available icons at https://fontawesome.com/v5/search

    pip install fonticon-fontawesome5\n
    "},{"location":"utilities/fonticon/#material-design-icons-7","title":"Material Design Icons 7","text":"

    Browse available icons at https://materialdesignicons.com/

    pip install fonticon-materialdesignicons7\n
    "},{"location":"utilities/fonticon/#material-design-icons-6","title":"Material Design Icons 6","text":"

    Browse available icons at https://materialdesignicons.com/ (note that the search defaults to v7, see changes from v6 in the changelog)

    pip install fonticon-materialdesignicons6\n
    "},{"location":"utilities/fonticon/#see-also","title":"See also","text":"
    • https://github.com/tlambert03/fonticon-bootstrapicons
    • https://github.com/tlambert03/fonticon-linearicons
    • https://github.com/tlambert03/fonticon-feather

    superqt.fonticon is a pluggable system, and font icon packs may use the \"superqt.fonticon\" entry point to register themselves with superqt. See fonticon-cookiecutter for a template, or look through the following repos for examples:

    • https://github.com/tlambert03/fonticon-fontawesome6
    • https://github.com/tlambert03/fonticon-fontawesome5
    • https://github.com/tlambert03/fonticon-materialdesignicons6
    "},{"location":"utilities/fonticon/#api","title":"API","text":"

    options: heading_level: 3

    options: heading_level: 3

    options: heading_level: 3

    options: heading_level: 3

    options: heading_level: 3

    "},{"location":"utilities/fonticon/#superqt.fonticon.icon","title":"superqt.fonticon.icon(glyph_key, scale_factor=DEFAULT_SCALING_FACTOR, color=None, opacity=1, animation=None, transform=None, states=None)","text":"

    Create a QIcon for glyph_key, with a number of optional settings.

    The glyph_key (e.g. 'fa5s.smile') represents a Font-family & style, and a glyph. In most cases, the key should be provided by a plugin in the environment, like:

    • fonticon-fontawesome5 ('fa5s' & 'fa5r' prefixes)
    • fonticon-materialdesignicons6 ('mdi6' prefix)

    ...but fonts can also be added manually using addFont.

    Parameters:

    Name Type Description Default glyph_key str

    String encapsulating a font-family, style, and glyph. e.g. 'fa5s.smile'.

    required scale_factor float

    Scale factor (fraction of widget height), When widget icon is painted on widget, it will use font.setPixelSize(round(wdg.height() * scale_factor)). by default 0.875.

    DEFAULT_SCALING_FACTOR color ValidColor

    Color for the font, by default None. (e.g. The default QColor) Valid color types include QColor, int, str, Qt.GlobalColor, tuple (of integer: RGB[A]) (anything that can be passed to QColor).

    None opacity float

    Opacity of icon, by default 1

    1 animation Animation

    Animation for the icon. A subclass of superqt.fonticon.Animation, that provides a concrete animate method. (see \"spin\" and \"pulse\" for examples). by default None.

    None transform QTransform

    A QTransform to apply when painting the icon, by default None

    None states dict

    Provide additional styling for the icon in different states. states must be a mapping of string to dict, where:

    • the key represents a QIcon.State (\"on\", \"off\"), a QIcon.Mode (\"normal\", \"active\", \"selected\", \"disabled\"), or any combination of a state & mode separated by an underscore (e.g. \"off_active\", \"selected_on\", etc...).
    • the value is a dict with all of the same key/value meanings listed above as parameters to this function (e.g. glyph_key, color,scale_factor, animation, etc...)

    Missing keys in the state dicts will be taken from the default options, provided by the parameters above.

    None

    Returns:

    Type Description QFontIcon

    A subclass of QIcon. Can be used wherever QIcons are used, such as widget.setIcon()

    Examples:

    simple example (using the string 'fa5s.smile' assumes the fonticon-fontawesome5 plugin is installed)

    >>> btn = QPushButton()\n>>> btn.setIcon(icon(\"fa5s.smile\"))\n

    can also directly import from fonticon_fa5

    >>> from fonticon_fa5 import FA5S\n>>> btn.setIcon(icon(FA5S.smile))\n

    with animation

    >>> btn2 = QPushButton()\n>>> btn2.setIcon(icon(FA5S.spinner, animation=pulse(btn2)))\n

    complicated example

    >>> btn = QPushButton()\n>>> btn.setIcon(\n...     icon(\n...         FA5S.ambulance,\n...         color=\"blue\",\n...         states={\n...             \"active\": {\n...                 \"glyph\": FA5S.bath,\n...                 \"color\": \"red\",\n...                 \"scale_factor\": 0.5,\n...                 \"animation\": pulse(btn),\n...             },\n...             \"disabled\": {\n...                 \"color\": \"green\",\n...                 \"scale_factor\": 0.8,\n...                 \"animation\": spin(btn),\n...             },\n...         },\n...     )\n... )\n>>> btn.setIconSize(QSize(256, 256))\n>>> btn.show()\n
    "},{"location":"utilities/fonticon/#superqt.fonticon.setTextIcon","title":"superqt.fonticon.setTextIcon(widget, glyph_key, size=None)","text":"

    Set text on a widget to a specific font & glyph.

    This is an alternative to setting a QIcon with a pixmap. It may be easier to combine with dynamic stylesheets.

    Parameters:

    Name Type Description Default widget QWidget

    A widget supporting a setText method.

    required glyph_key str

    String encapsulating a font-family, style, and glyph. e.g. 'fa5s.smile'.

    required size int

    Size for QFont. passed to setPixelSize, by default None

    None"},{"location":"utilities/fonticon/#superqt.fonticon.font","title":"superqt.fonticon.font(font_prefix, size=None)","text":"

    Create QFont for font_prefix.

    Parameters:

    Name Type Description Default font_prefix str

    Font_prefix, such as 'fa5s' or 'mdi6', representing a font-family and style.

    required size int

    Size for QFont. passed to setPixelSize, by default None

    None

    Returns:

    Type Description QFont

    QFont instance that can be used to add fonticons to widgets.

    "},{"location":"utilities/fonticon/#superqt.fonticon.IconOpts","title":"superqt.fonticon.IconOpts dataclass","text":"

    Options for rendering an icon.

    Parameters:

    Name Type Description Default glyph_key str

    The key of the glyph to use, e.g. 'fa5s.smile', by default None

    _Unset scale_factor float

    The scale factor to use, by default None

    _Unset color ValidColor

    The color to use, by default None. Colors may be specified as a string, QColor, Qt.GlobalColor, or a 3 or 4-tuple of integers.

    _Unset opacity float

    The opacity to use, by default None

    _Unset animation Animation

    The animation to use, by default None

    _Unset"},{"location":"utilities/fonticon/#superqt.fonticon.addFont","title":"superqt.fonticon.addFont(filepath, prefix, charmap=None)","text":"

    Add OTF/TTF file at filepath to the registry under prefix.

    If you'd like to later use a fontkey in the form of prefix.some-name, then charmap must be provided and provide a mapping for all of the glyph names to their unicode numbers. If a charmap is not provided, glyphs must be directly accessed with their unicode as something like key.\uffff.

    Note

    in most cases, users will not need this. Instead, they should install a font plugin, like:

    • fonticon-fontawesome5
    • fonticon-materialdesignicons6

    Parameters:

    Name Type Description Default filepath str

    Path to an OTF or TTF file containing the fonts

    required prefix str

    A prefix that will represent this font file when used for lookup. For example, 'fa5s' for 'Font-Awesome 5 Solid'.

    required charmap Dict[str, str]

    optional mapping for all of the glyph names to their unicode numbers. See note above.

    None

    Returns:

    Type Description (Tuple[str, str], optional)

    font-family and font-style for the file just registered, or None if something goes wrong.

    "},{"location":"utilities/fonticon/#animations","title":"Animations","text":"

    the animation parameter to icon() accepts a subclass of Animation that will be

    options: heading_level: 3

    options: heading_level: 3

    options: heading_level: 3

    "},{"location":"utilities/fonticon/#superqt.fonticon.Animation","title":"superqt.fonticon.Animation","text":"

    Bases: ABC

    Base icon animation class.

    "},{"location":"utilities/fonticon/#superqt.fonticon.Animation.animate","title":"animate(painter) abstractmethod","text":"

    Setup and start the timer for the animation.

    "},{"location":"utilities/fonticon/#superqt.fonticon.pulse","title":"superqt.fonticon.pulse","text":"

    Bases: spin

    Animation that spins an icon in slower, discrete steps.

    "},{"location":"utilities/fonticon/#superqt.fonticon.spin","title":"superqt.fonticon.spin","text":"

    Bases: Animation

    Animation that smoothly spins an icon.

    "},{"location":"utilities/qmessagehandler/","title":"QMessageHandler","text":""},{"location":"utilities/qmessagehandler/#superqt.utils.QMessageHandler","title":"superqt.utils.QMessageHandler","text":"

    A context manager to intercept messages from Qt.

    Parameters:

    Name Type Description Default logger Logger

    If provided, intercepted messages will be logged with logger at the corresponding python log level, by default None

    None

    Attributes:

    Name Type Description records list of tuple

    Captured messages. This is a 3-tuple of: (log_level: int, message: str, context: dict)

    Examples:

    >>> handler = QMessageHandler()\n>>> handler.install()  # now all Qt output will be available at mh.records\n
    >>> with QMessageHandler() as handler:  # temporarily install\n...     ...\n
    >>> logger = logging.getLogger(__name__)\n>>> with QMessageHandler(logger):  # re-reoute Qt messages to a python logger.\n...     ...\n
    "},{"location":"utilities/qmessagehandler/#superqt.utils.QMessageHandler.__enter__","title":"__enter__()","text":"

    Enter a context with this handler installed.

    "},{"location":"utilities/qmessagehandler/#superqt.utils.QMessageHandler.install","title":"install()","text":"

    Install this handler (override the current QtMessageHandler).

    "},{"location":"utilities/qmessagehandler/#superqt.utils.QMessageHandler.uninstall","title":"uninstall()","text":"

    Uninstall this handler, restoring the previous handler.

    "},{"location":"utilities/signal_utils/","title":"Signal Utilities","text":""},{"location":"utilities/signal_utils/#superqt.utils.signals_blocked","title":"superqt.utils.signals_blocked(obj)","text":"

    Context manager to temporarily block signals emitted by QObject: obj.

    Parameters:

    Name Type Description Default obj QObject

    The QObject whose signals should be blocked.

    required

    Examples:

    from qtpy.QtWidgets import QSpinBox\nfrom superqt import signals_blocked\n\nspinbox = QSpinBox()\nwith signals_blocked(spinbox):\n    spinbox.setValue(10)\n
    "},{"location":"utilities/thread_decorators/","title":"Threading decorators","text":"

    superqt provides two decorators that help to ensure that given function is running in the desired thread:

    "},{"location":"utilities/thread_decorators/#ensure_main_thread","title":"ensure_main_thread","text":"

    ensure_main_thread ensures that the decorated function/method runs in the main thread

    "},{"location":"utilities/thread_decorators/#ensure_object_thread","title":"ensure_object_thread","text":"

    ensure_object_thread ensures that a decorated bound method of a QObject runs in the thread in which the instance lives (see qt documentation for details).

    "},{"location":"utilities/thread_decorators/#usage","title":"Usage","text":"

    By default, functions are executed asynchronously (they return immediately with an instance of concurrent.futures.Future).

    To block and wait for the result, see Synchronous mode

    from qtpy.QtCore import QObject\nfrom superqt import ensure_main_thread, ensure_object_thread\n\n@ensure_main_thread\ndef sample_function():\n    print(\"This function will run in main thread\")\n\n\nclass SampleObject(QObject):\n    def __init__(self):\n        super().__init__()\n        self._value = 1\n\n    @ensure_main_thread\n    def sample_method1(self):\n        print(\"This method will run in main thread\")\n\n    @ensure_object_thread\n    def sample_method3(self):\n        import time\n        print(\"sleeping\")\n        time.sleep(1)\n        print(\"This method will run in object thread\")\n\n    @property\n    def value(self):\n        print(\"return value\")\n        return self._value\n\n    @value.setter\n    @ensure_object_thread\n    def value(self, value):\n        print(\"this setter will run in object thread\")\n        self._value = value\n

    As can be seen in this example these decorators can also be used for setters.

    These decorators should not be used as replacement of Qt Signals but rather to interact with Qt objects from non Qt code.

    "},{"location":"utilities/thread_decorators/#synchronous-mode","title":"Synchronous mode","text":"

    If you'd like for the program to block and wait for the result of your function call, use the await_return=True parameter, and optionally specify a timeout.

    Important

    Using synchronous mode may significantly impact performance.

    from superqt import ensure_main_thread\n\n@ensure_main_thread\ndef sample_function1():\n    return 1\n\n@ensure_main_thread(await_return=True)\ndef sample_function2():\n    return 2\n\nassert sample_function1() is None\nassert sample_function2() == 2\n\n# optionally, specify a timeout\n@ensure_main_thread(await_return=True, timeout=10000)\ndef sample_function():\n    return 1\n
    "},{"location":"utilities/threading/","title":"Thread workers","text":"

    The objects in this module provide utilities for running tasks in a separate thread. In general (with the exception of new_worker_qthread), everything here wraps Qt's QRunnable API.

    The highest level object is the @thread_worker decorator. It was originally written for napari, and was later extracted into superqt. You may also be interested in reading the napari documentation on this feature, which provides a more in-depth/introductory usage guide.

    For additional control, you can create your own FunctionWorker or GeneratorWorker objects.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase","title":"superqt.utils.WorkerBase","text":"

    Bases: QRunnable, Generic[_R]

    Base class for creating a Worker that can run in another thread.

    Parameters:

    Name Type Description Default SignalsClass type

    A QObject subclass that contains signals, by default WorkerBaseSignals

    WorkerBaseSignals

    Attributes:

    Name Type Description signals WorkerBaseSignals

    signal emitter object. To allow identify which worker thread emitted signal.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.abort_requested","title":"abort_requested property","text":"

    Whether the worker has been requested to stop.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.is_running","title":"is_running property","text":"

    Whether the worker has been started.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.__getattr__","title":"__getattr__(name)","text":"

    Pass through attr requests to signals to simplify connection API.

    The goal is to enable worker.yielded.connect instead of worker.signals.yielded.connect. Because multiple inheritance of Qt classes is not well supported in PyQt, we have to use composition here (signals are provided by QObjects, and QRunnable is not a QObject). So this passthrough allows us to connect to signals on the _signals object.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.await_workers","title":"await_workers(msecs=None) classmethod","text":"

    Ask all workers to quit, and wait up to msec for quit.

    Attempts to clean up all running workers by calling worker.quit() method. Any workers in the WorkerBase._worker_set set will have this method.

    By default, this function will block indefinitely, until worker threads finish. If a timeout is provided, a RuntimeError will be raised if the workers do not gracefully exit in the time requests, but the threads will NOT be killed. It is (currently) left to the user to use their OS to force-quit rogue threads.

    Important

    If the user does not put any yields in their function, and the function is super long, it will just hang... For instance, there's no graceful way to kill this thread in python:

    @thread_worker\ndef ZZZzzz():\n    time.sleep(10000000)\n

    This is why it's always advisable to use a generator that periodically yields for long-running computations in another thread.

    See this stack-overflow post for a good discussion on the difficulty of killing a rogue python thread:

    Parameters:

    Name Type Description Default msecs int

    Waits up to msecs milliseconds for all threads to exit and removes all threads from the thread pool. If msecs is None (the default), the timeout is ignored (waits for the last thread to exit).

    None

    Raises:

    Type Description RuntimeError

    If a timeout is provided and workers do not quit successfully within the time allotted.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.quit","title":"quit()","text":"

    Send a request to abort the worker.

    Note

    It is entirely up to subclasses to honor this method by checking self.abort_requested periodically in their worker.work method, and exiting if True.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.run","title":"run()","text":"

    Start the worker.

    The end-user should never need to call this function. But it cannot be made private or renamed, since it is called by Qt.

    The order of method calls when starting a worker is:

       calls QThreadPool.globalInstance().start(worker)\n   |               triggered by the QThreadPool.start() method\n   |               |             called by worker.run\n   |               |             |\n   V               V             V\n   worker.start -> worker.run -> worker.work\n

    This is the function that actually gets called when calling QThreadPool.start(worker). It simply wraps the work() method, and emits a few signals. Subclasses should NOT override this method (except with good reason), and instead should implement work().

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.start","title":"start()","text":"

    Start this worker in a thread and add it to the global threadpool.

    The order of method calls when starting a worker is:

       calls QThreadPool.globalInstance().start(worker)\n   |               triggered by the QThreadPool.start() method\n   |               |             called by worker.run\n   |               |             |\n   V               V             V\n   worker.start -> worker.run -> worker.work\n
    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.work","title":"work()","text":"

    Main method to execute the worker.

    The end-user should never need to call this function. But subclasses must implement this method (See GeneratorFunction.work for an example implementation). Minimally, it should check self.abort_requested periodically and exit if True.

    Examples:

    class MyWorker(WorkerBase):\n    def work(self):\n        i = 0\n        while True:\n            if self.abort_requested:\n                self.aborted.emit()\n                break\n            i += 1\n            if i > max_iters:\n                break\n            time.sleep(0.5)\n
    "},{"location":"utilities/threading/#superqt.utils.FunctionWorker","title":"superqt.utils.FunctionWorker","text":"

    Bases: WorkerBase[_R]

    QRunnable with signals that wraps a simple long-running function.

    Note

    FunctionWorker does not provide a way to stop a very long-running function (e.g. time.sleep(10000)). So whenever possible, it is better to implement your long running function as a generator that yields periodically, and use the GeneratorWorker instead.

    Parameters:

    Name Type Description Default func Callable

    A function to call in another thread

    required *args

    will be passed to the function

    () **kwargs

    will be passed to the function

    {}

    Raises:

    Type Description TypeError

    If func is a generator function and not a regular function.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker","title":"superqt.utils.GeneratorWorker","text":"

    Bases: WorkerBase, Generic[_Y, _S, _R]

    QRunnable with signals that wraps a long-running generator.

    Provides a convenient way to run a generator function in another thread, while allowing 2-way communication between threads, using plain-python generator syntax in the original function.

    Parameters:

    Name Type Description Default func callable

    The function being run in another thread. May be a generator function.

    required SignalsClass type

    A QObject subclass that contains signals, by default GeneratorWorkerSignals

    GeneratorWorkerSignals *args

    Will be passed to func on instantiation

    () **kwargs

    Will be passed to func on instantiation

    {}"},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.is_paused","title":"is_paused property","text":"

    Whether the worker is currently paused.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.pause","title":"pause()","text":"

    Request to pause the worker.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.resume","title":"resume()","text":"

    Send a request to resume the worker.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.send","title":"send(value)","text":"

    Send a value into the function (if a generator was used).

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.toggle_pause","title":"toggle_pause()","text":"

    Request to pause the worker if playing or resume if paused.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.work","title":"work()","text":"

    Core event loop that calls the original function.

    Enters a continual loop, yielding and returning from the original function. Checks for various events (quit, pause, resume, etc...). (To clarify: we are creating a rudimentary event loop here because there IS NO Qt event loop running in the other thread to hook into)

    "},{"location":"utilities/threading/#convenience-functions","title":"Convenience functions","text":""},{"location":"utilities/threading/#superqt.utils.thread_worker","title":"superqt.utils.thread_worker(function=None, start_thread=None, connect=None, worker_class=None, ignore_errors=False)","text":"
    thread_worker(\n    function: Callable[_P, Generator[_Y, _S, _R]],\n    start_thread: bool | None = None,\n    connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    worker_class: type[WorkerBase] | None = None,\n    ignore_errors: bool = False,\n) -> Callable[_P, GeneratorWorker[_Y, _S, _R]]\n
    thread_worker(\n    function: Callable[_P, _R],\n    start_thread: bool | None = None,\n    connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    worker_class: type[WorkerBase] | None = None,\n    ignore_errors: bool = False,\n) -> Callable[_P, FunctionWorker[_R]]\n
    thread_worker(\n    function: Literal[None] = None,\n    start_thread: bool | None = None,\n    connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    worker_class: type[WorkerBase] | None = None,\n    ignore_errors: bool = False,\n) -> Callable[\n    [Callable],\n    Callable[_P, FunctionWorker | GeneratorWorker],\n]\n

    Decorator that runs a function in a separate thread when called.

    When called, the decorated function returns a WorkerBase. See create_worker for additional keyword arguments that can be used when calling the function.

    The returned worker will have these signals:

    • started: emitted when the work is started
    • finished: emitted when the work is finished
    • returned: emitted with return value
    • errored: emitted with error object on Exception

    It will also have a worker.start() method that can be used to start execution of the function in another thread. (useful if you need to connect callbacks to signals prior to execution)

    If the decorated function is a generator, the returned worker will also provide these signals:

    • yielded: emitted with yielded values
    • paused: emitted when a running job has successfully paused
    • resumed: emitted when a paused job has successfully resumed
    • aborted: emitted when a running job is successfully aborted

    And these methods:

    • quit: ask the thread to quit
    • toggle_paused: toggle the running state of the thread.
    • send: send a value into the generator. (This requires that your decorator function uses the value = yield syntax)

    Parameters:

    Name Type Description Default function callable

    Function to call in another thread. For communication between threads may be a generator function.

    None start_thread bool

    Whether to immediaetly start the thread. If False, the returned worker must be manually started with worker.start(). by default it will be False if the _connect argument is None, otherwise True.

    None connect Dict[str, Union[Callable, Sequence]]

    A mapping of \"signal_name\" -> callable or list of callable: callback functions to connect to the various signals offered by the worker class. by default None

    None worker_class Type[WorkerBase]

    The WorkerBase to instantiate, by default FunctionWorker will be used if func is a regular function, and GeneratorWorker will be used if it is a generator.

    None ignore_errors bool

    If False (the default), errors raised in the other thread will be reraised in the main thread (makes debugging significantly easier).

    False

    Returns:

    Type Description callable

    function that creates a worker, puts it in a new thread and returns the worker instance.

    Examples:

    @thread_worker\ndef long_function(start, end):\n    # do work, periodically yielding\n    i = start\n    while i <= end:\n        time.sleep(0.1)\n        yield i\n\n    # do teardown\n    return \"anything\"\n\n\n# call the function to start running in another thread.\nworker = long_function()\n\n# connect signals here if desired... or they may be added using the\n# `connect` argument in the `@thread_worker` decorator... in which\n# case the worker will start immediately when long_function() is called\nworker.start()\n
    "},{"location":"utilities/threading/#superqt.utils.create_worker","title":"superqt.utils.create_worker(func, *args, _start_thread=None, _connect=None, _worker_class=None, _ignore_errors=False, **kwargs)","text":"
    create_worker(\n    func: Callable[_P, Generator[_Y, _S, _R]],\n    *args,\n    _start_thread: bool | None = None,\n    _connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    _worker_class: type[GeneratorWorker]\n    | type[FunctionWorker]\n    | None = None,\n    _ignore_errors: bool = False,\n    **kwargs,\n) -> GeneratorWorker[_Y, _S, _R]\n
    create_worker(\n    func: Callable[_P, _R],\n    *args,\n    _start_thread: bool | None = None,\n    _connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    _worker_class: type[GeneratorWorker]\n    | type[FunctionWorker]\n    | None = None,\n    _ignore_errors: bool = False,\n    **kwargs,\n) -> FunctionWorker[_R]\n

    Convenience function to start a function in another thread.

    By default, uses FunctionWorker for functions and GeneratorWorker for generators, but a custom WorkerBase subclass may be provided. If so, it must be a subclass of WorkerBase, which defines a standard set of signals and a run method.

    Parameters:

    Name Type Description Default func Callable

    The function to call in another thread.

    required _start_thread bool

    Whether to immediaetly start the thread. If False, the returned worker must be manually started with worker.start(). by default it will be False if the _connect argument is None, otherwise True.

    None _connect Dict[str, Union[Callable, Sequence]]

    A mapping of \"signal_name\" -> callable or list of callable: callback functions to connect to the various signals offered by the worker class. by default None

    None _worker_class type of `GeneratorWorker` or `FunctionWorker`

    The WorkerBase to instantiate, by default FunctionWorker will be used if func is a regular function, and GeneratorWorker will be used if it is a generator.

    None _ignore_errors bool

    If False (the default), errors raised in the other thread will be reraised in the main thread (makes debugging significantly easier).

    False *args

    will be passed to func

    () **kwargs

    will be passed to func

    {}

    Returns:

    Name Type Description worker WorkerBase

    An instantiated worker. If _start_thread was False, the worker will have a .start() method that can be used to start the thread.

    Raises:

    Type Description TypeError

    If a worker_class is provided that is not a subclass of WorkerBase.

    TypeError

    If _connect is provided and is not a dict of {str: callable}

    Examples:

    def long_function(duration):\n    import time\n\n    time.sleep(duration)\n\n\nworker = create_worker(long_function, 10)\n
    "},{"location":"utilities/threading/#superqt.utils.new_worker_qthread","title":"superqt.utils.new_worker_qthread(Worker, *args, _start_thread=False, _connect=None, **kwargs)","text":"

    Convenience function to start a worker in a QThread.

    thread, not as the actual code or object that runs in that thread. The QThread object is created on the main thread and lives there.

    Worker objects which derive from QObject are the things that actually do the work. They can be moved to a QThread as is done here.

    Mostly ignorable detail

    While the signals/slots syntax of the worker looks very similar to standard \"single-threaded\" signals & slots, note that inter-thread signals and slots (automatically) use an event-based QueuedConnection, while intra-thread signals use a DirectConnection. See Signals and Slots Across Threads

    Parameters:

    Name Type Description Default Worker QObject

    QObject type that implements a work() method. The Worker should also emit a finished signal when the work is done.

    required _start_thread bool

    If True, thread will be started immediately, otherwise, thread must be manually started with thread.start().

    False _connect dict

    Optional dictionary of {signal: function} to connect to the new worker. for instance: _connect = {'incremented': myfunc} will result in: worker.incremented.connect(myfunc)

    None *args

    will be passed to the Worker class on instantiation.

    () **kwargs

    will be passed to the Worker class on instantiation.

    {}

    Returns:

    Name Type Description worker WorkerBase

    The created worker.

    thread QThread

    The thread on which the worker is running.

    Examples:

    Create some QObject that has a long-running work method:

    class Worker(QObject):\n    finished = Signal()\n    increment = Signal(int)\n\n    def __init__(self, argument):\n        super().__init__()\n        self.argument = argument\n\n    @Slot()\n    def work(self):\n        # some long running task...\n        import time\n\n        for i in range(10):\n            time.sleep(1)\n            self.increment.emit(i)\n        self.finished.emit()\n\n\nworker, thread = new_worker_qthread(\n    Worker,\n    \"argument\",\n    _start_thread=True,\n    _connect={\"increment\": print},\n)\n
    "},{"location":"utilities/throttling/","title":"Throttling & Debouncing","text":"

    These utilities allow you to throttle or debounce a function. This is useful when you have a function that is called multiple times in a short period of time, and you want to make sure it is only \"actually\" called once (or at least no more than a certain frequency).

    For background on throttling and debouncing, see:

    • https://blog.openreplay.com/forever-functional-debouncing-and-throttling-for-performance
    • https://css-tricks.com/debouncing-throttling-explained-examples/
    "},{"location":"utilities/throttling/#superqt.utils.qdebounced","title":"superqt.utils.qdebounced(func=None, timeout=100, leading=False, timer_type=Qt.TimerType.PreciseTimer, parent=None)","text":"
    qdebounced(\n    func: Callable[P, R],\n    timeout: int = 100,\n    leading: bool = False,\n    timer_type: Qt.TimerType = Qt.TimerType.PreciseTimer,\n    parent: QObject | None = None,\n) -> ThrottledCallable[P, R]\n
    qdebounced(\n    func: None = ...,\n    timeout: int = 100,\n    leading: bool = False,\n    timer_type: Qt.TimerType = Qt.TimerType.PreciseTimer,\n    parent: QObject | None = None,\n) -> Callable[[Callable[P, R]], ThrottledCallable[P, R]]\n

    Creates a debounced function that delays invoking func.

    func will not be invoked until timeout ms have elapsed since the last time the debounced function was invoked.

    The debounced function comes with a cancel method to cancel delayed func invocations and a flush method to immediately invoke them. Options indicate whether func should be invoked on the leading and/or trailing edge of the wait timeout. The func is invoked with the last arguments provided to the debounced function. Subsequent calls to the debounced function return the result of the last func invocation.

    This decorator may be used with or without parameters.

    Parameters:

    Name Type Description Default func Callable

    A function to throttle

    None timeout int

    Timeout in milliseconds to wait before allowing another call, by default 100

    100 leading bool

    Whether to invoke the function on the leading edge of the wait timer, by default False

    False timer_type TimerType

    The timer type. by default Qt.TimerType.PreciseTimer One of: - Qt.PreciseTimer: Precise timers try to keep millisecond accuracy - Qt.CoarseTimer: Coarse timers try to keep accuracy within 5% of the desired interval - Qt.VeryCoarseTimer: Very coarse timers only keep full second accuracy

    PreciseTimer parent QObject | None

    Parent object for timer. If using qthrottled as function it may be usefull for cleaning data

    None"},{"location":"utilities/throttling/#superqt.utils.qthrottled","title":"superqt.utils.qthrottled(func=None, timeout=100, leading=True, timer_type=Qt.TimerType.PreciseTimer, parent=None)","text":"
    qthrottled(\n    func: Callable[P, R],\n    timeout: int = 100,\n    leading: bool = True,\n    timer_type: Qt.TimerType = Qt.TimerType.PreciseTimer,\n    parent: QObject | None = None,\n) -> ThrottledCallable[P, R]\n
    qthrottled(\n    func: None = ...,\n    timeout: int = 100,\n    leading: bool = True,\n    timer_type: Qt.TimerType = Qt.TimerType.PreciseTimer,\n    parent: QObject | None = None,\n) -> Callable[[Callable[P, R]], ThrottledCallable[P, R]]\n

    Creates a throttled function that invokes func at most once per timeout.

    The throttled function comes with a cancel method to cancel delayed func invocations and a flush method to immediately invoke them. Options to indicate whether func should be invoked on the leading and/or trailing edge of the wait timeout. The func is invoked with the last arguments provided to the throttled function. Subsequent calls to the throttled function return the result of the last func invocation.

    This decorator may be used with or without parameters.

    Parameters:

    Name Type Description Default func Callable

    A function to throttle

    None timeout int

    Timeout in milliseconds to wait before allowing another call, by default 100

    100 leading bool

    Whether to invoke the function on the leading edge of the wait timer, by default True

    True timer_type TimerType

    The timer type. by default Qt.TimerType.PreciseTimer One of: - Qt.PreciseTimer: Precise timers try to keep millisecond accuracy - Qt.CoarseTimer: Coarse timers try to keep accuracy within 5% of the desired interval - Qt.VeryCoarseTimer: Very coarse timers only keep full second accuracy

    PreciseTimer parent QObject | None

    Parent object for timer. If using qthrottled as function it may be usefull for cleaning data

    None"},{"location":"utilities/throttling/#superqt.utils.QSignalDebouncer","title":"superqt.utils.QSignalDebouncer","text":"

    Bases: GenericSignalThrottler

    A Signal Debouncer.

    This object's triggered signal will not be emitted until self.timeout() milliseconds have elapsed since the last time triggered was emitted.

    "},{"location":"utilities/throttling/#superqt.utils.QSignalThrottler","title":"superqt.utils.QSignalThrottler","text":"

    Bases: GenericSignalThrottler

    A Signal Throttler.

    This object's triggered signal will emit at most once per timeout (set with setTimeout()).

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler","title":"superqt.utils._throttler.GenericSignalThrottler","text":"

    Bases: QObject

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.cancel","title":"cancel()","text":"

    Cancel any pending emissions.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.emissionPolicy","title":"emissionPolicy()","text":"

    Return the emission policy (trailing or leading).

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.flush","title":"flush(restart_timer=True)","text":"

    Force emission of any pending emissions.

    Parameters:

    Name Type Description Default restart_timer bool

    Whether to restart the timer after flushing. Defaults to True.

    True"},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.kind","title":"kind()","text":"

    Return the kind of throttler (throttler or debouncer).

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.setTimeout","title":"setTimeout(timeout)","text":"

    Set timeout in milliseconds.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.setTimerType","title":"setTimerType(timerType)","text":"

    Set current Qt.TimerType.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.throttle","title":"throttle()","text":"

    Emit triggered if not running, then start timer.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.timeout","title":"timeout()","text":"

    Return current timeout in milliseconds.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.timerType","title":"timerType()","text":"

    Return current Qt.TimerType.

    "},{"location":"widgets/","title":"Widgets","text":"

    The following are QWidget subclasses:

    "},{"location":"widgets/#sliders-and-numerical-inputs","title":"Sliders and Numerical Inputs","text":"Widget Description QDoubleRangeSlider Multi-handle slider for float values QDoubleSlider Slider for float values QLabeledDoubleRangeSlider QDoubleRangeSlider variant with editable labels for each handle QLabeledDoubleSlider QSlider for float values with editable QSpinBox with the current value QLabeledRangeSlider QRangeSlider variant, with editable labels for each handle QLabeledSlider QSlider with editable QSpinBox that shows the current value QLargeIntSpinBox QSpinbox that accepts arbitrarily large integers QRangeSlider Multi-handle slider QQuantity Pint-backed quantity widget (magnitude combined with unit dropdown)"},{"location":"widgets/#labels-and-categorical-inputs","title":"Labels and categorical inputs","text":"Widget Description QElidingLabel A QLabel variant that will elide text (add \u2026) to fit width. QEnumComboBox QComboBox that populates the combobox from a python Enum QSearchableComboBox QComboBox variant that filters available options based on text input QSearchableListWidget QListWidget variant with search field that filters available options QSearchableTreeWidget QTreeWidget variant with search field that filters available options QColorComboBox QComboBox to select from a specified set of colors QColormapComboBox QComboBox to select from a specified set of colormaps."},{"location":"widgets/#frames-and-containers","title":"Frames and containers","text":"Widget Description QCollapsible A collapsible widget to hide and unhide child widgets. QFlowLayout A layout that rearranges items based on parent width."},{"location":"widgets/colormap_catalog/","title":"CmapCatalogComboBox","text":"

    Searchable QComboBox variant that contains the entire cmap colormap catalog

    requires cmap

    This widget uses the cmap library to provide colormaps. You can install it with:

    # use the `cmap` extra to include colormap support\npip install superqt[cmap]\n

    You can limit the colormaps shown by setting the categories or interpolation keyword arguments.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt.cmap import CmapCatalogComboBox\n\napp = QApplication([])\n\ncatalog_combo = CmapCatalogComboBox(interpolation=\"linear\")\ncatalog_combo.setCurrentText(\"viridis\")\ncatalog_combo.show()\n\napp.exec()\n

    "},{"location":"widgets/colormap_catalog/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/colormap_catalog/#signals","title":"Signals","text":""},{"location":"widgets/colormap_catalog/#currentcolormapchanged","title":"currentColormapChanged","text":""},{"location":"widgets/colormap_catalog/#methods","title":"Methods","text":"

    A combo box for selecting a colormap from the entire cmap catalog.

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget.

    None prefer_short_names bool

    If True (default), short names (without the namespace prefix) will be preferred over fully qualified names. In cases where the same short name is used in multiple namespaces, they will all be referred to by their fully qualified (namespaced) name.

    True categories Container[Category]

    If provided, only return names from the given categories.

    () interpolation Interpolation

    If provided, only return names that have the given interpolation method.

    None"},{"location":"widgets/colormap_catalog/#superqt.cmap.CmapCatalogComboBox.currentColormap","title":"currentColormap() -> Colormap | None","text":"

    Returns the currently selected Colormap or None if not yet selected.

    "},{"location":"widgets/qcollapsible/","title":"QCollapsible","text":"

    Collapsible QFrame that can be expanded or collapsed by clicking on the header.

    from qtpy.QtWidgets import QApplication, QLabel, QPushButton\n\nfrom superqt import QCollapsible\n\napp = QApplication([])\n\ncollapsible = QCollapsible(\"Advanced analysis\")\ncollapsible.addWidget(QLabel(\"This is the inside of the collapsible frame\"))\nfor i in range(10):\n    collapsible.addWidget(QPushButton(f\"Content button {i + 1}\"))\n\ncollapsible.expand(animate=False)\ncollapsible.show()\napp.exec_()\n

    "},{"location":"widgets/qcollapsible/#qt-class","title":"Qt Class","text":"

    QFrame

    "},{"location":"widgets/qcollapsible/#signals","title":"Signals","text":""},{"location":"widgets/qcollapsible/#toggled","title":"toggled","text":""},{"location":"widgets/qcollapsible/#methods","title":"Methods","text":"

    A collapsible widget to hide and unhide child widgets.

    A signal is emitted when the widget is expanded (True) or collapsed (False).

    Based on https://stackoverflow.com/a/68141638

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.addWidget","title":"addWidget(widget: QWidget) -> None","text":"

    Add a widget to the central content widget's layout.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.collapse","title":"collapse(animate: bool = True) -> None","text":"

    Collapse (hide) the collapsible section.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.collapsedIcon","title":"collapsedIcon() -> QIcon","text":"

    Returns the icon used when the widget is collapsed.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.content","title":"content() -> QWidget","text":"

    Return the current content widget.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.expand","title":"expand(animate: bool = True) -> None","text":"

    Expand (show) the collapsible section.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.expandedIcon","title":"expandedIcon() -> QIcon","text":"

    Returns the icon used when the widget is expanded.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.isExpanded","title":"isExpanded() -> bool","text":"

    Return whether the collapsible section is visible.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.locked","title":"locked() -> bool","text":"

    Return True if collapse/expand is disabled.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.removeWidget","title":"removeWidget(widget: QWidget) -> None","text":"

    Remove widget from the central content widget's layout.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setCollapsedIcon","title":"setCollapsedIcon(icon: QIcon | str | None = None) -> None","text":"

    Set the icon on the toggle button when the widget is collapsed.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setContent","title":"setContent(content: QWidget) -> None","text":"

    Replace central widget (the widget that gets expanded/collapsed).

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setDuration","title":"setDuration(msecs: int) -> None","text":"

    Set duration of the collapse/expand animation.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setEasingCurve","title":"setEasingCurve(easing: QEasingCurve | QEasingCurve.Type) -> None","text":"

    Set the easing curve for the collapse/expand animation.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setExpandedIcon","title":"setExpandedIcon(icon: QIcon | str | None = None) -> None","text":"

    Set the icon on the toggle button when the widget is expanded.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setLocked","title":"setLocked(locked: bool = True) -> None","text":"

    Set whether collapse/expand is disabled.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setText","title":"setText(text: str) -> None","text":"

    Set the text of the toggle button.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.text","title":"text() -> str","text":"

    Return the text of the toggle button.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.toggleButton","title":"toggleButton() -> QPushButton","text":"

    Return the toggle button.

    "},{"location":"widgets/qcolorcombobox/","title":"QColorComboBox","text":"

    QComboBox designed to select from a specific set of colors.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QColorComboBox\n\napp = QApplication([])\n\ncolors = QColorComboBox()\ncolors.addColors(['red', 'green', 'blue'])\n\n# show an \"Add Color\" item that opens a QColorDialog when clicked\ncolors.setUserColorsAllowed(True)\n\n# emits a QColor when changed\ncolors.currentColorChanged.connect(print)\ncolors.show()\n\napp.exec_()\n

    "},{"location":"widgets/qcolorcombobox/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/qcolorcombobox/#signals","title":"Signals","text":""},{"location":"widgets/qcolorcombobox/#currentcolorchanged","title":"currentColorChanged","text":""},{"location":"widgets/qcolorcombobox/#enums","title":"Enums","text":""},{"location":"widgets/qcolorcombobox/#qcolorcomboboxinvalidcolorpolicy","title":"QColorComboBox.InvalidColorPolicy","text":"
    • Ignore

    • Warn

    • Raise

    "},{"location":"widgets/qcolorcombobox/#methods","title":"Methods","text":"

    A drop down menu for selecting colors.

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget.

    None allow_user_colors bool

    Whether to show an \"Add Color\" item that opens a QColorDialog when clicked. Whether the user can add custom colors by clicking the \"Add Color\" item. Default is False. Can also be set with setUserColorsAllowed.

    False add_color_text str

    The text to display for the \"Add Color\" item. Default is \"Add Color...\".

    'Add Color...'"},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.addColor","title":"addColor(color: Any) -> None","text":"

    Adds the color to the QComboBox.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.addColors","title":"addColors(colors: Sequence[Any]) -> None","text":"

    Adds colors to the QComboBox.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.currentColor","title":"currentColor() -> QColor | None","text":"

    Returns the currently selected QColor or None if not yet selected.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.currentColorName","title":"currentColorName() -> str | None","text":"

    Returns the name of the currently selected QColor or black if None.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.invalidColorPolicy","title":"invalidColorPolicy() -> InvalidColorPolicy","text":"

    Returns the policy for handling invalid colors.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.itemColor","title":"itemColor(index: int) -> QColor | None","text":"

    Returns the color of the item at the given index.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.setCurrentColor","title":"setCurrentColor(color: Any) -> None","text":"

    Adds the color to the QComboBox and selects it.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.setInvalidColorPolicy","title":"setInvalidColorPolicy(policy: InvalidColorPolicy | int | Literal['Raise', 'Ignore', 'Warn']) -> None","text":"

    Sets the policy for handling invalid colors.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.setUserColorsAllowed","title":"setUserColorsAllowed(allow: bool) -> None","text":"

    Sets whether the user can add custom colors.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.userColorsAllowed","title":"userColorsAllowed() -> bool","text":"

    Returns whether the user can add custom colors.

    "},{"location":"widgets/qcolormap/","title":"QColormapComboBox","text":"

    QComboBox variant to select from a specific set of colormaps.

    requires cmap

    This widget uses the cmap library to provide colormaps. You can install it with:

    # use the `cmap` extra to include colormap support\npip install superqt[cmap]\n
    "},{"location":"widgets/qcolormap/#colormaplike-objects","title":"ColorMapLike objects","text":"

    Colormaps may be specified in a variety of ways, such as by name (string), an iterable of a color/color-like objects, or as a cmap.Colormap instance. See cmap documentation for details on all ColormapLike types

    "},{"location":"widgets/qcolormap/#example","title":"Example","text":"
    from cmap import Colormap\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QColormapComboBox\n\napp = QApplication([])\n\ncmap_combo = QColormapComboBox()\n# see note above about colormap-like objects\n# as names from the cmap catalog\ncmap_combo.addColormaps([\"viridis\", \"plasma\", \"magma\", \"gray\"])\n# as a sequence of colors, linearly interpolated\ncmap_combo.addColormap((\"#0f0\", \"slateblue\", \"#F3A003A0\"))\n# as a `cmap.Colormap` instance with custom name:\ncmap_combo.addColormap(Colormap((\"green\", \"white\", \"orange\"), name=\"MyMap\"))\n\ncmap_combo.show()\napp.exec()\n
    "},{"location":"widgets/qcolormap/#style-customization","title":"Style Customization","text":"

    Note that both the LineEdit and the dropdown can be styled to have the colormap on the left, or fill the entire width of the widget.

    To make the CombBox label colormap fill the entire width of the widget:

    from superqt.cmap import QColormapLineEdit\ncmap_combo.setLineEdit(QColormapLineEdit())\n

    To make the CombBox dropdown colormaps fill less than the entire width of the widget:

    from superqt.cmap import QColormapItemDelegate\ndelegate = QColormapItemDelegate(fractional_colormap_width=0.33)\ncmap_combo.setItemDelegate(delegate)\n
    "},{"location":"widgets/qcolormap/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/qcolormap/#signals","title":"Signals","text":""},{"location":"widgets/qcolormap/#currentcolormapchanged","title":"currentColormapChanged","text":""},{"location":"widgets/qcolormap/#methods","title":"Methods","text":"

    A drop down menu for selecting colors.

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget.

    None allow_user_colormaps bool

    Whether the user can add custom colormaps by clicking the \"Add Colormap...\" item. Default is False. Can also be set with setUserAdditionsAllowed.

    False add_colormap_text str

    The text to display for the \"Add Colormap...\" item. Default is \"Add Colormap...\".

    'Add Colormap...'"},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.addColormap","title":"addColormap(cmap: ColorStopsLike) -> None","text":"

    Adds the colormap to the QComboBox.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.addColormaps","title":"addColormaps(colors: Sequence[Any]) -> None","text":"

    Adds colors to the QComboBox.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.currentColormap","title":"currentColormap() -> Colormap | None","text":"

    Returns the currently selected Colormap or None if not yet selected.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.itemColormap","title":"itemColormap(index: int) -> Colormap | None","text":"

    Returns the color of the item at the given index.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.setCurrentColormap","title":"setCurrentColormap(color: Any) -> None","text":"

    Adds the color to the QComboBox and selects it.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.setUserAdditionsAllowed","title":"setUserAdditionsAllowed(allow: bool) -> None","text":"

    Sets whether the user can add custom colors.

    If enabled, an \"Add Colormap...\" item will be added to the end of the list. When clicked, a dialog will be shown to allow the user to select a colormap from the cmap catalog.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.userAdditionsAllowed","title":"userAdditionsAllowed() -> bool","text":"

    Returns whether the user can add custom colors.

    "},{"location":"widgets/qdoublerangeslider/","title":"QDoubleRangeSlider","text":"

    Float variant of QRangeSlider. (see that page for more details).

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QDoubleRangeSlider\n\napp = QApplication([])\n\nslider = QDoubleRangeSlider(Qt.Orientation.Horizontal)\nslider.setRange(0, 1)\nslider.setValue((0.2, 0.8))\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qdoublerangeslider/#qt-class","title":"Qt Class","text":"

    QSlider

    "},{"location":"widgets/qdoublerangeslider/#methods","title":"Methods","text":""},{"location":"widgets/qdoubleslider/","title":"QDoubleSlider","text":"

    QSlider variant that accepts floating point values.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QDoubleSlider\n\napp = QApplication([])\n\nslider = QDoubleSlider(Qt.Orientation.Horizontal)\nslider.setRange(0, 1)\nslider.setValue(0.5)\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qdoubleslider/#qt-class","title":"Qt Class","text":"

    QSlider

    "},{"location":"widgets/qdoubleslider/#methods","title":"Methods","text":""},{"location":"widgets/qelidinglabel/","title":"QElidingLabel","text":"

    QLabel variant that will elide text (i.e. add an ellipsis) if it is too long to fit in the available space.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QElidingLabel\n\napp = QApplication([])\n\nwidget = QElidingLabel(\n    \"a skj skjfskfj sdlf sdfl sdlfk jsdf sdlkf jdsf dslfksdl sdlfk sdf sdl \"\n    \"fjsdlf kjsdlfk laskdfsal as lsdfjdsl kfjdslf asfd dslkjfldskf sdlkfj\"\n)\nwidget.setWordWrap(True)\nwidget.resize(300, 20)\nwidget.show()\n\napp.exec_()\n

    "},{"location":"widgets/qelidinglabel/#qt-class","title":"Qt Class","text":"

    QLabel

    "},{"location":"widgets/qelidinglabel/#methods","title":"Methods","text":"

    A QLabel variant that will elide text (could add '\u2026') to fit width.

    QElidingLabel() QElidingLabel(parent: Optional[QWidget], f: Qt.WindowFlags = ...) QElidingLabel(text: str, parent: Optional[QWidget] = None, f: Qt.WindowFlags = ...)

    For a multiline eliding label, use setWordWrap(True). In this case, text will wrap to fit the width, and only the last line will be elided. When wordWrap() is True, sizeHint() will return the size required to fit the full text.

    "},{"location":"widgets/qelidinglabel/#superqt.QElidingLabel.setElideMode","title":"setElideMode(mode: Qt.TextElideMode) -> None","text":"

    Set the elide mode to a Qt.TextElideMode.

    "},{"location":"widgets/qelidinglabel/#superqt.QElidingLabel.setEllipsesWidth","title":"setEllipsesWidth(width: int) -> None","text":"

    A width value to take into account ellipses width when eliding text.

    The value is deducted from the widget width when computing the elided version of the text.

    "},{"location":"widgets/qenumcombobox/","title":"QEnumComboBox","text":"

    QEnumComboBox is a variant of QComboBox that populates the items in the combobox based on a python Enum class. In addition to all the methods provided by QComboBox, this subclass adds the methods enumClass/setEnumClass to get/set the current Enum class represented by the combobox, and currentEnum/setCurrentEnum to get/set the current Enum member in the combobox. There is also a new signal currentEnumChanged(enum) analogous to currentIndexChanged and currentTextChanged.

    Method like insertItem and addItem are blocked and try of its usage will end with RuntimeError

    from enum import Enum\n\nfrom qtpy.QtWidgets import QApplication\nfrom superqt import QEnumComboBox\n\n\nclass SampleEnum(Enum):\n    first = 1\n    second = 2\n    third = 3\n\napp = QApplication([])\n\ncombo = QEnumComboBox()\ncombo.setEnumClass(SampleEnum)\ncombo.show()\n\napp.exec_()\n

    Another option is to use optional enum_class argument of constructor and change

    # option A:\ncombo = QEnumComboBox()\ncombo.setEnumClass(SampleEnum)\n# option B:\ncombo = QEnumComboBox(enum_class=SampleEnum)\n
    "},{"location":"widgets/qenumcombobox/#allow-none","title":"Allow None","text":"

    QEnumComboBox also allows using Optional type annotation:

    from enum import Enum\n\nfrom superqt import QEnumComboBox\n\nclass SampleEnum(Enum):\n    first = 1\n    second = 2\n    third = 3\n\n# as usual:\n# you must create a QApplication before create a widget.\n\ncombo = QEnumComboBox()\ncombo.setEnumClass(SampleEnum, allow_none=True)\n

    In this case there is added option ---- and the currentEnum() method will return None when it is selected.

    "},{"location":"widgets/qenumcombobox/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/qenumcombobox/#signals","title":"Signals","text":""},{"location":"widgets/qenumcombobox/#currentenumchanged","title":"currentEnumChanged","text":""},{"location":"widgets/qenumcombobox/#methods","title":"Methods","text":"

    ComboBox presenting options from a python Enum.

    If the Enum class does not implement __str__ then a human readable name is created from the name of the enum member, replacing underscores with spaces.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.currentEnum","title":"currentEnum() -> Optional[EnumType]","text":"

    Current value as Enum member.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.enumClass","title":"enumClass() -> Optional[EnumMeta]","text":"

    Return current Enum class.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.isOptional","title":"isOptional() -> bool","text":"

    Return if current enum is with optional annotation.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.setCurrentEnum","title":"setCurrentEnum(value: Optional[EnumType]) -> None","text":"

    Set value with Enum.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.setEnumClass","title":"setEnumClass(enum: Optional[EnumMeta], allow_none=False)","text":"

    Set enum class from which members value should be selected.

    "},{"location":"widgets/qflowlayout/","title":"QFlowLayout","text":"

    QLayout that rearranges items based on parent width.

    from qtpy.QtWidgets import QApplication, QPushButton, QWidget\n\nfrom superqt import QFlowLayout\n\napp = QApplication([])\n\nwdg = QWidget()\n\nlayout = QFlowLayout(wdg)\nlayout.addWidget(QPushButton(\"Short\"))\nlayout.addWidget(QPushButton(\"Longer\"))\nlayout.addWidget(QPushButton(\"Different text\"))\nlayout.addWidget(QPushButton(\"More text\"))\nlayout.addWidget(QPushButton(\"Even longer button text\"))\n\nwdg.setWindowTitle(\"Flow Layout\")\nwdg.show()\n\napp.exec()\n

    "},{"location":"widgets/qflowlayout/#qt-class","title":"Qt Class","text":"

    QLayout

    "},{"location":"widgets/qflowlayout/#methods","title":"Methods","text":"

    Layout that handles different window sizes.

    The widget placement changes depending on the width of the application window.

    Code translated from C++ at: https://code.qt.io/cgit/qt/qtbase.git/tree/examples/widgets/layouts/flowlayout

    described at: https://doc.qt.io/qt-6/qtwidgets-layouts-flowlayout-example.html

    See also: https://doc.qt.io/qt-6/layout.html

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget, by default None

    None"},{"location":"widgets/qflowlayout/#superqt.QFlowLayout.horizontalSpacing","title":"horizontalSpacing() -> int","text":"

    Return the horizontal spacing.

    "},{"location":"widgets/qflowlayout/#superqt.QFlowLayout.setHorizontalSpacing","title":"setHorizontalSpacing(space: int | None) -> None","text":"

    Set the horizontal spacing.

    If None or -1, the spacing is set to the default value based on the style of the parent widget.

    "},{"location":"widgets/qflowlayout/#superqt.QFlowLayout.setVerticalSpacing","title":"setVerticalSpacing(space: int | None) -> None","text":"

    Set the vertical spacing.

    If None or -1, the spacing is set to the default value based on the style of the parent widget.

    "},{"location":"widgets/qflowlayout/#superqt.QFlowLayout.verticalSpacing","title":"verticalSpacing() -> int","text":"

    Return the vertical spacing.

    "},{"location":"widgets/qlabeleddoublerangeslider/","title":"QLabeledDoubleRangeSlider","text":"

    Labeled Float variant of QRangeSlider. (see that page for more details).

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLabeledDoubleRangeSlider\n\napp = QApplication([])\n\nslider = QLabeledDoubleRangeSlider(Qt.Orientation.Horizontal)\nslider.setRange(0, 1)\nslider.setValue((0.2, 0.8))\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlabeleddoublerangeslider/#qt-class","title":"Qt Class","text":"

    QAbstractSlider

    "},{"location":"widgets/qlabeleddoublerangeslider/#enums","title":"Enums","text":""},{"location":"widgets/qlabeleddoublerangeslider/#qlabeleddoublerangesliderlabelposition","title":"QLabeledDoubleRangeSlider.LabelPosition","text":"
    • NoLabel

    • LabelsAbove

    • LabelsBelow

    • LabelsOnHandle

    "},{"location":"widgets/qlabeleddoublerangeslider/#qlabeleddoublerangeslideredgelabelmode","title":"QLabeledDoubleRangeSlider.EdgeLabelMode","text":"
    • LabelIsRange

    • LabelIsValue

    "},{"location":"widgets/qlabeleddoublerangeslider/#methods","title":"Methods","text":""},{"location":"widgets/qlabeleddoublerangeslider/#superqt.QLabeledDoubleRangeSlider.barColor","title":"barColor = Property(QtGui.QBrush, _getBarColor, _setBarColor) class-attribute instance-attribute","text":"

    The color of the bar between the first and last handle.

    "},{"location":"widgets/qlabeleddoublerangeslider/#superqt.QLabeledDoubleRangeSlider.decimals","title":"decimals() -> int","text":""},{"location":"widgets/qlabeleddoublerangeslider/#superqt.QLabeledDoubleRangeSlider.setDecimals","title":"setDecimals(prec: int) -> None","text":""},{"location":"widgets/qlabeleddoubleslider/","title":"QLabeledDoubleSlider","text":"

    QDoubleSlider variant that shows an editable (SpinBox) label next to the slider.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLabeledDoubleSlider\n\napp = QApplication([])\n\nslider = QLabeledDoubleSlider(Qt.Orientation.Horizontal)\nslider.setRange(0, 2.5)\nslider.setValue(1.3)\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlabeleddoubleslider/#qt-class","title":"Qt Class","text":"

    QAbstractSlider

    "},{"location":"widgets/qlabeleddoubleslider/#enums","title":"Enums","text":""},{"location":"widgets/qlabeleddoubleslider/#qlabeleddoubleslideredgelabelmode","title":"QLabeledDoubleSlider.EdgeLabelMode","text":"
    • LabelIsRange

    • LabelIsValue

    "},{"location":"widgets/qlabeleddoubleslider/#methods","title":"Methods","text":""},{"location":"widgets/qlabeleddoubleslider/#superqt.QLabeledDoubleSlider.decimals","title":"decimals() -> int","text":""},{"location":"widgets/qlabeleddoubleslider/#superqt.QLabeledDoubleSlider.setDecimals","title":"setDecimals(prec: int) -> None","text":""},{"location":"widgets/qlabeledrangeslider/","title":"QLabeledRangeSlider","text":"

    Labeled variant of QRangeSlider. (see that page for more details).

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLabeledRangeSlider\n\napp = QApplication([])\n\nslider = QLabeledRangeSlider(Qt.Orientation.Horizontal)\nslider.setValue((20, 80))\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlabeledrangeslider/#qt-class","title":"Qt Class","text":"

    QAbstractSlider

    "},{"location":"widgets/qlabeledrangeslider/#signals","title":"Signals","text":""},{"location":"widgets/qlabeledrangeslider/#editingfinished","title":"editingFinished","text":""},{"location":"widgets/qlabeledrangeslider/#enums","title":"Enums","text":""},{"location":"widgets/qlabeledrangeslider/#qlabeledrangesliderlabelposition","title":"QLabeledRangeSlider.LabelPosition","text":"
    • NoLabel

    • LabelsAbove

    • LabelsBelow

    • LabelsOnHandle

    "},{"location":"widgets/qlabeledrangeslider/#qlabeledrangeslideredgelabelmode","title":"QLabeledRangeSlider.EdgeLabelMode","text":"
    • LabelIsRange

    • LabelIsValue

    "},{"location":"widgets/qlabeledrangeslider/#methods","title":"Methods","text":"

    If you find that you need to fine tune the position of the handle labels:

    • QLabeledRangeSlider.label_shift_x: adjust horizontal label position
    • QLabeledRangeSlider.label_shift_y: adjust vertical label position
    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.barColor","title":"barColor = Property(QtGui.QBrush, _getBarColor, _setBarColor) class-attribute instance-attribute","text":"

    The color of the bar between the first and last handle.

    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.edgeLabelMode","title":"edgeLabelMode() -> EdgeLabelMode","text":"

    Return current EdgeLabelMode.

    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.handleLabelPosition","title":"handleLabelPosition() -> LabelPosition","text":"

    Return where/whether labels are shown adjacent to slider handles.

    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.setEdgeLabelMode","title":"setEdgeLabelMode(opt: EdgeLabelMode) -> None","text":"

    Set EdgeLabelMode, controls what is shown at the min/max labels.

    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.setHandleLabelPosition","title":"setHandleLabelPosition(opt: LabelPosition) -> None","text":"

    Set where/whether labels are shown adjacent to slider handles.

    "},{"location":"widgets/qlabeledslider/","title":"QLabeledSlider","text":"

    QSlider variant that shows an editable (SpinBox) label next to the slider.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLabeledSlider\n\napp = QApplication([])\n\nslider = QLabeledSlider(Qt.Orientation.Horizontal)\nslider.setValue(42)\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlabeledslider/#qt-class","title":"Qt Class","text":"

    QAbstractSlider

    "},{"location":"widgets/qlabeledslider/#signals","title":"Signals","text":""},{"location":"widgets/qlabeledslider/#editingfinished","title":"editingFinished","text":""},{"location":"widgets/qlabeledslider/#enums","title":"Enums","text":""},{"location":"widgets/qlabeledslider/#qlabeledslideredgelabelmode","title":"QLabeledSlider.EdgeLabelMode","text":"
    • LabelIsRange

    • LabelIsValue

    "},{"location":"widgets/qlabeledslider/#methods","title":"Methods","text":""},{"location":"widgets/qlabeledslider/#superqt.QLabeledSlider.edgeLabelMode","title":"edgeLabelMode() -> EdgeLabelMode","text":"

    Return current EdgeLabelMode.

    "},{"location":"widgets/qlabeledslider/#superqt.QLabeledSlider.setEdgeLabelMode","title":"setEdgeLabelMode(opt: EdgeLabelMode) -> None","text":"

    Set the EdgeLabelMode.

    Parameters:

    Name Type Description Default opt EdgeLabelMode

    To show no label, use EdgeLabelMode.NoLabel. To show the value of the slider, use EdgeLabelMode.LabelIsValue. To show value / maximum, use EdgeLabelMode.LabelIsValue | EdgeLabelMode.LabelIsRange.

    required"},{"location":"widgets/qlargeintspinbox/","title":"QLargeIntSpinBox","text":"

    QSpinBox variant that allows to enter large integers, without overflow.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLargeIntSpinBox\n\napp = QApplication([])\n\nslider = QLargeIntSpinBox()\nslider.setRange(0, 4.53e8)\nslider.setValue(4.53e8)\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlargeintspinbox/#qt-class","title":"Qt Class","text":"

    QAbstractSpinBox

    "},{"location":"widgets/qlargeintspinbox/#signals","title":"Signals","text":""},{"location":"widgets/qlargeintspinbox/#valuechanged","title":"valueChanged","text":""},{"location":"widgets/qlargeintspinbox/#textchanged","title":"textChanged","text":""},{"location":"widgets/qlargeintspinbox/#methods","title":"Methods","text":"

    An integer spinboxes backed by unbound python integer.

    Qt's built-in QSpinBox is backed by a signed 32-bit integer. This could become limiting, particularly in large dense segmentations. This class behaves like a QSpinBox backed by an unbound python int.

    Does not yet support \"prefix\", \"suffix\" or \"specialValue\" like QSpinBox.

    "},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.maximum","title":"maximum()","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.minimum","title":"minimum()","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setMaximum","title":"setMaximum(max)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setMinimum","title":"setMinimum(min)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setRange","title":"setRange(minimum, maximum)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setSingleStep","title":"setSingleStep(step)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setStepType","title":"setStepType(stepType: QAbstractSpinBox.StepType) -> None","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setValue","title":"setValue(value)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.singleStep","title":"singleStep()","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.stepType","title":"stepType() -> QAbstractSpinBox.StepType","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.value","title":"value()","text":""},{"location":"widgets/qquantity/","title":"QQuantity","text":"

    A widget that allows the user to edit a quantity (a magnitude associated with a unit).

    Note

    This widget requires pint:

    pip install pint\n

    or

    pip install superqt[quantity]\n
    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QQuantity\n\napp = QApplication([])\nw = QQuantity(\"1m\")\nw.show()\n\napp.exec()\n

    "},{"location":"widgets/qquantity/#qt-class","title":"Qt Class","text":"

    QWidget

    "},{"location":"widgets/qquantity/#signals","title":"Signals","text":""},{"location":"widgets/qquantity/#dimensionalitychanged","title":"dimensionalityChanged","text":""},{"location":"widgets/qquantity/#valuechanged","title":"valueChanged","text":""},{"location":"widgets/qquantity/#unitschanged","title":"unitsChanged","text":""},{"location":"widgets/qquantity/#methods","title":"Methods","text":"

    A combination QDoubleSpinBox and QComboBox for entering quantities.

    For this widget, value() returns a pint.Quantity object, while setValue() accepts either a number, pint.Quantity, a string that can be parsed by pint.

    Parameters:

    Name Type Description Default value Union[str, Quantity, Number]

    The initial value to display. If a string, it will be parsed by pint.

    0 units Union[UnitsContainer, str, Quantity]

    The units to use if value is a number. If a string, it will be parsed by pint. If a pint.Quantity, the units will be extracted from it.

    None ureg UnitRegistry

    The unit registry to use. If not provided, the registry will be extracted from value if it is a pint.Quantity, otherwise the default registry will be used.

    None parent QWidget

    The parent widget, by default None

    None"},{"location":"widgets/qquantity/#superqt.QQuantity.dimensionality","title":"dimensionality() -> UnitsContainer","text":"

    Return the current dimensionality (cast to str for nice repr).

    "},{"location":"widgets/qquantity/#superqt.QQuantity.isDimensionless","title":"isDimensionless() -> bool","text":"

    Return True if the current value is dimensionless.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.magnitude","title":"magnitude() -> Union[float, int]","text":"

    Return the magnitude of the current value.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.magnitudeSpinBox","title":"magnitudeSpinBox() -> QDoubleSpinBox","text":"

    Return the QSpinBox widget used to edit the magnitude.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.setDecimals","title":"setDecimals(decimals: int) -> None","text":"

    Set the number of decimals to display in the spinbox.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.setMagnitude","title":"setMagnitude(magnitude: Number) -> None","text":"

    Set the magnitude of the current value.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.setUnits","title":"setUnits(units: Union[str, Unit, Quantity]) -> None","text":"

    Set the units of the current value.

    If units is None, will convert to a dimensionless quantity. Otherwise, units must be compatible with the current dimensionality.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.setValue","title":"setValue(value: Union[str, Quantity, Number], units: Optional[Union[UnitsContainer, str, Quantity]] = None) -> None","text":"

    Set the current value (will cast to a pint Quantity).

    "},{"location":"widgets/qquantity/#superqt.QQuantity.text","title":"text() -> str","text":""},{"location":"widgets/qquantity/#superqt.QQuantity.unitRegistry","title":"unitRegistry() -> UnitRegistry","text":"

    Return the pint UnitRegistry used by this widget.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.units","title":"units() -> Unit","text":"

    Return the current units.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.unitsComboBox","title":"unitsComboBox() -> QComboBox","text":"

    Return the QCombBox widget used to edit the units.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.value","title":"value() -> Quantity","text":"

    Return the current value as a pint.Quantity.

    "},{"location":"widgets/qrangeslider/","title":"QRangeSlider","text":"

    A multi-handle slider widget than can be used to select a range of values.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QRangeSlider\n\napp = QApplication([])\n\nslider = QRangeSlider(Qt.Orientation.Horizontal)\nslider.setValue((20, 80))\nslider.show()\n\napp.exec_()\n

    • QRangeSlider inherits from QSlider and attempts to match the Qt API as closely as possible
    • It uses platform-specific styles (for handle, groove, & ticks) but also supports QSS style sheets.
    • Supports mouse wheel events
    • Supports more than 2 handles (e.g. slider.setValue([0, 10, 60, 80]))

    As QRangeSlider inherits from QtWidgets.QSlider, you can use all of the same methods available in the QSlider API. The major difference is that value() and sliderPosition() are reimplemented as tuples of int (where the length of the tuple is equal to the number of handles in the slider.)

    These options are in addition to the Qt QSlider API, and control the behavior of the bar between handles.

    getter setter type default description barIsVisible setBarIsVisible hideBar / showBar bool True Whether the bar between handles is visible. barMovesAllHandles setBarMovesAllHandles bool True Whether clicking on the bar moves all handles or just the nearest barIsRigid setBarIsRigid bool True Whether bar length is constant or \"elastic\" when dragging the bar beyond min/max."},{"location":"widgets/qrangeslider/#screenshots","title":"Screenshots","text":"code that generates the images below
    import os\n\nfrom qtpy import QtCore\nfrom qtpy import QtWidgets as QtW\n\n# patch for Qt 5.15 on macos >= 12\nos.environ[\"USE_MAC_SLIDER_PATCH\"] = \"1\"\n\nfrom superqt import QRangeSlider  # noqa\n\nQSS = \"\"\"\nQSlider {\n    min-height: 20px;\n}\n\nQSlider::groove:horizontal {\n    border: 0px;\n    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #888, stop:1 #ddd);\n    height: 20px;\n    border-radius: 10px;\n}\n\nQSlider::handle {\n    background: qradialgradient(cx:0, cy:0, radius: 1.2, fx:0.35,\n                                fy:0.3, stop:0 #eef, stop:1 #002);\n    height: 20px;\n    width: 20px;\n    border-radius: 10px;\n}\n\nQSlider::sub-page:horizontal {\n    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #227, stop:1 #77a);\n    border-top-left-radius: 10px;\n    border-bottom-left-radius: 10px;\n}\n\nQRangeSlider {\n    qproperty-barColor: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #227, stop:1 #77a);\n}\n\"\"\"\n\nHorizontal = QtCore.Qt.Orientation.Horizontal\n\n\nclass DemoWidget(QtW.QWidget):\n    def __init__(self) -> None:\n        super().__init__()\n\n        reg_hslider = QtW.QSlider(Horizontal)\n        reg_hslider.setValue(50)\n        range_hslider = QRangeSlider(Horizontal)\n        range_hslider.setValue((20, 80))\n        multi_range_hslider = QRangeSlider(Horizontal)\n        multi_range_hslider.setValue((11, 33, 66, 88))\n        multi_range_hslider.setTickPosition(QtW.QSlider.TickPosition.TicksAbove)\n\n        styled_reg_hslider = QtW.QSlider(Horizontal)\n        styled_reg_hslider.setValue(50)\n        styled_reg_hslider.setStyleSheet(QSS)\n        styled_range_hslider = QRangeSlider(Horizontal)\n        styled_range_hslider.setValue((20, 80))\n        styled_range_hslider.setStyleSheet(QSS)\n\n        reg_vslider = QtW.QSlider(QtCore.Qt.Orientation.Vertical)\n        reg_vslider.setValue(50)\n        range_vslider = QRangeSlider(QtCore.Qt.Orientation.Vertical)\n        range_vslider.setValue((22, 77))\n\n        tick_vslider = QtW.QSlider(QtCore.Qt.Orientation.Vertical)\n        tick_vslider.setValue(55)\n        tick_vslider.setTickPosition(QtW.QSlider.TicksRight)\n        range_tick_vslider = QRangeSlider(QtCore.Qt.Orientation.Vertical)\n        range_tick_vslider.setValue((22, 77))\n        range_tick_vslider.setTickPosition(QtW.QSlider.TicksLeft)\n\n        szp = QtW.QSizePolicy.Maximum\n        left = QtW.QWidget()\n        left.setLayout(QtW.QVBoxLayout())\n        left.setContentsMargins(2, 2, 2, 2)\n        label1 = QtW.QLabel(\"Regular QSlider Unstyled\")\n        label2 = QtW.QLabel(\"QRangeSliders Unstyled\")\n        label3 = QtW.QLabel(\"Styled Sliders (using same stylesheet)\")\n        label1.setSizePolicy(szp, szp)\n        label2.setSizePolicy(szp, szp)\n        label3.setSizePolicy(szp, szp)\n        left.layout().addWidget(label1)\n        left.layout().addWidget(reg_hslider)\n        left.layout().addWidget(label2)\n        left.layout().addWidget(range_hslider)\n        left.layout().addWidget(multi_range_hslider)\n        left.layout().addWidget(label3)\n        left.layout().addWidget(styled_reg_hslider)\n        left.layout().addWidget(styled_range_hslider)\n\n        right = QtW.QWidget()\n        right.setLayout(QtW.QHBoxLayout())\n        right.setContentsMargins(15, 5, 5, 0)\n        right.layout().setSpacing(30)\n        right.layout().addWidget(reg_vslider)\n        right.layout().addWidget(range_vslider)\n        right.layout().addWidget(tick_vslider)\n        right.layout().addWidget(range_tick_vslider)\n\n        self.setLayout(QtW.QHBoxLayout())\n        self.layout().addWidget(left)\n        self.layout().addWidget(right)\n        self.setGeometry(600, 300, 580, 300)\n        self.activateWindow()\n        self.show()\n\n\nif __name__ == \"__main__\":\n\n    import sys\n    from pathlib import Path\n\n    dest = Path(\"screenshots\")\n    dest.mkdir(exist_ok=True)\n\n    app = QtW.QApplication([])\n    demo = DemoWidget()\n\n    if \"-snap\" in sys.argv:\n        import platform\n\n        QtW.QApplication.processEvents()\n        demo.grab().save(str(dest / f\"demo_{platform.system().lower()}.png\"))\n    else:\n        app.exec_()\n
    "},{"location":"widgets/qrangeslider/#macos","title":"macOS","text":""},{"location":"widgets/qrangeslider/#catalina","title":"Catalina","text":""},{"location":"widgets/qrangeslider/#big-sur","title":"Big Sur","text":""},{"location":"widgets/qrangeslider/#windows","title":"Windows","text":""},{"location":"widgets/qrangeslider/#linux","title":"Linux","text":""},{"location":"widgets/qrangeslider/#qt-class","title":"Qt Class","text":"

    QSlider

    "},{"location":"widgets/qrangeslider/#methods","title":"Methods","text":"

    MultiHandle Range Slider widget.

    Same API as QSlider, but value, setValue, sliderPosition, and setSliderPosition are all sequences of integers.

    The valueChanged and sliderMoved signals also both emit a tuple of integers.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.barColor","title":"barColor = Property(QtGui.QBrush, _getBarColor, _setBarColor) class-attribute instance-attribute","text":"

    The color of the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.applyMacStylePatch","title":"applyMacStylePatch() -> None","text":"

    Apply a QSS patch to fix sliders on macos>=12 with QT < 6.

    see FAQ for more details.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.barIsRigid","title":"barIsRigid() -> bool","text":"

    Whether bar length is constant when dragging the bar.

    If False, the bar can shorten when dragged beyond min/max. Default is True.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.barIsVisible","title":"barIsVisible() -> bool","text":"

    Whether to show the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.barMovesAllHandles","title":"barMovesAllHandles() -> bool","text":"

    Whether clicking on the bar moves all handles, or just the nearest.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.hideBar","title":"hideBar() -> None","text":"

    Hide the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.setBarIsRigid","title":"setBarIsRigid(val: bool = True) -> None","text":"

    Whether bar length is constant when dragging the bar.

    If False, the bar can shorten when dragged beyond min/max. Default is True.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.setBarMovesAllHandles","title":"setBarMovesAllHandles(val: bool = True) -> None","text":"

    Whether clicking on the bar moves all handles, or just the nearest.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.setBarVisible","title":"setBarVisible(val: bool = True) -> None","text":"

    Whether to show the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.showBar","title":"showBar() -> None","text":"

    Show the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#type-changes","title":"Type changes","text":"

    Note the following changes in types compared to the QSlider API:

    value() -> Tuple[int, ...]\n
    setValue(val: Sequence[int]) -> None\n
    # Signal\nvalueChanged(Tuple[int, ...])\n
    sliderPosition() -> Tuple[int, ...]\n
    setSliderPosition(val: Sequence[int]) -> None\n
    sliderMoved(Tuple[int, ...])\n
    "},{"location":"widgets/qsearchablecombobox/","title":"QSearchableComboBox","text":"

    QSearchableComboBox is a variant of QComboBox that allow to filter list of options by enter part of text. It could be drop in replacement for QComboBox.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QSearchableComboBox\n\napp = QApplication([])\n\ncombo = QSearchableComboBox()\ncombo.addItems([\"foo\", \"bar\", \"baz\", \"foobar\", \"foobaz\", \"barbaz\"])\ncombo.show()\n\napp.exec_()\n

    "},{"location":"widgets/qsearchablecombobox/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/qsearchablelistwidget/","title":"QSearchableListWidget","text":"

    QSearchableListWidget is a variant of QListWidget that add text entry above list widget that allow to filter list of available options.

    Due to implementation details, this widget it does not inherit directly from QListWidget but it does fully satisfy its api. The only limitation is that it cannot be used as argument of QListWidgetItem constructor.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QSearchableListWidget\n\napp = QApplication([])\n\nslider = QSearchableListWidget()\nslider.addItems([\"foo\", \"bar\", \"baz\", \"foobar\", \"foobaz\", \"barbaz\"])\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qsearchablelistwidget/#qt-class","title":"Qt Class","text":"

    QWidget

    "},{"location":"widgets/qsearchablelistwidget/#methods","title":"Methods","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.addItem","title":"addItem(*args)","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.addItems","title":"addItems(*args)","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.insertItem","title":"insertItem(*args)","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.insertItems","title":"insertItems(*args)","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.update_visible","title":"update_visible(text)","text":""},{"location":"widgets/qsearchabletreewidget/","title":"QSearchableTreeWidget","text":"

    QSearchableTreeWidget combines a QTreeWidget and a QLineEdit for showing a mapping that can be searched by key.

    This is intended to be used with a read-only mapping and be conveniently created using QSearchableTreeWidget.fromData(data). If the mapping changes, the easiest way to update this is by calling setData.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QSearchableTreeWidget\n\napp = QApplication([])\n\ndata = {\n    \"none\": None,\n    \"str\": \"test\",\n    \"int\": 42,\n    \"list\": [2, 3, 5],\n    \"dict\": {\n        \"float\": 0.5,\n        \"tuple\": (22, 99),\n        \"bool\": False,\n    },\n}\ntree = QSearchableTreeWidget.fromData(data)\ntree.show()\n\napp.exec_()\n

    "},{"location":"widgets/qsearchabletreewidget/#qt-class","title":"Qt Class","text":"

    QWidget

    "},{"location":"widgets/qsearchabletreewidget/#methods","title":"Methods","text":"

    A tree widget for showing a mapping that can be searched by key.

    This is intended to be used with a read-only mapping and be conveniently created using QSearchableTreeWidget.fromData(data). If the mapping changes, the easiest way to update this is by calling setData.

    The tree can be searched by entering a regular expression pattern into the filter line edit. An item is only shown if its, any of its ancestors', or any of its descendants' keys or values match this pattern. The regular expression follows the conventions described by the Qt docs: https://doc.qt.io/qt-5/qregularexpression.html#details

    Attributes:

    Name Type Description tree QTreeWidget

    Shows the mapping as a tree of items.

    filter QLineEdit

    Used to filter items in the tree by matching their key against a regular expression.

    "},{"location":"widgets/qsearchabletreewidget/#superqt.QSearchableTreeWidget.fromData","title":"fromData(data: Mapping, *, parent: QWidget = None) -> QSearchableTreeWidget classmethod","text":"

    Make a searchable tree widget from a mapping.

    "},{"location":"widgets/qsearchabletreewidget/#superqt.QSearchableTreeWidget.setData","title":"setData(data: Mapping) -> None","text":"

    Update the mapping data shown by the tree.

    "}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"superqt","text":""},{"location":"#missing-widgets-and-components-for-pyqtpyside","title":"\"missing\" widgets and components for PyQt/PySide","text":"

    This repository aims to provide high-quality community-contributed Qt widgets and components for PyQt & PySide that are not provided in the native QtWidgets module.

    Components are tested on:

    • macOS, Windows, & Linux
    • Python 3.9 and above
    • PyQt5 (5.11 and above) & PyQt6
    • PySide2 (5.11 and above) & PySide6
    "},{"location":"#installation","title":"Installation","text":"
    pip install superqt\n
    conda install -c conda-forge superqt\n
    "},{"location":"#usage","title":"Usage","text":"

    See the Widgets and Utilities pages for features offered by superqt.

    "},{"location":"faq/","title":"FAQ","text":""},{"location":"faq/#sliders-not-dragging-properly-on-macos-12","title":"Sliders not dragging properly on MacOS 12+","text":"Details

    On MacOS Monterey, with Qt5, there is a bug that causes all sliders (including native Qt sliders) to not respond properly to drag events. See:

    • https://bugreports.qt.io/browse/QTBUG-98093
    • https://github.com/pyapp-kit/superqt/issues/74

    Superqt includes a workaround for this issue, but it is not perfect, and it requires using a custom stylesheet (which may interfere with your own styles). Note that you may not see this issue if you're already using custom stylesheets.

    To opt in to the workaround, do any of the following:

    • set the environment variable USE_MAC_SLIDER_PATCH=1 before importing superqt (note: this is safe to use even if you're targeting more than just MacOS 12, it will only be applied when needed)
    • call the applyMacStylePatch() method on any of the superqt slider subclasses (note, this will override your slider styles)
    • apply the stylesheet manually:
    from superqt.sliders import MONTEREY_SLIDER_STYLES_FIX\n\nslider.setStyleSheet(MONTEREY_SLIDER_STYLES_FIX)\n
    "},{"location":"utilities/","title":"Utilities","text":""},{"location":"utilities/#font-icons","title":"Font Icons","text":"Object Description addFont Add an OTF/TTF file at to the font registry. font Create QFont for a given font-icon font family key icon Create a QIcon for font-con glyph key setTextIcon Set text on a QWidget to a specific font & glyph. IconFont Helper class that provides a standard way to create an IconFont. IconOpts Options for rendering an icon Animation Base class for adding animations to a font-icon."},{"location":"utilities/#svg-icons","title":"SVG Icons","text":"Object Description QIconifyIcon QIcons backed by the Iconify icon library."},{"location":"utilities/#threading-tools","title":"Threading tools","text":"Object Description ensure_main_thread Decorator that ensures a function is called in the main QApplication thread. ensure_object_thread Decorator that ensures a QObject method is called in the object's thread. FunctionWorker QRunnable with signals that wraps a simple long-running function. GeneratorWorker QRunnable with signals that wraps a long-running generator. create_worker Create a worker to run a target function in another thread. thread_worker Decorator for create_worker, turn a function into a worker."},{"location":"utilities/#miscellaneous","title":"Miscellaneous","text":"Object Description QMessageHandler A context manager to intercept messages from Qt. CodeSyntaxHighlight A QSyntaxHighlighter for code syntax highlighting. draw_colormap Function that draws a colormap into any QPaintDevice."},{"location":"utilities/cmap/","title":"Colormap utilities","text":"

    See also:

    • superqt.QColormapComboBox
    • superqt.cmap.CmapCatalogComboBox
    "},{"location":"utilities/cmap/#superqt.cmap.draw_colormap","title":"superqt.cmap.draw_colormap(painter_or_device, cmap, rect=None, border_color=None, border_width=1, lighter=100, checkerboard_size=4)","text":"

    Draw a colormap onto a QPainter or QPaintDevice.

    Parameters:

    Name Type Description Default painter_or_device QPainter | QPaintDevice

    A QPainter instance or a QPaintDevice (e.g. a QWidget or QPixmap) onto which to paint the colormap.

    required cmap Colormap | Any

    cmap.Colormap instance, or anything that can be converted to one (such as a string name of a colormap in the cmap catalog). https://cmap-docs.readthedocs.io/en/latest/colormaps/#colormaplike-objects

    required rect QRect | QRectF | None

    A rect onto which to draw. If None, the painter.viewport() will be used. by default None

    None border_color QColor | str | None

    If not None, a border of color border_color and width border_width is included around the edge, by default None.

    None border_width int

    The width of the border to draw (provided border_color is not None), by default 2

    1 lighter int

    Percentage by which to lighten (or darken) the colors. Greater than 100 lightens, less than 100 darkens, by default 100 (i.e. no change).

    100 checkerboard_size bool

    Size (in pixels) of the checkerboard pattern to draw, by default 5. If 0, no checkerboard is drawn.

    4

    Examples:

    from qtpy.QtGui import QPixmap\nfrom qtpy.QtWidgets import QWidget\nfrom superqt.utils import draw_colormap\n\nviridis = \"viridis\"  # or cmap.Colormap('viridis')\n\n\nclass W(QWidget):\n    def paintEvent(self, event) -> None:\n        draw_colormap(self, viridis, event.rect())\n\n\n# or draw onto a QPixmap\npm = QPixmap(200, 200)\ndraw_colormap(pm, viridis)\n
    "},{"location":"utilities/cmap/#superqt.cmap.QColormapLineEdit","title":"superqt.cmap.QColormapLineEdit","text":"

    Bases: QLineEdit

    A QLineEdit that shows a colormap swatch.

    When the current text is a valid colormap name from the cmap package, a swatch of the colormap will be shown to the left of the text (if fractionalColormapWidth is less than .75) or behind the text (for when the colormap fills the full width).

    If the current text is not a valid colormap name, a swatch of the fallback colormap will be shown instead (by default, a gray colormap) if fractionalColormapWidth is less than .75.

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget.

    None fractional_colormap_width float

    The fraction of the widget width to use for the colormap swatch. If the colormap is full width (greater than 0.75), the swatch will be drawn behind the text. Otherwise, the swatch will be drawn to the left of the text. Default is 0.33.

    0.33 fallback_cmap Colormap | str | None

    The colormap to use when the current text is not a recognized colormap. by default \"gray\".

    'gray' missing_icon QIcon | StandardPixmap

    The icon to show when the current text is not a recognized colormap and fractionalColormapWidth is less than .75. Default is a question mark.

    MISSING checkerboard_size int

    Size (in pixels) of the checkerboard pattern to draw behind colormaps with transparency, by default 4. If 0, no checkerboard is drawn.

    4"},{"location":"utilities/cmap/#superqt.cmap.QColormapItemDelegate","title":"superqt.cmap.QColormapItemDelegate","text":"

    Bases: QStyledItemDelegate

    Delegate that draws colormaps into a QAbstractItemView item.

    Parameters:

    Name Type Description Default parent QObject

    The parent object.

    None item_size QSize

    The size hint for each item, by default QSize(80, 22).

    DEFAULT_SIZE fractional_colormap_width float

    The fraction of the widget width to use for the colormap swatch. If the colormap is full width (greater than 0.75), the swatch will be drawn behind the text. Otherwise, the swatch will be drawn to the left of the text. Default is 0.33.

    1 padding int

    The padding (in pixels) around the edge of the item, by default 1.

    1 checkerboard_size int

    Size (in pixels) of the checkerboard pattern to draw behind colormaps with transparency, by default 4. If 0, no checkerboard is drawn.

    4"},{"location":"utilities/code_syntax_highlight/","title":"CodeSyntaxHighlight","text":"

    A code highlighter subclass of QSyntaxHighlighter that can be used to highlight code in a QTextEdit.

    Code lexer and available styles are from pygments python library

    List of available languages are available here.

    List of available styles are available here.

    "},{"location":"utilities/code_syntax_highlight/#example","title":"Example","text":"
    from qtpy.QtGui import QColor, QPalette\nfrom qtpy.QtWidgets import QApplication, QTextEdit\n\nfrom superqt.utils import CodeSyntaxHighlight\n\napp = QApplication([])\n\ntext_area = QTextEdit()\n\nhighlight = CodeSyntaxHighlight(text_area.document(), \"python\", \"monokai\")\n\npalette = text_area.palette()\npalette.setColor(QPalette.Base, QColor(highlight.background_color))\ntext_area.setPalette(palette)\ntext_area.setText(\n    \"\"\"from argparse import ArgumentParser\n\ndef main():\n    parser = ArgumentParser()\n    parser.add_argument(\"name\", help=\"Your name\")\n    args = parser.parse_args()\n    print(f\"Hello {args.name}\")\n\n\nif __name__ == \"__main__\":\n    main()\n\"\"\"\n)\n\ntext_area.show()\ntext_area.resize(400, 200)\n\napp.exec_()\n
    "},{"location":"utilities/code_syntax_highlight/#qt-class","title":"Qt Class","text":"

    QSyntaxHighlighter

    "},{"location":"utilities/code_syntax_highlight/#methods","title":"Methods","text":"

    A syntax highlighter for code using Pygments.

    Parameters:

    Name Type Description Default parent QTextDocument | QObject | None

    The parent object. Usually a QTextDocument. To use this class with a QTextArea, pass in text_area.document().

    required lang str

    The language of the code to highlight. This should be a string that Pygments recognizes, e.g. 'python', 'pytb', 'cpp', 'java', etc.

    required theme KnownStyle | str

    The name of the Pygments style to use. For a complete list of available styles, use pygments.styles.get_all_styles().

    'default'

    Examples:

    from qtpy.QtWidgets import QTextEdit\nfrom superqt.utils import CodeSyntaxHighlight\n\ntext_area = QTextEdit()\nhighlighter = CodeSyntaxHighlight(text_area.document(), \"python\", \"monokai\")\n\n# then manually apply the background color to the text area.\npalette = text_area.palette()\nbgrd_color = QColor(self._highlight.background_color)\npalette.setColor(QPalette.ColorRole.Base, bgrd_color)\ntext_area.setPalette(palette)\n
    "},{"location":"utilities/code_syntax_highlight/#superqt.utils.CodeSyntaxHighlight.background_color","title":"background_color: str property","text":""},{"location":"utilities/code_syntax_highlight/#superqt.utils.CodeSyntaxHighlight.setLanguage","title":"setLanguage(lang: str) -> None","text":"

    Set the language for the syntax highlighting.

    This should be a string that Pygments recognizes, e.g. 'python', 'pytb', 'cpp', 'java', etc.

    "},{"location":"utilities/code_syntax_highlight/#superqt.utils.CodeSyntaxHighlight.setTheme","title":"setTheme(theme: KnownStyle | str) -> None","text":"

    Set the theme for the syntax highlighting.

    This should be a string that Pygments recognizes, e.g. 'monokai', 'solarized'. Use pygments.styles.get_all_styles() to see a list of available styles.

    "},{"location":"utilities/error_dialog_contexts/","title":"Error message context manager","text":""},{"location":"utilities/error_dialog_contexts/#superqt.utils.exceptions_as_dialog","title":"superqt.utils.exceptions_as_dialog","text":"

    Context manager that shows a dialog when an exception is raised.

    See examples below for common usage patterns.

    To determine whether an exception was raised or not, check the exception attribute after the context manager has exited. If use_error_message is False (the default), you can also access the dialog attribute to get/manipulate the QMessageBox instance.

    Parameters:

    Name Type Description Default exceptions type[BaseException] | tuple[type[BaseException], ...]

    The exception(s) to catch, by default Exception (i.e. all exceptions).

    Exception icon Icon

    The icon to show in the QMessageBox, by default QMessageBox.Icon.Critical

    Critical title str

    The title of the QMessageBox, by default \"An error occurred\".

    'An error occurred' msg_template str

    The message to show in the QMessageBox. The message will be formatted using three variables:

    • exc_value: the exception instance
    • exc_type: the exception type
    • tb: the traceback as a string

    The default template is the content of the exception: \"{exc_value}\"

    '{exc_value}' buttons StandardButton

    The buttons to show in the QMessageBox, by default QMessageBox.StandardButton.Ok

    Ok parent QWidget | None

    The parent widget of the QMessageBox, by default None

    None use_error_message bool | QErrorMessage

    Whether to use a QErrorMessage instead of a QMessageBox. By default False. QErrorMessage shows a checkbox that the user can check to prevent seeing the message again (based on the text of the formatted msg_template.) If True, the global QMessageError.qtHandler() instance is used to maintain a history of dismissed messages. You may also pass a QErrorMessage instance to use a specific instance. If use_error_message is True, or if you pass your own QErrorMessage instance, the parent argument is ignored.

    False

    Attributes:

    Name Type Description dialog QMessageBox | None

    The QMessageBox instance that was created (if use_error_message was False). This can be used, among other things, to determine the result of the dialog (e.g. dialog.result()) or to manipulate the dialog (e.g. dialog.setDetailedText(\"some text\")).

    exception BaseException | None

    Will hold the exception instance if an exception was raised and caught.

    Examples:

    from qtpy.QtWidgets import QApplication\nfrom superqt.utils import exceptions_as_dialog\n\napp = QApplication([])\n\nwith exceptions_as_dialog() as ctx:\n    raise Exception(\"This will be caught and shown in a QMessageBox\")\n\n# you can access the exception instance here\nassert ctx.exception is not None\n\n# with exceptions_as_dialog(ValueError):\n#     1 / 0  # ZeroDivisionError is not caught, so this will raise\n\nwith exceptions_as_dialog(msg_template=\"Error: {exc_value}\"):\n    raise Exception(\"This message will be inserted at 'exc_value'\")\n\nfor _i in range(3):\n    with exceptions_as_dialog(AssertionError, use_error_message=True):\n        assert False, \"Uncheck the checkbox to ignore this in the future\"\n\n# use ctx.dialog to get the result of the dialog\nbtns = QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel\nwith exceptions_as_dialog(buttons=btns) as ctx:\n    raise Exception(\"This will be caught and shown in a QMessageBox\")\nprint(ctx.dialog.result())  # prints which button was clicked\n\napp.exec()  # needed only for the use_error_message example to show\n
    "},{"location":"utilities/fonticon/","title":"Font icons","text":"

    The superqt.fonticon module provides a set of utilities for working with font icons such as Font Awesome or Material Design Icons.

    "},{"location":"utilities/fonticon/#basic-example","title":"Basic Example","text":"
    from fonticon_fa5 import FA5S\n\nfrom qtpy.QtCore import QSize\nfrom qtpy.QtWidgets import QApplication, QPushButton\n\nfrom superqt.fonticon import icon, pulse\n\napp = QApplication([])\n\nbtn2 = QPushButton()\nbtn2.setIcon(icon(FA5S.smile, color=\"blue\"))\nbtn2.setIconSize(QSize(225, 225))\nbtn2.show()\n\napp.exec()\n
    "},{"location":"utilities/fonticon/#font-icon-plugins","title":"Font Icon plugins","text":"

    Ready-made fonticon packs are available as plugins.

    A great way to search across most available icons libraries from a single search interface is to use glyphsearch: https://glyphsearch.com/

    If a font library you'd like to use is unavailable as a superqt plugin, please open a feature request

    "},{"location":"utilities/fonticon/#font-awesome-6","title":"Font Awesome 6","text":"

    Browse available icons at https://fontawesome.com/v6/search

    pip install fonticon-fontawesome6\n
    "},{"location":"utilities/fonticon/#font-awesome-5","title":"Font Awesome 5","text":"

    Browse available icons at https://fontawesome.com/v5/search

    pip install fonticon-fontawesome5\n
    "},{"location":"utilities/fonticon/#material-design-icons-7","title":"Material Design Icons 7","text":"

    Browse available icons at https://materialdesignicons.com/

    pip install fonticon-materialdesignicons7\n
    "},{"location":"utilities/fonticon/#material-design-icons-6","title":"Material Design Icons 6","text":"

    Browse available icons at https://materialdesignicons.com/ (note that the search defaults to v7, see changes from v6 in the changelog)

    pip install fonticon-materialdesignicons6\n
    "},{"location":"utilities/fonticon/#see-also","title":"See also","text":"
    • https://github.com/tlambert03/fonticon-bootstrapicons
    • https://github.com/tlambert03/fonticon-linearicons
    • https://github.com/tlambert03/fonticon-feather

    superqt.fonticon is a pluggable system, and font icon packs may use the \"superqt.fonticon\" entry point to register themselves with superqt. See fonticon-cookiecutter for a template, or look through the following repos for examples:

    • https://github.com/tlambert03/fonticon-fontawesome6
    • https://github.com/tlambert03/fonticon-fontawesome5
    • https://github.com/tlambert03/fonticon-materialdesignicons6
    "},{"location":"utilities/fonticon/#api","title":"API","text":"

    options: heading_level: 3

    options: heading_level: 3

    options: heading_level: 3

    options: heading_level: 3

    options: heading_level: 3

    "},{"location":"utilities/fonticon/#superqt.fonticon.icon","title":"superqt.fonticon.icon(glyph_key, scale_factor=DEFAULT_SCALING_FACTOR, color=None, opacity=1, animation=None, transform=None, states=None)","text":"

    Create a QIcon for glyph_key, with a number of optional settings.

    The glyph_key (e.g. 'fa5s.smile') represents a Font-family & style, and a glyph. In most cases, the key should be provided by a plugin in the environment, like:

    • fonticon-fontawesome5 ('fa5s' & 'fa5r' prefixes)
    • fonticon-materialdesignicons6 ('mdi6' prefix)

    ...but fonts can also be added manually using addFont.

    Parameters:

    Name Type Description Default glyph_key str

    String encapsulating a font-family, style, and glyph. e.g. 'fa5s.smile'.

    required scale_factor float

    Scale factor (fraction of widget height), When widget icon is painted on widget, it will use font.setPixelSize(round(wdg.height() * scale_factor)). by default 0.875.

    DEFAULT_SCALING_FACTOR color ValidColor

    Color for the font, by default None. (e.g. The default QColor) Valid color types include QColor, int, str, Qt.GlobalColor, tuple (of integer: RGB[A]) (anything that can be passed to QColor).

    None opacity float

    Opacity of icon, by default 1

    1 animation Animation

    Animation for the icon. A subclass of superqt.fonticon.Animation, that provides a concrete animate method. (see \"spin\" and \"pulse\" for examples). by default None.

    None transform QTransform

    A QTransform to apply when painting the icon, by default None

    None states dict

    Provide additional styling for the icon in different states. states must be a mapping of string to dict, where:

    • the key represents a QIcon.State (\"on\", \"off\"), a QIcon.Mode (\"normal\", \"active\", \"selected\", \"disabled\"), or any combination of a state & mode separated by an underscore (e.g. \"off_active\", \"selected_on\", etc...).
    • the value is a dict with all of the same key/value meanings listed above as parameters to this function (e.g. glyph_key, color,scale_factor, animation, etc...)

    Missing keys in the state dicts will be taken from the default options, provided by the parameters above.

    None

    Returns:

    Type Description QFontIcon

    A subclass of QIcon. Can be used wherever QIcons are used, such as widget.setIcon()

    Examples:

    simple example (using the string 'fa5s.smile' assumes the fonticon-fontawesome5 plugin is installed)

    >>> btn = QPushButton()\n>>> btn.setIcon(icon(\"fa5s.smile\"))\n

    can also directly import from fonticon_fa5

    >>> from fonticon_fa5 import FA5S\n>>> btn.setIcon(icon(FA5S.smile))\n

    with animation

    >>> btn2 = QPushButton()\n>>> btn2.setIcon(icon(FA5S.spinner, animation=pulse(btn2)))\n

    complicated example

    >>> btn = QPushButton()\n>>> btn.setIcon(\n...     icon(\n...         FA5S.ambulance,\n...         color=\"blue\",\n...         states={\n...             \"active\": {\n...                 \"glyph\": FA5S.bath,\n...                 \"color\": \"red\",\n...                 \"scale_factor\": 0.5,\n...                 \"animation\": pulse(btn),\n...             },\n...             \"disabled\": {\n...                 \"color\": \"green\",\n...                 \"scale_factor\": 0.8,\n...                 \"animation\": spin(btn),\n...             },\n...         },\n...     )\n... )\n>>> btn.setIconSize(QSize(256, 256))\n>>> btn.show()\n
    "},{"location":"utilities/fonticon/#superqt.fonticon.setTextIcon","title":"superqt.fonticon.setTextIcon(widget, glyph_key, size=None)","text":"

    Set text on a widget to a specific font & glyph.

    This is an alternative to setting a QIcon with a pixmap. It may be easier to combine with dynamic stylesheets.

    Parameters:

    Name Type Description Default widget QWidget

    A widget supporting a setText method.

    required glyph_key str

    String encapsulating a font-family, style, and glyph. e.g. 'fa5s.smile'.

    required size int

    Size for QFont. passed to setPixelSize, by default None

    None"},{"location":"utilities/fonticon/#superqt.fonticon.font","title":"superqt.fonticon.font(font_prefix, size=None)","text":"

    Create QFont for font_prefix.

    Parameters:

    Name Type Description Default font_prefix str

    Font_prefix, such as 'fa5s' or 'mdi6', representing a font-family and style.

    required size int

    Size for QFont. passed to setPixelSize, by default None

    None

    Returns:

    Type Description QFont

    QFont instance that can be used to add fonticons to widgets.

    "},{"location":"utilities/fonticon/#superqt.fonticon.IconOpts","title":"superqt.fonticon.IconOpts dataclass","text":"

    Options for rendering an icon.

    Parameters:

    Name Type Description Default glyph_key str

    The key of the glyph to use, e.g. 'fa5s.smile', by default None

    _Unset scale_factor float

    The scale factor to use, by default None

    _Unset color ValidColor

    The color to use, by default None. Colors may be specified as a string, QColor, Qt.GlobalColor, or a 3 or 4-tuple of integers.

    _Unset opacity float

    The opacity to use, by default None

    _Unset animation Animation

    The animation to use, by default None

    _Unset"},{"location":"utilities/fonticon/#superqt.fonticon.addFont","title":"superqt.fonticon.addFont(filepath, prefix, charmap=None)","text":"

    Add OTF/TTF file at filepath to the registry under prefix.

    If you'd like to later use a fontkey in the form of prefix.some-name, then charmap must be provided and provide a mapping for all of the glyph names to their unicode numbers. If a charmap is not provided, glyphs must be directly accessed with their unicode as something like key.\uffff.

    Note

    in most cases, users will not need this. Instead, they should install a font plugin, like:

    • fonticon-fontawesome5
    • fonticon-materialdesignicons6

    Parameters:

    Name Type Description Default filepath str

    Path to an OTF or TTF file containing the fonts

    required prefix str

    A prefix that will represent this font file when used for lookup. For example, 'fa5s' for 'Font-Awesome 5 Solid'.

    required charmap Dict[str, str]

    optional mapping for all of the glyph names to their unicode numbers. See note above.

    None

    Returns:

    Type Description (Tuple[str, str], optional)

    font-family and font-style for the file just registered, or None if something goes wrong.

    "},{"location":"utilities/fonticon/#animations","title":"Animations","text":"

    the animation parameter to icon() accepts a subclass of Animation that will be

    options: heading_level: 3

    options: heading_level: 3

    options: heading_level: 3

    "},{"location":"utilities/fonticon/#superqt.fonticon.Animation","title":"superqt.fonticon.Animation","text":"

    Bases: ABC

    Base icon animation class.

    "},{"location":"utilities/fonticon/#superqt.fonticon.Animation.animate","title":"animate(painter) abstractmethod","text":"

    Setup and start the timer for the animation.

    "},{"location":"utilities/fonticon/#superqt.fonticon.pulse","title":"superqt.fonticon.pulse","text":"

    Bases: spin

    Animation that spins an icon in slower, discrete steps.

    "},{"location":"utilities/fonticon/#superqt.fonticon.spin","title":"superqt.fonticon.spin","text":"

    Bases: Animation

    Animation that smoothly spins an icon.

    "},{"location":"utilities/iconify/","title":"QIconifyIcon","text":"

    Iconify is an icon library that includes 150,000+ icons from most major icon sets including Bootstrap, FontAwesome, Material Design, and many more; each available as individual SVGs. Unlike the superqt.fonticon module, superqt.QIconifyIcon does not require any additional dependencies or font files to be installed. Icons are downloaded (and cached) on-demand from the Iconify API, using pyconify

    Search availble icons at https://icon-sets.iconify.design Once you find one you like, use the key in the format \"prefix:name\" to create an icon: QIconifyIcon(\"bi:bell\").

    "},{"location":"utilities/iconify/#basic-example","title":"Basic Example","text":"
    from qtpy.QtCore import QSize\nfrom qtpy.QtWidgets import QApplication, QPushButton\n\nfrom superqt import QIconifyIcon\n\napp = QApplication([])\n\nbtn = QPushButton()\nbtn.setIcon(QIconifyIcon(\"fluent-emoji-flat:alarm-clock\"))\nbtn.setIconSize(QSize(60, 60))\nbtn.show()\n\napp.exec()\n
    "},{"location":"utilities/iconify/#superqt.QIconifyIcon","title":"superqt.QIconifyIcon","text":"

    Bases: QIcon

    QIcon backed by an iconify icon.

    Iconify includes 150,000+ icons from most major icon sets including Bootstrap, FontAwesome, Material Design, and many more.

    Search availble icons at https://icon-sets.iconify.design Once you find one you like, use the key in the format \"prefix:name\" to create an icon: QIconifyIcon(\"bi:bell\").

    This class is a thin wrapper around the pyconify svg_path function. It pulls SVGs from iconify, creates a temporary SVG file and uses it as the source for a QIcon. SVGs are cached to disk, and persist across sessions (until pyconify.clear_cache() is called).

    Parameters are the same as QIconifyIcon.addKey, which can be used to add additional icons for various modes and states to the same QIcon.

    Parameters:

    Name Type Description Default *key str

    Icon set prefix and name. May be passed as a single string in the format \"prefix:name\" or as two separate strings: 'prefix', 'name'.

    () color str

    Icon color. If not provided, the icon will appear black (the icon fill color will be set to the string \"currentColor\").

    None flip str

    Flip icon. Must be one of \"horizontal\", \"vertical\", \"horizontal,vertical\"

    None rotate str | int

    Rotate icon. Must be one of 0, 90, 180, 270, or 0, 1, 2, 3 (equivalent to 0, 90, 180, 270, respectively)

    None dir str

    If 'dir' is not None, the file will be created in that directory, otherwise a default directory is used.

    None

    Examples:

    >>> from qtpy.QtWidgets import QPushButton\n>>> from superqt import QIconifyIcon\n>>> btn = QPushButton()\n>>> icon = QIconifyIcon(\"bi:alarm-fill\", color=\"red\", rotate=90)\n>>> btn.setIcon(icon)\n
    "},{"location":"utilities/iconify/#superqt.QIconifyIcon.addKey","title":"addKey(*key, color=None, flip=None, rotate=None, dir=None, size=None, mode=QIcon.Mode.Normal, state=QIcon.State.Off)","text":"

    Add an icon to this QIcon.

    This is a variant of QIcon.addFile that uses an iconify icon keys and arguments instead of a file path.

    Parameters:

    Name Type Description Default *key str

    Icon set prefix and name. May be passed as a single string in the format \"prefix:name\" or as two separate strings: 'prefix', 'name'.

    () color str

    Icon color. If not provided, the icon will appear black (the icon fill color will be set to the string \"currentColor\").

    None flip str

    Flip icon. Must be one of \"horizontal\", \"vertical\", \"horizontal,vertical\"

    None rotate str | int

    Rotate icon. Must be one of 0, 90, 180, 270, or 0, 1, 2, 3 (equivalent to 0, 90, 180, 270, respectively)

    None dir str

    If 'dir' is not None, the file will be created in that directory, otherwise a default directory is used.

    None size QSize

    Size specified for the icon, passed to QIcon.addFile.

    None mode Mode

    Mode specified for the icon, passed to QIcon.addFile.

    Normal state State

    State specified for the icon, passed to QIcon.addFile.

    Off

    Returns:

    Type Description QIconifyIcon

    This QIconifyIcon instance, for chaining.

    "},{"location":"utilities/qmessagehandler/","title":"QMessageHandler","text":""},{"location":"utilities/qmessagehandler/#superqt.utils.QMessageHandler","title":"superqt.utils.QMessageHandler","text":"

    A context manager to intercept messages from Qt.

    Parameters:

    Name Type Description Default logger Logger

    If provided, intercepted messages will be logged with logger at the corresponding python log level, by default None

    None

    Attributes:

    Name Type Description records list of tuple

    Captured messages. This is a 3-tuple of: (log_level: int, message: str, context: dict)

    Examples:

    >>> handler = QMessageHandler()\n>>> handler.install()  # now all Qt output will be available at mh.records\n
    >>> with QMessageHandler() as handler:  # temporarily install\n...     ...\n
    >>> logger = logging.getLogger(__name__)\n>>> with QMessageHandler(logger):  # re-reoute Qt messages to a python logger.\n...     ...\n
    "},{"location":"utilities/qmessagehandler/#superqt.utils.QMessageHandler.__enter__","title":"__enter__()","text":"

    Enter a context with this handler installed.

    "},{"location":"utilities/qmessagehandler/#superqt.utils.QMessageHandler.install","title":"install()","text":"

    Install this handler (override the current QtMessageHandler).

    "},{"location":"utilities/qmessagehandler/#superqt.utils.QMessageHandler.uninstall","title":"uninstall()","text":"

    Uninstall this handler, restoring the previous handler.

    "},{"location":"utilities/signal_utils/","title":"Signal Utilities","text":""},{"location":"utilities/signal_utils/#superqt.utils.signals_blocked","title":"superqt.utils.signals_blocked(obj)","text":"

    Context manager to temporarily block signals emitted by QObject: obj.

    Parameters:

    Name Type Description Default obj QObject

    The QObject whose signals should be blocked.

    required

    Examples:

    from qtpy.QtWidgets import QSpinBox\nfrom superqt import signals_blocked\n\nspinbox = QSpinBox()\nwith signals_blocked(spinbox):\n    spinbox.setValue(10)\n
    "},{"location":"utilities/thread_decorators/","title":"Threading decorators","text":"

    superqt provides two decorators that help to ensure that given function is running in the desired thread:

    "},{"location":"utilities/thread_decorators/#ensure_main_thread","title":"ensure_main_thread","text":"

    ensure_main_thread ensures that the decorated function/method runs in the main thread

    "},{"location":"utilities/thread_decorators/#ensure_object_thread","title":"ensure_object_thread","text":"

    ensure_object_thread ensures that a decorated bound method of a QObject runs in the thread in which the instance lives (see qt documentation for details).

    "},{"location":"utilities/thread_decorators/#usage","title":"Usage","text":"

    By default, functions are executed asynchronously (they return immediately with an instance of concurrent.futures.Future).

    To block and wait for the result, see Synchronous mode

    from qtpy.QtCore import QObject\nfrom superqt import ensure_main_thread, ensure_object_thread\n\n@ensure_main_thread\ndef sample_function():\n    print(\"This function will run in main thread\")\n\n\nclass SampleObject(QObject):\n    def __init__(self):\n        super().__init__()\n        self._value = 1\n\n    @ensure_main_thread\n    def sample_method1(self):\n        print(\"This method will run in main thread\")\n\n    @ensure_object_thread\n    def sample_method3(self):\n        import time\n        print(\"sleeping\")\n        time.sleep(1)\n        print(\"This method will run in object thread\")\n\n    @property\n    def value(self):\n        print(\"return value\")\n        return self._value\n\n    @value.setter\n    @ensure_object_thread\n    def value(self, value):\n        print(\"this setter will run in object thread\")\n        self._value = value\n

    As can be seen in this example these decorators can also be used for setters.

    These decorators should not be used as replacement of Qt Signals but rather to interact with Qt objects from non Qt code.

    "},{"location":"utilities/thread_decorators/#synchronous-mode","title":"Synchronous mode","text":"

    If you'd like for the program to block and wait for the result of your function call, use the await_return=True parameter, and optionally specify a timeout.

    Important

    Using synchronous mode may significantly impact performance.

    from superqt import ensure_main_thread\n\n@ensure_main_thread\ndef sample_function1():\n    return 1\n\n@ensure_main_thread(await_return=True)\ndef sample_function2():\n    return 2\n\nassert sample_function1() is None\nassert sample_function2() == 2\n\n# optionally, specify a timeout\n@ensure_main_thread(await_return=True, timeout=10000)\ndef sample_function():\n    return 1\n
    "},{"location":"utilities/threading/","title":"Thread workers","text":"

    The objects in this module provide utilities for running tasks in a separate thread. In general (with the exception of new_worker_qthread), everything here wraps Qt's QRunnable API.

    The highest level object is the @thread_worker decorator. It was originally written for napari, and was later extracted into superqt. You may also be interested in reading the napari documentation on this feature, which provides a more in-depth/introductory usage guide.

    For additional control, you can create your own FunctionWorker or GeneratorWorker objects.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase","title":"superqt.utils.WorkerBase","text":"

    Bases: QRunnable, Generic[_R]

    Base class for creating a Worker that can run in another thread.

    Parameters:

    Name Type Description Default SignalsClass type

    A QObject subclass that contains signals, by default WorkerBaseSignals

    WorkerBaseSignals

    Attributes:

    Name Type Description signals WorkerBaseSignals

    signal emitter object. To allow identify which worker thread emitted signal.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.abort_requested","title":"abort_requested property","text":"

    Whether the worker has been requested to stop.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.is_running","title":"is_running property","text":"

    Whether the worker has been started.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.__getattr__","title":"__getattr__(name)","text":"

    Pass through attr requests to signals to simplify connection API.

    The goal is to enable worker.yielded.connect instead of worker.signals.yielded.connect. Because multiple inheritance of Qt classes is not well supported in PyQt, we have to use composition here (signals are provided by QObjects, and QRunnable is not a QObject). So this passthrough allows us to connect to signals on the _signals object.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.await_workers","title":"await_workers(msecs=None) classmethod","text":"

    Ask all workers to quit, and wait up to msec for quit.

    Attempts to clean up all running workers by calling worker.quit() method. Any workers in the WorkerBase._worker_set set will have this method.

    By default, this function will block indefinitely, until worker threads finish. If a timeout is provided, a RuntimeError will be raised if the workers do not gracefully exit in the time requests, but the threads will NOT be killed. It is (currently) left to the user to use their OS to force-quit rogue threads.

    Important

    If the user does not put any yields in their function, and the function is super long, it will just hang... For instance, there's no graceful way to kill this thread in python:

    @thread_worker\ndef ZZZzzz():\n    time.sleep(10000000)\n

    This is why it's always advisable to use a generator that periodically yields for long-running computations in another thread.

    See this stack-overflow post for a good discussion on the difficulty of killing a rogue python thread:

    Parameters:

    Name Type Description Default msecs int

    Waits up to msecs milliseconds for all threads to exit and removes all threads from the thread pool. If msecs is None (the default), the timeout is ignored (waits for the last thread to exit).

    None

    Raises:

    Type Description RuntimeError

    If a timeout is provided and workers do not quit successfully within the time allotted.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.quit","title":"quit()","text":"

    Send a request to abort the worker.

    Note

    It is entirely up to subclasses to honor this method by checking self.abort_requested periodically in their worker.work method, and exiting if True.

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.run","title":"run()","text":"

    Start the worker.

    The end-user should never need to call this function. But it cannot be made private or renamed, since it is called by Qt.

    The order of method calls when starting a worker is:

       calls QThreadPool.globalInstance().start(worker)\n   |               triggered by the QThreadPool.start() method\n   |               |             called by worker.run\n   |               |             |\n   V               V             V\n   worker.start -> worker.run -> worker.work\n

    This is the function that actually gets called when calling QThreadPool.start(worker). It simply wraps the work() method, and emits a few signals. Subclasses should NOT override this method (except with good reason), and instead should implement work().

    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.start","title":"start()","text":"

    Start this worker in a thread and add it to the global threadpool.

    The order of method calls when starting a worker is:

       calls QThreadPool.globalInstance().start(worker)\n   |               triggered by the QThreadPool.start() method\n   |               |             called by worker.run\n   |               |             |\n   V               V             V\n   worker.start -> worker.run -> worker.work\n
    "},{"location":"utilities/threading/#superqt.utils.WorkerBase.work","title":"work()","text":"

    Main method to execute the worker.

    The end-user should never need to call this function. But subclasses must implement this method (See GeneratorFunction.work for an example implementation). Minimally, it should check self.abort_requested periodically and exit if True.

    Examples:

    class MyWorker(WorkerBase):\n    def work(self):\n        i = 0\n        while True:\n            if self.abort_requested:\n                self.aborted.emit()\n                break\n            i += 1\n            if i > max_iters:\n                break\n            time.sleep(0.5)\n
    "},{"location":"utilities/threading/#superqt.utils.FunctionWorker","title":"superqt.utils.FunctionWorker","text":"

    Bases: WorkerBase[_R]

    QRunnable with signals that wraps a simple long-running function.

    Note

    FunctionWorker does not provide a way to stop a very long-running function (e.g. time.sleep(10000)). So whenever possible, it is better to implement your long running function as a generator that yields periodically, and use the GeneratorWorker instead.

    Parameters:

    Name Type Description Default func Callable

    A function to call in another thread

    required *args

    will be passed to the function

    () **kwargs

    will be passed to the function

    {}

    Raises:

    Type Description TypeError

    If func is a generator function and not a regular function.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker","title":"superqt.utils.GeneratorWorker","text":"

    Bases: WorkerBase, Generic[_Y, _S, _R]

    QRunnable with signals that wraps a long-running generator.

    Provides a convenient way to run a generator function in another thread, while allowing 2-way communication between threads, using plain-python generator syntax in the original function.

    Parameters:

    Name Type Description Default func callable

    The function being run in another thread. May be a generator function.

    required SignalsClass type

    A QObject subclass that contains signals, by default GeneratorWorkerSignals

    GeneratorWorkerSignals *args

    Will be passed to func on instantiation

    () **kwargs

    Will be passed to func on instantiation

    {}"},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.is_paused","title":"is_paused property","text":"

    Whether the worker is currently paused.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.pause","title":"pause()","text":"

    Request to pause the worker.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.resume","title":"resume()","text":"

    Send a request to resume the worker.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.send","title":"send(value)","text":"

    Send a value into the function (if a generator was used).

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.toggle_pause","title":"toggle_pause()","text":"

    Request to pause the worker if playing or resume if paused.

    "},{"location":"utilities/threading/#superqt.utils.GeneratorWorker.work","title":"work()","text":"

    Core event loop that calls the original function.

    Enters a continual loop, yielding and returning from the original function. Checks for various events (quit, pause, resume, etc...). (To clarify: we are creating a rudimentary event loop here because there IS NO Qt event loop running in the other thread to hook into)

    "},{"location":"utilities/threading/#convenience-functions","title":"Convenience functions","text":""},{"location":"utilities/threading/#superqt.utils.thread_worker","title":"superqt.utils.thread_worker(function=None, start_thread=None, connect=None, worker_class=None, ignore_errors=False)","text":"
    thread_worker(\n    function: Callable[_P, Generator[_Y, _S, _R]],\n    start_thread: bool | None = None,\n    connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    worker_class: type[WorkerBase] | None = None,\n    ignore_errors: bool = False,\n) -> Callable[_P, GeneratorWorker[_Y, _S, _R]]\n
    thread_worker(\n    function: Callable[_P, _R],\n    start_thread: bool | None = None,\n    connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    worker_class: type[WorkerBase] | None = None,\n    ignore_errors: bool = False,\n) -> Callable[_P, FunctionWorker[_R]]\n
    thread_worker(\n    function: Literal[None] = None,\n    start_thread: bool | None = None,\n    connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    worker_class: type[WorkerBase] | None = None,\n    ignore_errors: bool = False,\n) -> Callable[\n    [Callable],\n    Callable[_P, FunctionWorker | GeneratorWorker],\n]\n

    Decorator that runs a function in a separate thread when called.

    When called, the decorated function returns a WorkerBase. See create_worker for additional keyword arguments that can be used when calling the function.

    The returned worker will have these signals:

    • started: emitted when the work is started
    • finished: emitted when the work is finished
    • returned: emitted with return value
    • errored: emitted with error object on Exception

    It will also have a worker.start() method that can be used to start execution of the function in another thread. (useful if you need to connect callbacks to signals prior to execution)

    If the decorated function is a generator, the returned worker will also provide these signals:

    • yielded: emitted with yielded values
    • paused: emitted when a running job has successfully paused
    • resumed: emitted when a paused job has successfully resumed
    • aborted: emitted when a running job is successfully aborted

    And these methods:

    • quit: ask the thread to quit
    • toggle_paused: toggle the running state of the thread.
    • send: send a value into the generator. (This requires that your decorator function uses the value = yield syntax)

    Parameters:

    Name Type Description Default function callable

    Function to call in another thread. For communication between threads may be a generator function.

    None start_thread bool

    Whether to immediaetly start the thread. If False, the returned worker must be manually started with worker.start(). by default it will be False if the _connect argument is None, otherwise True.

    None connect Dict[str, Union[Callable, Sequence]]

    A mapping of \"signal_name\" -> callable or list of callable: callback functions to connect to the various signals offered by the worker class. by default None

    None worker_class Type[WorkerBase]

    The WorkerBase to instantiate, by default FunctionWorker will be used if func is a regular function, and GeneratorWorker will be used if it is a generator.

    None ignore_errors bool

    If False (the default), errors raised in the other thread will be reraised in the main thread (makes debugging significantly easier).

    False

    Returns:

    Type Description callable

    function that creates a worker, puts it in a new thread and returns the worker instance.

    Examples:

    @thread_worker\ndef long_function(start, end):\n    # do work, periodically yielding\n    i = start\n    while i <= end:\n        time.sleep(0.1)\n        yield i\n\n    # do teardown\n    return \"anything\"\n\n\n# call the function to start running in another thread.\nworker = long_function()\n\n# connect signals here if desired... or they may be added using the\n# `connect` argument in the `@thread_worker` decorator... in which\n# case the worker will start immediately when long_function() is called\nworker.start()\n
    "},{"location":"utilities/threading/#superqt.utils.create_worker","title":"superqt.utils.create_worker(func, *args, _start_thread=None, _connect=None, _worker_class=None, _ignore_errors=False, **kwargs)","text":"
    create_worker(\n    func: Callable[_P, Generator[_Y, _S, _R]],\n    *args,\n    _start_thread: bool | None = None,\n    _connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    _worker_class: type[GeneratorWorker]\n    | type[FunctionWorker]\n    | None = None,\n    _ignore_errors: bool = False,\n    **kwargs,\n) -> GeneratorWorker[_Y, _S, _R]\n
    create_worker(\n    func: Callable[_P, _R],\n    *args,\n    _start_thread: bool | None = None,\n    _connect: dict[str, Callable | Sequence[Callable]]\n    | None = None,\n    _worker_class: type[GeneratorWorker]\n    | type[FunctionWorker]\n    | None = None,\n    _ignore_errors: bool = False,\n    **kwargs,\n) -> FunctionWorker[_R]\n

    Convenience function to start a function in another thread.

    By default, uses FunctionWorker for functions and GeneratorWorker for generators, but a custom WorkerBase subclass may be provided. If so, it must be a subclass of WorkerBase, which defines a standard set of signals and a run method.

    Parameters:

    Name Type Description Default func Callable

    The function to call in another thread.

    required _start_thread bool

    Whether to immediaetly start the thread. If False, the returned worker must be manually started with worker.start(). by default it will be False if the _connect argument is None, otherwise True.

    None _connect Dict[str, Union[Callable, Sequence]]

    A mapping of \"signal_name\" -> callable or list of callable: callback functions to connect to the various signals offered by the worker class. by default None

    None _worker_class type of `GeneratorWorker` or `FunctionWorker`

    The WorkerBase to instantiate, by default FunctionWorker will be used if func is a regular function, and GeneratorWorker will be used if it is a generator.

    None _ignore_errors bool

    If False (the default), errors raised in the other thread will be reraised in the main thread (makes debugging significantly easier).

    False *args

    will be passed to func

    () **kwargs

    will be passed to func

    {}

    Returns:

    Name Type Description worker WorkerBase

    An instantiated worker. If _start_thread was False, the worker will have a .start() method that can be used to start the thread.

    Raises:

    Type Description TypeError

    If a worker_class is provided that is not a subclass of WorkerBase.

    TypeError

    If _connect is provided and is not a dict of {str: callable}

    Examples:

    def long_function(duration):\n    import time\n\n    time.sleep(duration)\n\n\nworker = create_worker(long_function, 10)\n
    "},{"location":"utilities/threading/#superqt.utils.new_worker_qthread","title":"superqt.utils.new_worker_qthread(Worker, *args, _start_thread=False, _connect=None, **kwargs)","text":"

    Convenience function to start a worker in a QThread.

    thread, not as the actual code or object that runs in that thread. The QThread object is created on the main thread and lives there.

    Worker objects which derive from QObject are the things that actually do the work. They can be moved to a QThread as is done here.

    Mostly ignorable detail

    While the signals/slots syntax of the worker looks very similar to standard \"single-threaded\" signals & slots, note that inter-thread signals and slots (automatically) use an event-based QueuedConnection, while intra-thread signals use a DirectConnection. See Signals and Slots Across Threads

    Parameters:

    Name Type Description Default Worker QObject

    QObject type that implements a work() method. The Worker should also emit a finished signal when the work is done.

    required _start_thread bool

    If True, thread will be started immediately, otherwise, thread must be manually started with thread.start().

    False _connect dict

    Optional dictionary of {signal: function} to connect to the new worker. for instance: _connect = {'incremented': myfunc} will result in: worker.incremented.connect(myfunc)

    None *args

    will be passed to the Worker class on instantiation.

    () **kwargs

    will be passed to the Worker class on instantiation.

    {}

    Returns:

    Name Type Description worker WorkerBase

    The created worker.

    thread QThread

    The thread on which the worker is running.

    Examples:

    Create some QObject that has a long-running work method:

    class Worker(QObject):\n    finished = Signal()\n    increment = Signal(int)\n\n    def __init__(self, argument):\n        super().__init__()\n        self.argument = argument\n\n    @Slot()\n    def work(self):\n        # some long running task...\n        import time\n\n        for i in range(10):\n            time.sleep(1)\n            self.increment.emit(i)\n        self.finished.emit()\n\n\nworker, thread = new_worker_qthread(\n    Worker,\n    \"argument\",\n    _start_thread=True,\n    _connect={\"increment\": print},\n)\n
    "},{"location":"utilities/throttling/","title":"Throttling & Debouncing","text":"

    These utilities allow you to throttle or debounce a function. This is useful when you have a function that is called multiple times in a short period of time, and you want to make sure it is only \"actually\" called once (or at least no more than a certain frequency).

    For background on throttling and debouncing, see:

    • https://blog.openreplay.com/forever-functional-debouncing-and-throttling-for-performance
    • https://css-tricks.com/debouncing-throttling-explained-examples/
    "},{"location":"utilities/throttling/#superqt.utils.qdebounced","title":"superqt.utils.qdebounced(func=None, timeout=100, leading=False, timer_type=Qt.TimerType.PreciseTimer, parent=None)","text":"
    qdebounced(\n    func: Callable[P, R],\n    timeout: int = 100,\n    leading: bool = False,\n    timer_type: Qt.TimerType = Qt.TimerType.PreciseTimer,\n    parent: QObject | None = None,\n) -> ThrottledCallable[P, R]\n
    qdebounced(\n    func: None = ...,\n    timeout: int = 100,\n    leading: bool = False,\n    timer_type: Qt.TimerType = Qt.TimerType.PreciseTimer,\n    parent: QObject | None = None,\n) -> Callable[[Callable[P, R]], ThrottledCallable[P, R]]\n

    Creates a debounced function that delays invoking func.

    func will not be invoked until timeout ms have elapsed since the last time the debounced function was invoked.

    The debounced function comes with a cancel method to cancel delayed func invocations and a flush method to immediately invoke them. Options indicate whether func should be invoked on the leading and/or trailing edge of the wait timeout. The func is invoked with the last arguments provided to the debounced function. Subsequent calls to the debounced function return the result of the last func invocation.

    This decorator may be used with or without parameters.

    Parameters:

    Name Type Description Default func Callable

    A function to throttle

    None timeout int

    Timeout in milliseconds to wait before allowing another call, by default 100

    100 leading bool

    Whether to invoke the function on the leading edge of the wait timer, by default False

    False timer_type TimerType

    The timer type. by default Qt.TimerType.PreciseTimer One of: - Qt.PreciseTimer: Precise timers try to keep millisecond accuracy - Qt.CoarseTimer: Coarse timers try to keep accuracy within 5% of the desired interval - Qt.VeryCoarseTimer: Very coarse timers only keep full second accuracy

    PreciseTimer parent QObject | None

    Parent object for timer. If using qthrottled as function it may be usefull for cleaning data

    None"},{"location":"utilities/throttling/#superqt.utils.qthrottled","title":"superqt.utils.qthrottled(func=None, timeout=100, leading=True, timer_type=Qt.TimerType.PreciseTimer, parent=None)","text":"
    qthrottled(\n    func: Callable[P, R],\n    timeout: int = 100,\n    leading: bool = True,\n    timer_type: Qt.TimerType = Qt.TimerType.PreciseTimer,\n    parent: QObject | None = None,\n) -> ThrottledCallable[P, R]\n
    qthrottled(\n    func: None = ...,\n    timeout: int = 100,\n    leading: bool = True,\n    timer_type: Qt.TimerType = Qt.TimerType.PreciseTimer,\n    parent: QObject | None = None,\n) -> Callable[[Callable[P, R]], ThrottledCallable[P, R]]\n

    Creates a throttled function that invokes func at most once per timeout.

    The throttled function comes with a cancel method to cancel delayed func invocations and a flush method to immediately invoke them. Options to indicate whether func should be invoked on the leading and/or trailing edge of the wait timeout. The func is invoked with the last arguments provided to the throttled function. Subsequent calls to the throttled function return the result of the last func invocation.

    This decorator may be used with or without parameters.

    Parameters:

    Name Type Description Default func Callable

    A function to throttle

    None timeout int

    Timeout in milliseconds to wait before allowing another call, by default 100

    100 leading bool

    Whether to invoke the function on the leading edge of the wait timer, by default True

    True timer_type TimerType

    The timer type. by default Qt.TimerType.PreciseTimer One of: - Qt.PreciseTimer: Precise timers try to keep millisecond accuracy - Qt.CoarseTimer: Coarse timers try to keep accuracy within 5% of the desired interval - Qt.VeryCoarseTimer: Very coarse timers only keep full second accuracy

    PreciseTimer parent QObject | None

    Parent object for timer. If using qthrottled as function it may be usefull for cleaning data

    None"},{"location":"utilities/throttling/#superqt.utils.QSignalDebouncer","title":"superqt.utils.QSignalDebouncer","text":"

    Bases: GenericSignalThrottler

    A Signal Debouncer.

    This object's triggered signal will not be emitted until self.timeout() milliseconds have elapsed since the last time triggered was emitted.

    "},{"location":"utilities/throttling/#superqt.utils.QSignalThrottler","title":"superqt.utils.QSignalThrottler","text":"

    Bases: GenericSignalThrottler

    A Signal Throttler.

    This object's triggered signal will emit at most once per timeout (set with setTimeout()).

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler","title":"superqt.utils._throttler.GenericSignalThrottler","text":"

    Bases: QObject

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.cancel","title":"cancel()","text":"

    Cancel any pending emissions.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.emissionPolicy","title":"emissionPolicy()","text":"

    Return the emission policy (trailing or leading).

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.flush","title":"flush(restart_timer=True)","text":"

    Force emission of any pending emissions.

    Parameters:

    Name Type Description Default restart_timer bool

    Whether to restart the timer after flushing. Defaults to True.

    True"},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.kind","title":"kind()","text":"

    Return the kind of throttler (throttler or debouncer).

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.setTimeout","title":"setTimeout(timeout)","text":"

    Set timeout in milliseconds.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.setTimerType","title":"setTimerType(timerType)","text":"

    Set current Qt.TimerType.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.throttle","title":"throttle()","text":"

    Emit triggered if not running, then start timer.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.timeout","title":"timeout()","text":"

    Return current timeout in milliseconds.

    "},{"location":"utilities/throttling/#superqt.utils._throttler.GenericSignalThrottler.timerType","title":"timerType()","text":"

    Return current Qt.TimerType.

    "},{"location":"widgets/","title":"Widgets","text":"

    The following are QWidget subclasses:

    "},{"location":"widgets/#sliders-and-numerical-inputs","title":"Sliders and Numerical Inputs","text":"Widget Description QDoubleRangeSlider Multi-handle slider for float values QDoubleSlider Slider for float values QLabeledDoubleRangeSlider QDoubleRangeSlider variant with editable labels for each handle QLabeledDoubleSlider QSlider for float values with editable QSpinBox with the current value QLabeledRangeSlider QRangeSlider variant, with editable labels for each handle QLabeledSlider QSlider with editable QSpinBox that shows the current value QLargeIntSpinBox QSpinbox that accepts arbitrarily large integers QRangeSlider Multi-handle slider QQuantity Pint-backed quantity widget (magnitude combined with unit dropdown)"},{"location":"widgets/#labels-and-categorical-inputs","title":"Labels and categorical inputs","text":"Widget Description QElidingLabel A QLabel variant that will elide text (add \u2026) to fit width. QEnumComboBox QComboBox that populates the combobox from a python Enum QSearchableComboBox QComboBox variant that filters available options based on text input QSearchableListWidget QListWidget variant with search field that filters available options QSearchableTreeWidget QTreeWidget variant with search field that filters available options QColorComboBox QComboBox to select from a specified set of colors QColormapComboBox QComboBox to select from a specified set of colormaps."},{"location":"widgets/#frames-and-containers","title":"Frames and containers","text":"Widget Description QCollapsible A collapsible widget to hide and unhide child widgets. QFlowLayout A layout that rearranges items based on parent width."},{"location":"widgets/colormap_catalog/","title":"CmapCatalogComboBox","text":"

    Searchable QComboBox variant that contains the entire cmap colormap catalog

    requires cmap

    This widget uses the cmap library to provide colormaps. You can install it with:

    # use the `cmap` extra to include colormap support\npip install superqt[cmap]\n

    You can limit the colormaps shown by setting the categories or interpolation keyword arguments.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt.cmap import CmapCatalogComboBox\n\napp = QApplication([])\n\ncatalog_combo = CmapCatalogComboBox(interpolation=\"linear\")\ncatalog_combo.setCurrentText(\"viridis\")\ncatalog_combo.show()\n\napp.exec()\n

    "},{"location":"widgets/colormap_catalog/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/colormap_catalog/#signals","title":"Signals","text":""},{"location":"widgets/colormap_catalog/#currentcolormapchanged","title":"currentColormapChanged","text":""},{"location":"widgets/colormap_catalog/#methods","title":"Methods","text":"

    A combo box for selecting a colormap from the entire cmap catalog.

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget.

    None prefer_short_names bool

    If True (default), short names (without the namespace prefix) will be preferred over fully qualified names. In cases where the same short name is used in multiple namespaces, they will all be referred to by their fully qualified (namespaced) name.

    True categories Container[Category]

    If provided, only return names from the given categories.

    () interpolation Interpolation

    If provided, only return names that have the given interpolation method.

    None"},{"location":"widgets/colormap_catalog/#superqt.cmap.CmapCatalogComboBox.currentColormap","title":"currentColormap() -> Colormap | None","text":"

    Returns the currently selected Colormap or None if not yet selected.

    "},{"location":"widgets/qcollapsible/","title":"QCollapsible","text":"

    Collapsible QFrame that can be expanded or collapsed by clicking on the header.

    from qtpy.QtWidgets import QApplication, QLabel, QPushButton\n\nfrom superqt import QCollapsible\n\napp = QApplication([])\n\ncollapsible = QCollapsible(\"Advanced analysis\")\ncollapsible.addWidget(QLabel(\"This is the inside of the collapsible frame\"))\nfor i in range(10):\n    collapsible.addWidget(QPushButton(f\"Content button {i + 1}\"))\n\ncollapsible.expand(animate=False)\ncollapsible.show()\napp.exec_()\n

    "},{"location":"widgets/qcollapsible/#qt-class","title":"Qt Class","text":"

    QFrame

    "},{"location":"widgets/qcollapsible/#signals","title":"Signals","text":""},{"location":"widgets/qcollapsible/#toggled","title":"toggled","text":""},{"location":"widgets/qcollapsible/#methods","title":"Methods","text":"

    A collapsible widget to hide and unhide child widgets.

    A signal is emitted when the widget is expanded (True) or collapsed (False).

    Based on https://stackoverflow.com/a/68141638

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.addWidget","title":"addWidget(widget: QWidget) -> None","text":"

    Add a widget to the central content widget's layout.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.collapse","title":"collapse(animate: bool = True) -> None","text":"

    Collapse (hide) the collapsible section.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.collapsedIcon","title":"collapsedIcon() -> QIcon","text":"

    Returns the icon used when the widget is collapsed.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.content","title":"content() -> QWidget","text":"

    Return the current content widget.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.expand","title":"expand(animate: bool = True) -> None","text":"

    Expand (show) the collapsible section.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.expandedIcon","title":"expandedIcon() -> QIcon","text":"

    Returns the icon used when the widget is expanded.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.isExpanded","title":"isExpanded() -> bool","text":"

    Return whether the collapsible section is visible.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.locked","title":"locked() -> bool","text":"

    Return True if collapse/expand is disabled.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.removeWidget","title":"removeWidget(widget: QWidget) -> None","text":"

    Remove widget from the central content widget's layout.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setCollapsedIcon","title":"setCollapsedIcon(icon: QIcon | str | None = None) -> None","text":"

    Set the icon on the toggle button when the widget is collapsed.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setContent","title":"setContent(content: QWidget) -> None","text":"

    Replace central widget (the widget that gets expanded/collapsed).

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setDuration","title":"setDuration(msecs: int) -> None","text":"

    Set duration of the collapse/expand animation.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setEasingCurve","title":"setEasingCurve(easing: QEasingCurve | QEasingCurve.Type) -> None","text":"

    Set the easing curve for the collapse/expand animation.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setExpandedIcon","title":"setExpandedIcon(icon: QIcon | str | None = None) -> None","text":"

    Set the icon on the toggle button when the widget is expanded.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setLocked","title":"setLocked(locked: bool = True) -> None","text":"

    Set whether collapse/expand is disabled.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.setText","title":"setText(text: str) -> None","text":"

    Set the text of the toggle button.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.text","title":"text() -> str","text":"

    Return the text of the toggle button.

    "},{"location":"widgets/qcollapsible/#superqt.QCollapsible.toggleButton","title":"toggleButton() -> QPushButton","text":"

    Return the toggle button.

    "},{"location":"widgets/qcolorcombobox/","title":"QColorComboBox","text":"

    QComboBox designed to select from a specific set of colors.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QColorComboBox\n\napp = QApplication([])\n\ncolors = QColorComboBox()\ncolors.addColors(['red', 'green', 'blue'])\n\n# show an \"Add Color\" item that opens a QColorDialog when clicked\ncolors.setUserColorsAllowed(True)\n\n# emits a QColor when changed\ncolors.currentColorChanged.connect(print)\ncolors.show()\n\napp.exec_()\n

    "},{"location":"widgets/qcolorcombobox/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/qcolorcombobox/#signals","title":"Signals","text":""},{"location":"widgets/qcolorcombobox/#currentcolorchanged","title":"currentColorChanged","text":""},{"location":"widgets/qcolorcombobox/#enums","title":"Enums","text":""},{"location":"widgets/qcolorcombobox/#qcolorcomboboxinvalidcolorpolicy","title":"QColorComboBox.InvalidColorPolicy","text":"
    • Ignore

    • Warn

    • Raise

    "},{"location":"widgets/qcolorcombobox/#methods","title":"Methods","text":"

    A drop down menu for selecting colors.

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget.

    None allow_user_colors bool

    Whether to show an \"Add Color\" item that opens a QColorDialog when clicked. Whether the user can add custom colors by clicking the \"Add Color\" item. Default is False. Can also be set with setUserColorsAllowed.

    False add_color_text str

    The text to display for the \"Add Color\" item. Default is \"Add Color...\".

    'Add Color...'"},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.addColor","title":"addColor(color: Any) -> None","text":"

    Adds the color to the QComboBox.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.addColors","title":"addColors(colors: Sequence[Any]) -> None","text":"

    Adds colors to the QComboBox.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.currentColor","title":"currentColor() -> QColor | None","text":"

    Returns the currently selected QColor or None if not yet selected.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.currentColorName","title":"currentColorName() -> str | None","text":"

    Returns the name of the currently selected QColor or black if None.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.invalidColorPolicy","title":"invalidColorPolicy() -> InvalidColorPolicy","text":"

    Returns the policy for handling invalid colors.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.itemColor","title":"itemColor(index: int) -> QColor | None","text":"

    Returns the color of the item at the given index.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.setCurrentColor","title":"setCurrentColor(color: Any) -> None","text":"

    Adds the color to the QComboBox and selects it.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.setInvalidColorPolicy","title":"setInvalidColorPolicy(policy: InvalidColorPolicy | int | Literal['Raise', 'Ignore', 'Warn']) -> None","text":"

    Sets the policy for handling invalid colors.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.setUserColorsAllowed","title":"setUserColorsAllowed(allow: bool) -> None","text":"

    Sets whether the user can add custom colors.

    "},{"location":"widgets/qcolorcombobox/#superqt.QColorComboBox.userColorsAllowed","title":"userColorsAllowed() -> bool","text":"

    Returns whether the user can add custom colors.

    "},{"location":"widgets/qcolormap/","title":"QColormapComboBox","text":"

    QComboBox variant to select from a specific set of colormaps.

    requires cmap

    This widget uses the cmap library to provide colormaps. You can install it with:

    # use the `cmap` extra to include colormap support\npip install superqt[cmap]\n
    "},{"location":"widgets/qcolormap/#colormaplike-objects","title":"ColorMapLike objects","text":"

    Colormaps may be specified in a variety of ways, such as by name (string), an iterable of a color/color-like objects, or as a cmap.Colormap instance. See cmap documentation for details on all ColormapLike types

    "},{"location":"widgets/qcolormap/#example","title":"Example","text":"
    from cmap import Colormap\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QColormapComboBox\n\napp = QApplication([])\n\ncmap_combo = QColormapComboBox()\n# see note above about colormap-like objects\n# as names from the cmap catalog\ncmap_combo.addColormaps([\"viridis\", \"plasma\", \"magma\", \"gray\"])\n# as a sequence of colors, linearly interpolated\ncmap_combo.addColormap((\"#0f0\", \"slateblue\", \"#F3A003A0\"))\n# as a `cmap.Colormap` instance with custom name:\ncmap_combo.addColormap(Colormap((\"green\", \"white\", \"orange\"), name=\"MyMap\"))\n\ncmap_combo.show()\napp.exec()\n
    "},{"location":"widgets/qcolormap/#style-customization","title":"Style Customization","text":"

    Note that both the LineEdit and the dropdown can be styled to have the colormap on the left, or fill the entire width of the widget.

    To make the CombBox label colormap fill the entire width of the widget:

    from superqt.cmap import QColormapLineEdit\ncmap_combo.setLineEdit(QColormapLineEdit())\n

    To make the CombBox dropdown colormaps fill less than the entire width of the widget:

    from superqt.cmap import QColormapItemDelegate\ndelegate = QColormapItemDelegate(fractional_colormap_width=0.33)\ncmap_combo.setItemDelegate(delegate)\n
    "},{"location":"widgets/qcolormap/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/qcolormap/#signals","title":"Signals","text":""},{"location":"widgets/qcolormap/#currentcolormapchanged","title":"currentColormapChanged","text":""},{"location":"widgets/qcolormap/#methods","title":"Methods","text":"

    A drop down menu for selecting colors.

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget.

    None allow_user_colormaps bool

    Whether the user can add custom colormaps by clicking the \"Add Colormap...\" item. Default is False. Can also be set with setUserAdditionsAllowed.

    False add_colormap_text str

    The text to display for the \"Add Colormap...\" item. Default is \"Add Colormap...\".

    'Add Colormap...'"},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.addColormap","title":"addColormap(cmap: ColorStopsLike) -> None","text":"

    Adds the colormap to the QComboBox.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.addColormaps","title":"addColormaps(colors: Sequence[Any]) -> None","text":"

    Adds colors to the QComboBox.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.currentColormap","title":"currentColormap() -> Colormap | None","text":"

    Returns the currently selected Colormap or None if not yet selected.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.itemColormap","title":"itemColormap(index: int) -> Colormap | None","text":"

    Returns the color of the item at the given index.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.setCurrentColormap","title":"setCurrentColormap(color: Any) -> None","text":"

    Adds the color to the QComboBox and selects it.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.setUserAdditionsAllowed","title":"setUserAdditionsAllowed(allow: bool) -> None","text":"

    Sets whether the user can add custom colors.

    If enabled, an \"Add Colormap...\" item will be added to the end of the list. When clicked, a dialog will be shown to allow the user to select a colormap from the cmap catalog.

    "},{"location":"widgets/qcolormap/#superqt.QColormapComboBox.userAdditionsAllowed","title":"userAdditionsAllowed() -> bool","text":"

    Returns whether the user can add custom colors.

    "},{"location":"widgets/qdoublerangeslider/","title":"QDoubleRangeSlider","text":"

    Float variant of QRangeSlider. (see that page for more details).

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QDoubleRangeSlider\n\napp = QApplication([])\n\nslider = QDoubleRangeSlider(Qt.Orientation.Horizontal)\nslider.setRange(0, 1)\nslider.setValue((0.2, 0.8))\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qdoublerangeslider/#qt-class","title":"Qt Class","text":"

    QSlider

    "},{"location":"widgets/qdoublerangeslider/#methods","title":"Methods","text":""},{"location":"widgets/qdoubleslider/","title":"QDoubleSlider","text":"

    QSlider variant that accepts floating point values.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QDoubleSlider\n\napp = QApplication([])\n\nslider = QDoubleSlider(Qt.Orientation.Horizontal)\nslider.setRange(0, 1)\nslider.setValue(0.5)\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qdoubleslider/#qt-class","title":"Qt Class","text":"

    QSlider

    "},{"location":"widgets/qdoubleslider/#methods","title":"Methods","text":""},{"location":"widgets/qelidinglabel/","title":"QElidingLabel","text":"

    QLabel variant that will elide text (i.e. add an ellipsis) if it is too long to fit in the available space.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QElidingLabel\n\napp = QApplication([])\n\nwidget = QElidingLabel(\n    \"a skj skjfskfj sdlf sdfl sdlfk jsdf sdlkf jdsf dslfksdl sdlfk sdf sdl \"\n    \"fjsdlf kjsdlfk laskdfsal as lsdfjdsl kfjdslf asfd dslkjfldskf sdlkfj\"\n)\nwidget.setWordWrap(True)\nwidget.resize(300, 20)\nwidget.show()\n\napp.exec_()\n

    "},{"location":"widgets/qelidinglabel/#qt-class","title":"Qt Class","text":"

    QLabel

    "},{"location":"widgets/qelidinglabel/#methods","title":"Methods","text":"

    A QLabel variant that will elide text (could add '\u2026') to fit width.

    QElidingLabel() QElidingLabel(parent: Optional[QWidget], f: Qt.WindowFlags = ...) QElidingLabel(text: str, parent: Optional[QWidget] = None, f: Qt.WindowFlags = ...)

    For a multiline eliding label, use setWordWrap(True). In this case, text will wrap to fit the width, and only the last line will be elided. When wordWrap() is True, sizeHint() will return the size required to fit the full text.

    "},{"location":"widgets/qelidinglabel/#superqt.QElidingLabel.setElideMode","title":"setElideMode(mode: Qt.TextElideMode) -> None","text":"

    Set the elide mode to a Qt.TextElideMode.

    "},{"location":"widgets/qelidinglabel/#superqt.QElidingLabel.setEllipsesWidth","title":"setEllipsesWidth(width: int) -> None","text":"

    A width value to take into account ellipses width when eliding text.

    The value is deducted from the widget width when computing the elided version of the text.

    "},{"location":"widgets/qenumcombobox/","title":"QEnumComboBox","text":"

    QEnumComboBox is a variant of QComboBox that populates the items in the combobox based on a python Enum class. In addition to all the methods provided by QComboBox, this subclass adds the methods enumClass/setEnumClass to get/set the current Enum class represented by the combobox, and currentEnum/setCurrentEnum to get/set the current Enum member in the combobox. There is also a new signal currentEnumChanged(enum) analogous to currentIndexChanged and currentTextChanged.

    Method like insertItem and addItem are blocked and try of its usage will end with RuntimeError

    from enum import Enum\n\nfrom qtpy.QtWidgets import QApplication\nfrom superqt import QEnumComboBox\n\n\nclass SampleEnum(Enum):\n    first = 1\n    second = 2\n    third = 3\n\napp = QApplication([])\n\ncombo = QEnumComboBox()\ncombo.setEnumClass(SampleEnum)\ncombo.show()\n\napp.exec_()\n

    Another option is to use optional enum_class argument of constructor and change

    # option A:\ncombo = QEnumComboBox()\ncombo.setEnumClass(SampleEnum)\n# option B:\ncombo = QEnumComboBox(enum_class=SampleEnum)\n
    "},{"location":"widgets/qenumcombobox/#allow-none","title":"Allow None","text":"

    QEnumComboBox also allows using Optional type annotation:

    from enum import Enum\n\nfrom superqt import QEnumComboBox\n\nclass SampleEnum(Enum):\n    first = 1\n    second = 2\n    third = 3\n\n# as usual:\n# you must create a QApplication before create a widget.\n\ncombo = QEnumComboBox()\ncombo.setEnumClass(SampleEnum, allow_none=True)\n

    In this case there is added option ---- and the currentEnum() method will return None when it is selected.

    "},{"location":"widgets/qenumcombobox/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/qenumcombobox/#signals","title":"Signals","text":""},{"location":"widgets/qenumcombobox/#currentenumchanged","title":"currentEnumChanged","text":""},{"location":"widgets/qenumcombobox/#methods","title":"Methods","text":"

    ComboBox presenting options from a python Enum.

    If the Enum class does not implement __str__ then a human readable name is created from the name of the enum member, replacing underscores with spaces.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.currentEnum","title":"currentEnum() -> Optional[EnumType]","text":"

    Current value as Enum member.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.enumClass","title":"enumClass() -> Optional[EnumMeta]","text":"

    Return current Enum class.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.isOptional","title":"isOptional() -> bool","text":"

    Return if current enum is with optional annotation.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.setCurrentEnum","title":"setCurrentEnum(value: Optional[EnumType]) -> None","text":"

    Set value with Enum.

    "},{"location":"widgets/qenumcombobox/#superqt.QEnumComboBox.setEnumClass","title":"setEnumClass(enum: Optional[EnumMeta], allow_none=False)","text":"

    Set enum class from which members value should be selected.

    "},{"location":"widgets/qflowlayout/","title":"QFlowLayout","text":"

    QLayout that rearranges items based on parent width.

    from qtpy.QtWidgets import QApplication, QPushButton, QWidget\n\nfrom superqt import QFlowLayout\n\napp = QApplication([])\n\nwdg = QWidget()\n\nlayout = QFlowLayout(wdg)\nlayout.addWidget(QPushButton(\"Short\"))\nlayout.addWidget(QPushButton(\"Longer\"))\nlayout.addWidget(QPushButton(\"Different text\"))\nlayout.addWidget(QPushButton(\"More text\"))\nlayout.addWidget(QPushButton(\"Even longer button text\"))\n\nwdg.setWindowTitle(\"Flow Layout\")\nwdg.show()\n\napp.exec()\n

    "},{"location":"widgets/qflowlayout/#qt-class","title":"Qt Class","text":"

    QLayout

    "},{"location":"widgets/qflowlayout/#methods","title":"Methods","text":"

    Layout that handles different window sizes.

    The widget placement changes depending on the width of the application window.

    Code translated from C++ at: https://code.qt.io/cgit/qt/qtbase.git/tree/examples/widgets/layouts/flowlayout

    described at: https://doc.qt.io/qt-6/qtwidgets-layouts-flowlayout-example.html

    See also: https://doc.qt.io/qt-6/layout.html

    Parameters:

    Name Type Description Default parent QWidget

    The parent widget, by default None

    None"},{"location":"widgets/qflowlayout/#superqt.QFlowLayout.horizontalSpacing","title":"horizontalSpacing() -> int","text":"

    Return the horizontal spacing.

    "},{"location":"widgets/qflowlayout/#superqt.QFlowLayout.setHorizontalSpacing","title":"setHorizontalSpacing(space: int | None) -> None","text":"

    Set the horizontal spacing.

    If None or -1, the spacing is set to the default value based on the style of the parent widget.

    "},{"location":"widgets/qflowlayout/#superqt.QFlowLayout.setVerticalSpacing","title":"setVerticalSpacing(space: int | None) -> None","text":"

    Set the vertical spacing.

    If None or -1, the spacing is set to the default value based on the style of the parent widget.

    "},{"location":"widgets/qflowlayout/#superqt.QFlowLayout.verticalSpacing","title":"verticalSpacing() -> int","text":"

    Return the vertical spacing.

    "},{"location":"widgets/qlabeleddoublerangeslider/","title":"QLabeledDoubleRangeSlider","text":"

    Labeled Float variant of QRangeSlider. (see that page for more details).

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLabeledDoubleRangeSlider\n\napp = QApplication([])\n\nslider = QLabeledDoubleRangeSlider(Qt.Orientation.Horizontal)\nslider.setRange(0, 1)\nslider.setValue((0.2, 0.8))\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlabeleddoublerangeslider/#qt-class","title":"Qt Class","text":"

    QAbstractSlider

    "},{"location":"widgets/qlabeleddoublerangeslider/#enums","title":"Enums","text":""},{"location":"widgets/qlabeleddoublerangeslider/#qlabeleddoublerangesliderlabelposition","title":"QLabeledDoubleRangeSlider.LabelPosition","text":"
    • NoLabel

    • LabelsAbove

    • LabelsBelow

    • LabelsOnHandle

    "},{"location":"widgets/qlabeleddoublerangeslider/#qlabeleddoublerangeslideredgelabelmode","title":"QLabeledDoubleRangeSlider.EdgeLabelMode","text":"
    • LabelIsRange

    • LabelIsValue

    "},{"location":"widgets/qlabeleddoublerangeslider/#methods","title":"Methods","text":""},{"location":"widgets/qlabeleddoublerangeslider/#superqt.QLabeledDoubleRangeSlider.barColor","title":"barColor = Property(QtGui.QBrush, _getBarColor, _setBarColor) class-attribute instance-attribute","text":"

    The color of the bar between the first and last handle.

    "},{"location":"widgets/qlabeleddoublerangeslider/#superqt.QLabeledDoubleRangeSlider.decimals","title":"decimals() -> int","text":""},{"location":"widgets/qlabeleddoublerangeslider/#superqt.QLabeledDoubleRangeSlider.setDecimals","title":"setDecimals(prec: int) -> None","text":""},{"location":"widgets/qlabeleddoubleslider/","title":"QLabeledDoubleSlider","text":"

    QDoubleSlider variant that shows an editable (SpinBox) label next to the slider.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLabeledDoubleSlider\n\napp = QApplication([])\n\nslider = QLabeledDoubleSlider(Qt.Orientation.Horizontal)\nslider.setRange(0, 2.5)\nslider.setValue(1.3)\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlabeleddoubleslider/#qt-class","title":"Qt Class","text":"

    QAbstractSlider

    "},{"location":"widgets/qlabeleddoubleslider/#enums","title":"Enums","text":""},{"location":"widgets/qlabeleddoubleslider/#qlabeleddoubleslideredgelabelmode","title":"QLabeledDoubleSlider.EdgeLabelMode","text":"
    • LabelIsRange

    • LabelIsValue

    "},{"location":"widgets/qlabeleddoubleslider/#methods","title":"Methods","text":""},{"location":"widgets/qlabeleddoubleslider/#superqt.QLabeledDoubleSlider.decimals","title":"decimals() -> int","text":""},{"location":"widgets/qlabeleddoubleslider/#superqt.QLabeledDoubleSlider.setDecimals","title":"setDecimals(prec: int) -> None","text":""},{"location":"widgets/qlabeledrangeslider/","title":"QLabeledRangeSlider","text":"

    Labeled variant of QRangeSlider. (see that page for more details).

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLabeledRangeSlider\n\napp = QApplication([])\n\nslider = QLabeledRangeSlider(Qt.Orientation.Horizontal)\nslider.setValue((20, 80))\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlabeledrangeslider/#qt-class","title":"Qt Class","text":"

    QAbstractSlider

    "},{"location":"widgets/qlabeledrangeslider/#signals","title":"Signals","text":""},{"location":"widgets/qlabeledrangeslider/#editingfinished","title":"editingFinished","text":""},{"location":"widgets/qlabeledrangeslider/#enums","title":"Enums","text":""},{"location":"widgets/qlabeledrangeslider/#qlabeledrangesliderlabelposition","title":"QLabeledRangeSlider.LabelPosition","text":"
    • NoLabel

    • LabelsAbove

    • LabelsBelow

    • LabelsOnHandle

    "},{"location":"widgets/qlabeledrangeslider/#qlabeledrangeslideredgelabelmode","title":"QLabeledRangeSlider.EdgeLabelMode","text":"
    • LabelIsRange

    • LabelIsValue

    "},{"location":"widgets/qlabeledrangeslider/#methods","title":"Methods","text":"

    If you find that you need to fine tune the position of the handle labels:

    • QLabeledRangeSlider.label_shift_x: adjust horizontal label position
    • QLabeledRangeSlider.label_shift_y: adjust vertical label position
    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.barColor","title":"barColor = Property(QtGui.QBrush, _getBarColor, _setBarColor) class-attribute instance-attribute","text":"

    The color of the bar between the first and last handle.

    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.edgeLabelMode","title":"edgeLabelMode() -> EdgeLabelMode","text":"

    Return current EdgeLabelMode.

    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.handleLabelPosition","title":"handleLabelPosition() -> LabelPosition","text":"

    Return where/whether labels are shown adjacent to slider handles.

    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.setEdgeLabelMode","title":"setEdgeLabelMode(opt: EdgeLabelMode) -> None","text":"

    Set EdgeLabelMode, controls what is shown at the min/max labels.

    "},{"location":"widgets/qlabeledrangeslider/#superqt.QLabeledRangeSlider.setHandleLabelPosition","title":"setHandleLabelPosition(opt: LabelPosition) -> None","text":"

    Set where/whether labels are shown adjacent to slider handles.

    "},{"location":"widgets/qlabeledslider/","title":"QLabeledSlider","text":"

    QSlider variant that shows an editable (SpinBox) label next to the slider.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLabeledSlider\n\napp = QApplication([])\n\nslider = QLabeledSlider(Qt.Orientation.Horizontal)\nslider.setValue(42)\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlabeledslider/#qt-class","title":"Qt Class","text":"

    QAbstractSlider

    "},{"location":"widgets/qlabeledslider/#signals","title":"Signals","text":""},{"location":"widgets/qlabeledslider/#editingfinished","title":"editingFinished","text":""},{"location":"widgets/qlabeledslider/#enums","title":"Enums","text":""},{"location":"widgets/qlabeledslider/#qlabeledslideredgelabelmode","title":"QLabeledSlider.EdgeLabelMode","text":"
    • LabelIsRange

    • LabelIsValue

    "},{"location":"widgets/qlabeledslider/#methods","title":"Methods","text":""},{"location":"widgets/qlabeledslider/#superqt.QLabeledSlider.edgeLabelMode","title":"edgeLabelMode() -> EdgeLabelMode","text":"

    Return current EdgeLabelMode.

    "},{"location":"widgets/qlabeledslider/#superqt.QLabeledSlider.setEdgeLabelMode","title":"setEdgeLabelMode(opt: EdgeLabelMode) -> None","text":"

    Set the EdgeLabelMode.

    Parameters:

    Name Type Description Default opt EdgeLabelMode

    To show no label, use EdgeLabelMode.NoLabel. To show the value of the slider, use EdgeLabelMode.LabelIsValue. To show value / maximum, use EdgeLabelMode.LabelIsValue | EdgeLabelMode.LabelIsRange.

    required"},{"location":"widgets/qlargeintspinbox/","title":"QLargeIntSpinBox","text":"

    QSpinBox variant that allows to enter large integers, without overflow.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QLargeIntSpinBox\n\napp = QApplication([])\n\nslider = QLargeIntSpinBox()\nslider.setRange(0, 4.53e8)\nslider.setValue(4.53e8)\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qlargeintspinbox/#qt-class","title":"Qt Class","text":"

    QAbstractSpinBox

    "},{"location":"widgets/qlargeintspinbox/#signals","title":"Signals","text":""},{"location":"widgets/qlargeintspinbox/#valuechanged","title":"valueChanged","text":""},{"location":"widgets/qlargeintspinbox/#textchanged","title":"textChanged","text":""},{"location":"widgets/qlargeintspinbox/#methods","title":"Methods","text":"

    An integer spinboxes backed by unbound python integer.

    Qt's built-in QSpinBox is backed by a signed 32-bit integer. This could become limiting, particularly in large dense segmentations. This class behaves like a QSpinBox backed by an unbound python int.

    Does not yet support \"prefix\", \"suffix\" or \"specialValue\" like QSpinBox.

    "},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.maximum","title":"maximum()","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.minimum","title":"minimum()","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setMaximum","title":"setMaximum(max)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setMinimum","title":"setMinimum(min)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setRange","title":"setRange(minimum, maximum)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setSingleStep","title":"setSingleStep(step)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setStepType","title":"setStepType(stepType: QAbstractSpinBox.StepType) -> None","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.setValue","title":"setValue(value)","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.singleStep","title":"singleStep()","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.stepType","title":"stepType() -> QAbstractSpinBox.StepType","text":""},{"location":"widgets/qlargeintspinbox/#superqt.QLargeIntSpinBox.value","title":"value()","text":""},{"location":"widgets/qquantity/","title":"QQuantity","text":"

    A widget that allows the user to edit a quantity (a magnitude associated with a unit).

    Note

    This widget requires pint:

    pip install pint\n

    or

    pip install superqt[quantity]\n
    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QQuantity\n\napp = QApplication([])\nw = QQuantity(\"1m\")\nw.show()\n\napp.exec()\n

    "},{"location":"widgets/qquantity/#qt-class","title":"Qt Class","text":"

    QWidget

    "},{"location":"widgets/qquantity/#signals","title":"Signals","text":""},{"location":"widgets/qquantity/#unitschanged","title":"unitsChanged","text":""},{"location":"widgets/qquantity/#valuechanged","title":"valueChanged","text":""},{"location":"widgets/qquantity/#dimensionalitychanged","title":"dimensionalityChanged","text":""},{"location":"widgets/qquantity/#methods","title":"Methods","text":"

    A combination QDoubleSpinBox and QComboBox for entering quantities.

    For this widget, value() returns a pint.Quantity object, while setValue() accepts either a number, pint.Quantity, a string that can be parsed by pint.

    Parameters:

    Name Type Description Default value Union[str, Quantity, Number]

    The initial value to display. If a string, it will be parsed by pint.

    0 units Union[UnitsContainer, str, Quantity]

    The units to use if value is a number. If a string, it will be parsed by pint. If a pint.Quantity, the units will be extracted from it.

    None ureg UnitRegistry

    The unit registry to use. If not provided, the registry will be extracted from value if it is a pint.Quantity, otherwise the default registry will be used.

    None parent QWidget

    The parent widget, by default None

    None"},{"location":"widgets/qquantity/#superqt.QQuantity.dimensionality","title":"dimensionality() -> UnitsContainer","text":"

    Return the current dimensionality (cast to str for nice repr).

    "},{"location":"widgets/qquantity/#superqt.QQuantity.isDimensionless","title":"isDimensionless() -> bool","text":"

    Return True if the current value is dimensionless.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.magnitude","title":"magnitude() -> Union[float, int]","text":"

    Return the magnitude of the current value.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.magnitudeSpinBox","title":"magnitudeSpinBox() -> QDoubleSpinBox","text":"

    Return the QSpinBox widget used to edit the magnitude.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.setDecimals","title":"setDecimals(decimals: int) -> None","text":"

    Set the number of decimals to display in the spinbox.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.setMagnitude","title":"setMagnitude(magnitude: Number) -> None","text":"

    Set the magnitude of the current value.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.setUnits","title":"setUnits(units: Union[str, Unit, Quantity]) -> None","text":"

    Set the units of the current value.

    If units is None, will convert to a dimensionless quantity. Otherwise, units must be compatible with the current dimensionality.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.setValue","title":"setValue(value: Union[str, Quantity, Number], units: Optional[Union[UnitsContainer, str, Quantity]] = None) -> None","text":"

    Set the current value (will cast to a pint Quantity).

    "},{"location":"widgets/qquantity/#superqt.QQuantity.text","title":"text() -> str","text":""},{"location":"widgets/qquantity/#superqt.QQuantity.unitRegistry","title":"unitRegistry() -> UnitRegistry","text":"

    Return the pint UnitRegistry used by this widget.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.units","title":"units() -> Unit","text":"

    Return the current units.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.unitsComboBox","title":"unitsComboBox() -> QComboBox","text":"

    Return the QCombBox widget used to edit the units.

    "},{"location":"widgets/qquantity/#superqt.QQuantity.value","title":"value() -> Quantity","text":"

    Return the current value as a pint.Quantity.

    "},{"location":"widgets/qrangeslider/","title":"QRangeSlider","text":"

    A multi-handle slider widget than can be used to select a range of values.

    from qtpy.QtCore import Qt\nfrom qtpy.QtWidgets import QApplication\n\nfrom superqt import QRangeSlider\n\napp = QApplication([])\n\nslider = QRangeSlider(Qt.Orientation.Horizontal)\nslider.setValue((20, 80))\nslider.show()\n\napp.exec_()\n

    • QRangeSlider inherits from QSlider and attempts to match the Qt API as closely as possible
    • It uses platform-specific styles (for handle, groove, & ticks) but also supports QSS style sheets.
    • Supports mouse wheel events
    • Supports more than 2 handles (e.g. slider.setValue([0, 10, 60, 80]))

    As QRangeSlider inherits from QtWidgets.QSlider, you can use all of the same methods available in the QSlider API. The major difference is that value() and sliderPosition() are reimplemented as tuples of int (where the length of the tuple is equal to the number of handles in the slider.)

    These options are in addition to the Qt QSlider API, and control the behavior of the bar between handles.

    getter setter type default description barIsVisible setBarIsVisible hideBar / showBar bool True Whether the bar between handles is visible. barMovesAllHandles setBarMovesAllHandles bool True Whether clicking on the bar moves all handles or just the nearest barIsRigid setBarIsRigid bool True Whether bar length is constant or \"elastic\" when dragging the bar beyond min/max."},{"location":"widgets/qrangeslider/#screenshots","title":"Screenshots","text":"code that generates the images below
    import os\n\nfrom qtpy import QtCore\nfrom qtpy import QtWidgets as QtW\n\n# patch for Qt 5.15 on macos >= 12\nos.environ[\"USE_MAC_SLIDER_PATCH\"] = \"1\"\n\nfrom superqt import QRangeSlider  # noqa\n\nQSS = \"\"\"\nQSlider {\n    min-height: 20px;\n}\n\nQSlider::groove:horizontal {\n    border: 0px;\n    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #888, stop:1 #ddd);\n    height: 20px;\n    border-radius: 10px;\n}\n\nQSlider::handle {\n    background: qradialgradient(cx:0, cy:0, radius: 1.2, fx:0.35,\n                                fy:0.3, stop:0 #eef, stop:1 #002);\n    height: 20px;\n    width: 20px;\n    border-radius: 10px;\n}\n\nQSlider::sub-page:horizontal {\n    background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #227, stop:1 #77a);\n    border-top-left-radius: 10px;\n    border-bottom-left-radius: 10px;\n}\n\nQRangeSlider {\n    qproperty-barColor: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #227, stop:1 #77a);\n}\n\"\"\"\n\nHorizontal = QtCore.Qt.Orientation.Horizontal\n\n\nclass DemoWidget(QtW.QWidget):\n    def __init__(self) -> None:\n        super().__init__()\n\n        reg_hslider = QtW.QSlider(Horizontal)\n        reg_hslider.setValue(50)\n        range_hslider = QRangeSlider(Horizontal)\n        range_hslider.setValue((20, 80))\n        multi_range_hslider = QRangeSlider(Horizontal)\n        multi_range_hslider.setValue((11, 33, 66, 88))\n        multi_range_hslider.setTickPosition(QtW.QSlider.TickPosition.TicksAbove)\n\n        styled_reg_hslider = QtW.QSlider(Horizontal)\n        styled_reg_hslider.setValue(50)\n        styled_reg_hslider.setStyleSheet(QSS)\n        styled_range_hslider = QRangeSlider(Horizontal)\n        styled_range_hslider.setValue((20, 80))\n        styled_range_hslider.setStyleSheet(QSS)\n\n        reg_vslider = QtW.QSlider(QtCore.Qt.Orientation.Vertical)\n        reg_vslider.setValue(50)\n        range_vslider = QRangeSlider(QtCore.Qt.Orientation.Vertical)\n        range_vslider.setValue((22, 77))\n\n        tick_vslider = QtW.QSlider(QtCore.Qt.Orientation.Vertical)\n        tick_vslider.setValue(55)\n        tick_vslider.setTickPosition(QtW.QSlider.TicksRight)\n        range_tick_vslider = QRangeSlider(QtCore.Qt.Orientation.Vertical)\n        range_tick_vslider.setValue((22, 77))\n        range_tick_vslider.setTickPosition(QtW.QSlider.TicksLeft)\n\n        szp = QtW.QSizePolicy.Maximum\n        left = QtW.QWidget()\n        left.setLayout(QtW.QVBoxLayout())\n        left.setContentsMargins(2, 2, 2, 2)\n        label1 = QtW.QLabel(\"Regular QSlider Unstyled\")\n        label2 = QtW.QLabel(\"QRangeSliders Unstyled\")\n        label3 = QtW.QLabel(\"Styled Sliders (using same stylesheet)\")\n        label1.setSizePolicy(szp, szp)\n        label2.setSizePolicy(szp, szp)\n        label3.setSizePolicy(szp, szp)\n        left.layout().addWidget(label1)\n        left.layout().addWidget(reg_hslider)\n        left.layout().addWidget(label2)\n        left.layout().addWidget(range_hslider)\n        left.layout().addWidget(multi_range_hslider)\n        left.layout().addWidget(label3)\n        left.layout().addWidget(styled_reg_hslider)\n        left.layout().addWidget(styled_range_hslider)\n\n        right = QtW.QWidget()\n        right.setLayout(QtW.QHBoxLayout())\n        right.setContentsMargins(15, 5, 5, 0)\n        right.layout().setSpacing(30)\n        right.layout().addWidget(reg_vslider)\n        right.layout().addWidget(range_vslider)\n        right.layout().addWidget(tick_vslider)\n        right.layout().addWidget(range_tick_vslider)\n\n        self.setLayout(QtW.QHBoxLayout())\n        self.layout().addWidget(left)\n        self.layout().addWidget(right)\n        self.setGeometry(600, 300, 580, 300)\n        self.activateWindow()\n        self.show()\n\n\nif __name__ == \"__main__\":\n\n    import sys\n    from pathlib import Path\n\n    dest = Path(\"screenshots\")\n    dest.mkdir(exist_ok=True)\n\n    app = QtW.QApplication([])\n    demo = DemoWidget()\n\n    if \"-snap\" in sys.argv:\n        import platform\n\n        QtW.QApplication.processEvents()\n        demo.grab().save(str(dest / f\"demo_{platform.system().lower()}.png\"))\n    else:\n        app.exec_()\n
    "},{"location":"widgets/qrangeslider/#macos","title":"macOS","text":""},{"location":"widgets/qrangeslider/#catalina","title":"Catalina","text":""},{"location":"widgets/qrangeslider/#big-sur","title":"Big Sur","text":""},{"location":"widgets/qrangeslider/#windows","title":"Windows","text":""},{"location":"widgets/qrangeslider/#linux","title":"Linux","text":""},{"location":"widgets/qrangeslider/#qt-class","title":"Qt Class","text":"

    QSlider

    "},{"location":"widgets/qrangeslider/#methods","title":"Methods","text":"

    MultiHandle Range Slider widget.

    Same API as QSlider, but value, setValue, sliderPosition, and setSliderPosition are all sequences of integers.

    The valueChanged and sliderMoved signals also both emit a tuple of integers.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.barColor","title":"barColor = Property(QtGui.QBrush, _getBarColor, _setBarColor) class-attribute instance-attribute","text":"

    The color of the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.applyMacStylePatch","title":"applyMacStylePatch() -> None","text":"

    Apply a QSS patch to fix sliders on macos>=12 with QT < 6.

    see FAQ for more details.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.barIsRigid","title":"barIsRigid() -> bool","text":"

    Whether bar length is constant when dragging the bar.

    If False, the bar can shorten when dragged beyond min/max. Default is True.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.barIsVisible","title":"barIsVisible() -> bool","text":"

    Whether to show the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.barMovesAllHandles","title":"barMovesAllHandles() -> bool","text":"

    Whether clicking on the bar moves all handles, or just the nearest.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.hideBar","title":"hideBar() -> None","text":"

    Hide the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.setBarIsRigid","title":"setBarIsRigid(val: bool = True) -> None","text":"

    Whether bar length is constant when dragging the bar.

    If False, the bar can shorten when dragged beyond min/max. Default is True.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.setBarMovesAllHandles","title":"setBarMovesAllHandles(val: bool = True) -> None","text":"

    Whether clicking on the bar moves all handles, or just the nearest.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.setBarVisible","title":"setBarVisible(val: bool = True) -> None","text":"

    Whether to show the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#superqt.sliders._sliders._GenericRangeSlider.showBar","title":"showBar() -> None","text":"

    Show the bar between the first and last handle.

    "},{"location":"widgets/qrangeslider/#type-changes","title":"Type changes","text":"

    Note the following changes in types compared to the QSlider API:

    value() -> Tuple[int, ...]\n
    setValue(val: Sequence[int]) -> None\n
    # Signal\nvalueChanged(Tuple[int, ...])\n
    sliderPosition() -> Tuple[int, ...]\n
    setSliderPosition(val: Sequence[int]) -> None\n
    sliderMoved(Tuple[int, ...])\n
    "},{"location":"widgets/qsearchablecombobox/","title":"QSearchableComboBox","text":"

    QSearchableComboBox is a variant of QComboBox that allow to filter list of options by enter part of text. It could be drop in replacement for QComboBox.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QSearchableComboBox\n\napp = QApplication([])\n\ncombo = QSearchableComboBox()\ncombo.addItems([\"foo\", \"bar\", \"baz\", \"foobar\", \"foobaz\", \"barbaz\"])\ncombo.show()\n\napp.exec_()\n

    "},{"location":"widgets/qsearchablecombobox/#qt-class","title":"Qt Class","text":"

    QComboBox

    "},{"location":"widgets/qsearchablelistwidget/","title":"QSearchableListWidget","text":"

    QSearchableListWidget is a variant of QListWidget that add text entry above list widget that allow to filter list of available options.

    Due to implementation details, this widget it does not inherit directly from QListWidget but it does fully satisfy its api. The only limitation is that it cannot be used as argument of QListWidgetItem constructor.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QSearchableListWidget\n\napp = QApplication([])\n\nslider = QSearchableListWidget()\nslider.addItems([\"foo\", \"bar\", \"baz\", \"foobar\", \"foobaz\", \"barbaz\"])\nslider.show()\n\napp.exec_()\n

    "},{"location":"widgets/qsearchablelistwidget/#qt-class","title":"Qt Class","text":"

    QWidget

    "},{"location":"widgets/qsearchablelistwidget/#methods","title":"Methods","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.addItem","title":"addItem(*args)","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.addItems","title":"addItems(*args)","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.insertItem","title":"insertItem(*args)","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.insertItems","title":"insertItems(*args)","text":""},{"location":"widgets/qsearchablelistwidget/#superqt.QSearchableListWidget.update_visible","title":"update_visible(text)","text":""},{"location":"widgets/qsearchabletreewidget/","title":"QSearchableTreeWidget","text":"

    QSearchableTreeWidget combines a QTreeWidget and a QLineEdit for showing a mapping that can be searched by key.

    This is intended to be used with a read-only mapping and be conveniently created using QSearchableTreeWidget.fromData(data). If the mapping changes, the easiest way to update this is by calling setData.

    from qtpy.QtWidgets import QApplication\n\nfrom superqt import QSearchableTreeWidget\n\napp = QApplication([])\n\ndata = {\n    \"none\": None,\n    \"str\": \"test\",\n    \"int\": 42,\n    \"list\": [2, 3, 5],\n    \"dict\": {\n        \"float\": 0.5,\n        \"tuple\": (22, 99),\n        \"bool\": False,\n    },\n}\ntree = QSearchableTreeWidget.fromData(data)\ntree.show()\n\napp.exec_()\n

    "},{"location":"widgets/qsearchabletreewidget/#qt-class","title":"Qt Class","text":"

    QWidget

    "},{"location":"widgets/qsearchabletreewidget/#methods","title":"Methods","text":"

    A tree widget for showing a mapping that can be searched by key.

    This is intended to be used with a read-only mapping and be conveniently created using QSearchableTreeWidget.fromData(data). If the mapping changes, the easiest way to update this is by calling setData.

    The tree can be searched by entering a regular expression pattern into the filter line edit. An item is only shown if its, any of its ancestors', or any of its descendants' keys or values match this pattern. The regular expression follows the conventions described by the Qt docs: https://doc.qt.io/qt-5/qregularexpression.html#details

    Attributes:

    Name Type Description tree QTreeWidget

    Shows the mapping as a tree of items.

    filter QLineEdit

    Used to filter items in the tree by matching their key against a regular expression.

    "},{"location":"widgets/qsearchabletreewidget/#superqt.QSearchableTreeWidget.fromData","title":"fromData(data: Mapping, *, parent: QWidget = None) -> QSearchableTreeWidget classmethod","text":"

    Make a searchable tree widget from a mapping.

    "},{"location":"widgets/qsearchabletreewidget/#superqt.QSearchableTreeWidget.setData","title":"setData(data: Mapping) -> None","text":"

    Update the mapping data shown by the tree.

    "}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 6ead524..c9c32ef 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -28,6 +28,10 @@ https://github.com/pyapp-kit/superqt/utilities/fonticon/ 2025-01-05 + + https://github.com/pyapp-kit/superqt/utilities/iconify/ + 2025-01-05 + https://github.com/pyapp-kit/superqt/utilities/qmessagehandler/ 2025-01-05 diff --git a/sitemap.xml.gz b/sitemap.xml.gz index 9cf454947a489dc710ea9deb87ddc7477b9b8e3a..2b57c003fad2853355478c23059b3e729c0b7b26 100644 GIT binary patch delta 445 zcmV;u0Yd)61Ih!C7k`({j+`(I$M5?TBkn`kl~!u28TQsE=$=tXJi%&+AvVkK_6;-J z?Z>e_B#{tc8UKI6jt!@m>*x<}5E&_)tH-*j4iF4k4DMXLe*1d-RK2thrzLs@IV9)6 z=V}m{z9_Y>Yt1My>WOQLPO%x%4XbyfYUfju($|JY zHEnvDj^9xfFB8OB)Jg5Gzdxy2MzZZw^Ynad9*@m)a(TDirPPPkKdWB!oJn~R^e70N zUEk~(%nm^oI^KflYd4@9d^#jM6~sufv#33}&QK7zO8$gh5(p-m>>xV?UbgHU^9an^ z!Jvcn5VP|zx__X3w;S?TiwqI8?JO9IS}2x6lm<@;BqZYVp{!^fWNRru)eU)yX$o{k z%iiiTs| nVbIYGI&G*@`rt1jk1Tg{IZP4({+H=?VvzO+6`@NFbrJvoEV|Y> delta 438 zcmV;n0ZIPK1H%K57k`$`Zlo{_$M1cL5%(dqQl)k^LvQ;8+cPqWCqx@!h)tP!`-Yje z`*GYoB#{tcIsX5IKf>YVJo?=mMs^gA)qUMmI}DnP3-(yO{`kIss$SZ=!xBBC?2>cf zV>O6O-;`R{wPq(c!o)R2t5^@|h1G{qHT84V-tE%b0^FXi>wn-$w_6lWVXTv3>1$1+ znl3O+`=3q}FB8UD)In{ozwZQ=kxcv0JUs53`+f76Ts~|!DfOlG&#EVwGbu0Pyc36< zU0-h*%nm^YJH7;gb2m6U_;g8jDvXh0XB>F4ou(jomi!4jB@mZrvV+VcGK0kdg7Fx$ z^RTl4e770$XMahCh+sN{nj#3rQi#&PFM)(ad_I)b8H?Fk`BPn!r2~3dQ8pQ%~n2VDg=kUmS*(l$r>^B70}DP29hL%3#4nkp_x~9({I}u#BY? z@5$5Z;X;e#Cb^~tO>tHH2Uk%@<$a`5V4_7AgeMmYXfLsOf%Hc%m)sl$l?x+8JwR%x gQs&? +
    + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/utilities/code_syntax_highlight/index.html b/utilities/code_syntax_highlight/index.html index 9e504fb..846659c 100644 --- a/utilities/code_syntax_highlight/index.html +++ b/utilities/code_syntax_highlight/index.html @@ -286,6 +286,8 @@ + + @@ -517,6 +519,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/utilities/error_dialog_contexts/index.html b/utilities/error_dialog_contexts/index.html index d288062..fb5df59 100644 --- a/utilities/error_dialog_contexts/index.html +++ b/utilities/error_dialog_contexts/index.html @@ -286,6 +286,8 @@ + + @@ -466,6 +468,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/utilities/fonticon/index.html b/utilities/fonticon/index.html index 43dba54..8c15687 100644 --- a/utilities/fonticon/index.html +++ b/utilities/fonticon/index.html @@ -16,7 +16,7 @@ - + @@ -286,6 +286,8 @@ + + @@ -631,6 +633,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/utilities/iconify/index.html b/utilities/iconify/index.html new file mode 100644 index 0000000..ddf271d --- /dev/null +++ b/utilities/iconify/index.html @@ -0,0 +1,1649 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + QIconifyIcon - superqt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + Skip to content + + +
    +
    + +
    + + + + + + +
    + + +
    + +
    + + + + + + +
    +
    + + + +
    +
    +
    + + + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    +
    + + + +
    +
    + + + + + + + +

    QIconifyIcon#

    +

    Iconify is an icon library that includes 150,000+ +icons from most major icon sets including Bootstrap, FontAwesome, Material +Design, and many more; each available as individual SVGs. Unlike the +superqt.fonticon module, superqt.QIconifyIcon does not require any additional +dependencies or font files to be installed. Icons are downloaded (and cached) +on-demand from the Iconify API, using pyconify

    +

    Search availble icons at https://icon-sets.iconify.design +Once you find one you like, use the key in the format "prefix:name" to create an +icon: QIconifyIcon("bi:bell").

    +

    Basic Example#

    +
    from qtpy.QtCore import QSize
    +from qtpy.QtWidgets import QApplication, QPushButton
    +
    +from superqt import QIconifyIcon
    +
    +app = QApplication([])
    +
    +btn = QPushButton()
    +btn.setIcon(QIconifyIcon("fluent-emoji-flat:alarm-clock"))
    +btn.setIconSize(QSize(60, 60))
    +btn.show()
    +
    +app.exec()
    +
    +

    QIconifyIcon

    + + +
    + + + +

    + superqt.QIconifyIcon + + +#

    + + +
    +

    + Bases: QIcon

    + + +

    QIcon backed by an iconify icon.

    +

    Iconify includes 150,000+ icons from most major icon sets including Bootstrap, +FontAwesome, Material Design, and many more.

    +

    Search availble icons at https://icon-sets.iconify.design +Once you find one you like, use the key in the format "prefix:name" to create an +icon: QIconifyIcon("bi:bell").

    +

    This class is a thin wrapper around the +pyconify svg_path function. It pulls SVGs +from iconify, creates a temporary SVG file and uses it as the source for a QIcon. +SVGs are cached to disk, and persist across sessions (until pyconify.clear_cache() +is called).

    +

    Parameters are the same as QIconifyIcon.addKey, which can be used to add +additional icons for various modes and states to the same QIcon.

    + + +

    Parameters:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescriptionDefault
    + *key + + str + +
    +

    Icon set prefix and name. May be passed as a single string in the format +"prefix:name" or as two separate strings: 'prefix', 'name'.

    +
    +
    + () +
    + color + + str + +
    +

    Icon color. If not provided, the icon will appear black (the icon fill color +will be set to the string "currentColor").

    +
    +
    + None +
    + flip + + str + +
    +

    Flip icon. Must be one of "horizontal", "vertical", "horizontal,vertical"

    +
    +
    + None +
    + rotate + + str | int + +
    +

    Rotate icon. Must be one of 0, 90, 180, 270, +or 0, 1, 2, 3 (equivalent to 0, 90, 180, 270, respectively)

    +
    +
    + None +
    + dir + + str + +
    +

    If 'dir' is not None, the file will be created in that directory, otherwise a +default +directory is +used.

    +
    +
    + None +
    + + +

    Examples:

    +
    >>> from qtpy.QtWidgets import QPushButton
    +>>> from superqt import QIconifyIcon
    +>>> btn = QPushButton()
    +>>> icon = QIconifyIcon("bi:alarm-fill", color="red", rotate=90)
    +>>> btn.setIcon(icon)
    +
    + + + + + + + + + +
    + + + + + + + + + +
    + + +

    + addKey(*key, color=None, flip=None, rotate=None, dir=None, size=None, mode=QIcon.Mode.Normal, state=QIcon.State.Off) + +#

    + + +
    + +

    Add an icon to this QIcon.

    +

    This is a variant of QIcon.addFile that uses an iconify icon keys and +arguments instead of a file path.

    + + +

    Parameters:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescriptionDefault
    + *key + + str + +
    +

    Icon set prefix and name. May be passed as a single string in the format +"prefix:name" or as two separate strings: 'prefix', 'name'.

    +
    +
    + () +
    + color + + str + +
    +

    Icon color. If not provided, the icon will appear black (the icon fill color +will be set to the string "currentColor").

    +
    +
    + None +
    + flip + + str + +
    +

    Flip icon. Must be one of "horizontal", "vertical", "horizontal,vertical"

    +
    +
    + None +
    + rotate + + str | int + +
    +

    Rotate icon. Must be one of 0, 90, 180, 270, or 0, 1, 2, 3 (equivalent to 0, +90, 180, 270, respectively)

    +
    +
    + None +
    + dir + + str + +
    +

    If 'dir' is not None, the file will be created in that directory, otherwise +a default +directory +is used.

    +
    +
    + None +
    + size + + QSize + +
    +

    Size specified for the icon, passed to QIcon.addFile.

    +
    +
    + None +
    + mode + + Mode + +
    +

    Mode specified for the icon, passed to QIcon.addFile.

    +
    +
    + Normal +
    + state + + State + +
    +

    State specified for the icon, passed to QIcon.addFile.

    +
    +
    + Off +
    + + +

    Returns:

    + + + + + + + + + + + + + +
    TypeDescription
    + QIconifyIcon + +
    +

    This QIconifyIcon instance, for chaining.

    +
    +
    + +
    + +
    + + + +
    + +
    + +
    + + + + + + + + + + + + + +
    +
    + + + +
    + +
    + + + +
    +
    +
    +
    + + + + + + + + + + \ No newline at end of file diff --git a/utilities/index.html b/utilities/index.html index 591dc06..0afd988 100644 --- a/utilities/index.html +++ b/utilities/index.html @@ -286,6 +286,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • @@ -1053,6 +1076,15 @@ +
  • + +
  • + + + SVG Icons + + +
  • @@ -1131,6 +1163,21 @@ +

    SVG Icons#

    + + + + + + + + + + + + + +
    ObjectDescription
    QIconifyIconQIcons backed by the Iconify icon library.

    Threading tools#

    diff --git a/utilities/qmessagehandler/index.html b/utilities/qmessagehandler/index.html index dffc4fe..7398242 100644 --- a/utilities/qmessagehandler/index.html +++ b/utilities/qmessagehandler/index.html @@ -13,7 +13,7 @@ - + @@ -286,6 +286,8 @@ + + @@ -415,6 +417,27 @@ + + +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + diff --git a/utilities/signal_utils/index.html b/utilities/signal_utils/index.html index 8a6944c..6baf7ad 100644 --- a/utilities/signal_utils/index.html +++ b/utilities/signal_utils/index.html @@ -286,6 +286,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/utilities/thread_decorators/index.html b/utilities/thread_decorators/index.html index d3e34cb..d5cc290 100644 --- a/utilities/thread_decorators/index.html +++ b/utilities/thread_decorators/index.html @@ -286,6 +286,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/utilities/threading/index.html b/utilities/threading/index.html index 5f5207a..7634a1e 100644 --- a/utilities/threading/index.html +++ b/utilities/threading/index.html @@ -286,6 +286,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/utilities/throttling/index.html b/utilities/throttling/index.html index 00b9b15..d5943f6 100644 --- a/utilities/throttling/index.html +++ b/utilities/throttling/index.html @@ -286,6 +286,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/colormap_catalog/index.html b/widgets/colormap_catalog/index.html index 22505db..deb80a6 100644 --- a/widgets/colormap_catalog/index.html +++ b/widgets/colormap_catalog/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/index.html b/widgets/index.html index caf9868..dc20e45 100644 --- a/widgets/index.html +++ b/widgets/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qcollapsible/index.html b/widgets/qcollapsible/index.html index d31457f..9c6487e 100644 --- a/widgets/qcollapsible/index.html +++ b/widgets/qcollapsible/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qcolorcombobox/index.html b/widgets/qcolorcombobox/index.html index 5f69cf8..4313e14 100644 --- a/widgets/qcolorcombobox/index.html +++ b/widgets/qcolorcombobox/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qcolormap/index.html b/widgets/qcolormap/index.html index 0c46cad..aeb0e55 100644 --- a/widgets/qcolormap/index.html +++ b/widgets/qcolormap/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qdoublerangeslider/index.html b/widgets/qdoublerangeslider/index.html index 97898d8..034d855 100644 --- a/widgets/qdoublerangeslider/index.html +++ b/widgets/qdoublerangeslider/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qdoubleslider/index.html b/widgets/qdoubleslider/index.html index f4c4cfc..c066a96 100644 --- a/widgets/qdoubleslider/index.html +++ b/widgets/qdoubleslider/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qelidinglabel/index.html b/widgets/qelidinglabel/index.html index 2adf07e..ce1f43d 100644 --- a/widgets/qelidinglabel/index.html +++ b/widgets/qelidinglabel/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qenumcombobox/index.html b/widgets/qenumcombobox/index.html index a93bbdf..3a280d2 100644 --- a/widgets/qenumcombobox/index.html +++ b/widgets/qenumcombobox/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qflowlayout/index.html b/widgets/qflowlayout/index.html index 46b294c..04a4b93 100644 --- a/widgets/qflowlayout/index.html +++ b/widgets/qflowlayout/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qlabeleddoublerangeslider/index.html b/widgets/qlabeleddoublerangeslider/index.html index 38752d6..dcad447 100644 --- a/widgets/qlabeleddoublerangeslider/index.html +++ b/widgets/qlabeleddoublerangeslider/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qlabeleddoubleslider/index.html b/widgets/qlabeleddoubleslider/index.html index 19f1262..55845e6 100644 --- a/widgets/qlabeleddoubleslider/index.html +++ b/widgets/qlabeleddoubleslider/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qlabeledrangeslider/index.html b/widgets/qlabeledrangeslider/index.html index b7f604b..6607dbe 100644 --- a/widgets/qlabeledrangeslider/index.html +++ b/widgets/qlabeledrangeslider/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qlabeledslider/index.html b/widgets/qlabeledslider/index.html index dac426c..e8f1415 100644 --- a/widgets/qlabeledslider/index.html +++ b/widgets/qlabeledslider/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qlargeintspinbox/index.html b/widgets/qlargeintspinbox/index.html index 09bd907..ad53666 100644 --- a/widgets/qlargeintspinbox/index.html +++ b/widgets/qlargeintspinbox/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • diff --git a/widgets/qquantity/index.html b/widgets/qquantity/index.html index 4769d15..a214483 100644 --- a/widgets/qquantity/index.html +++ b/widgets/qquantity/index.html @@ -284,6 +284,8 @@ + + @@ -417,6 +419,27 @@ +
  • + + + + + QIconifyIcon + + + + +
  • + + + + + + + + + +
  • @@ -980,9 +1003,9 @@