인터페이스를 설명하는 Glade 파일이 있습니다. 그 목표는 로컬 네트워크를 통해 Nec 모니터를 제어하는 것입니다. 모니터의 작동 방식을 따라서 제어 위젯 많이 있습니다 : 나는/얻을 모니터와 위젯 /에서 설정 한 것 사이의 링크를 생성 할 필요가Haskell + GTK에서 위젯을 다루는 방법은 무엇입니까?
. 이것은 값을 가져 오거나 설정하고 함수를 위젯에 연결하는 것을 의미합니다.
GTK 라이브러리의 Builder
은 IO()를 사용하고 특정 기능을 호출하기 위해 모든 위젯을 캐스팅해야합니다. 이것은 다소 지루하고 불필요한 코드 행을 추가합니다.
module GUI where
import Graphics.UI.Gtk
data NecControlGUI = NecControlGUI
{ winNecControl :: Window
, entIPAddress :: Entry
, btnConnection :: Button
, cbtVideoInput :: ComboBox
, cbtPIPInput :: ComboBox
, sclSharpness :: Scale
, sclContrast :: Scale
, sclBrightness :: Scale
, sclBlackLevel :: Scale
, sclColorTemperature :: Scale
, cbtGamma :: ComboBox
, sclBalance :: Scale
, sclTreble :: Scale
, sclBass :: Scale
, sclVolume :: Scale
, cbtLanguage :: ComboBox
, sclMenuDisplayTime :: Scale
}
loadGUI :: String -> IO NecControlGUI
loadGUI guiPath = do
bdr <- builderNew
builderAddFromFile bdr guiPath
window <- builderGetObject bdr castToWindow "winNecControl"
ipaddress <- builderGetObject bdr castToEntry "entIPAddress"
connection <- builderGetObject bdr castToButton "btnConnection"
videoinput <- builderGetObject bdr castToComboBox "cbtVideoInput"
pipinput <- builderGetObject bdr castToComboBox "cbtPIPInput"
sharpness <- builderGetObject bdr castToScale "sclSharpness"
contrast <- builderGetObject bdr castToScale "sclContrast"
brightness <- builderGetObject bdr castToScale "sclBrightness"
blacklevel <- builderGetObject bdr castToScale "sclBlackLevel"
colortemperature <- builderGetObject bdr castToScale "sclColorTemparature"
gamma <- builderGetObject bdr castToComboBox "cbtGamma"
balance <- builderGetObject bdr castToScale "sclBalance"
treble <- builderGetObject bdr castToScale "sclTreble"
bass <- builderGetObject bdr castToScale "sclBass"
volume <- builderGetObject bdr castToScale "sclVolume"
language <- builderGetObject bdr castToComboBox "cbtLanguage"
menudisplaytime <- builderGetObject bdr castToScale "sclMenuDisplayTime"
return NecControlGUI
{ winNecControl = window
, entIPAddress = ipaddress
, btnConnection = connection
, cbtVideoInput = videoinput
, cbtPIPInput = pipinput
, sclSharpness = sharpness
, sclContrast = contrast
, sclBrightness = brightness
, sclBlackLevel = blacklevel
, sclColorTemperature = colortemperature
, cbtGamma = gamma
, sclBalance = balance
, sclTreble = treble
, sclBass = bass
, sclVolume = volume
, cbtLanguage = language
, sclMenuDisplayTime = menudisplaytime
}
이 부분을 자동화하는 방법이 있습니까?
나는 LGtk에 대해 들어 봤지만 그것을하는 유일한 방법 일까?
나는 실용적 길을 갈하려고 2016년 9월 20일 1
편집,하지만 실용적 IO를 결합처럼 그 하스켈을하지 않는 것?
.../src/NecControlGUI.hs:16:23: error:
• Couldn't match type ‘Adjustment’ with ‘Window’
Expected type: IO Window
Actual type: IO Adjustment
• In the second argument of ‘(<*>)’, namely
‘bget castToWindow "winNecControl"’
In a stmt of a 'do' block:
NecControlGUI <$> bget castToAdjustment "adjBalance"
<*> bget castToWindow "winNecControl"
In the expression:
do { bdr <- builderNew;
builderAddFromFile bdr guiPath;
let bget = builderGetObject bdr;
NecControlGUI <$> bget castToAdjustment "adjBalance"
<*> bget castToWindow "winNecControl" }
.../src/NecControlGUI.hs:16:28: error:
• Couldn't match type ‘Window’ with ‘Adjustment’
Expected type: GObject -> Adjustment
Actual type: GObject -> Window
• In the first argument of ‘bget’, namely ‘castToWindow’
In the second argument of ‘(<*>)’, namely
‘bget castToWindow "winNecControl"’
In a stmt of a 'do' block:
NecControlGUI <$> bget castToAdjustment "adjBalance"
<*> bget castToWindow "winNecControl"
편집 나는 let bdr = ...
문, 모든 작업을 제거하면 2016년 9월 20일 2
을 다음 오류 출력을 컴파일
module NecControlGUI where
import Graphics.UI.Gtk
data NecControlGUI = NecControlGUI
{ adjBalance :: Adjustment
, winNecControl :: Window
}
loadNecControlGUI :: String -> IO NecControlGUI
loadNecControlGUI guiPath = do
bdr <- builderNew
builderAddFromFile bdr guiPath
let bget = builderGetObject bdr
NecControlGUI <$> bget castToAdjustment "adjBalance"
<*> bget castToWindow "winNecControl"
(하지만 아마 나에게있어) 예상대로
두 가지 즉각적인 개선점은'bget = builderGetObject bdr'을 정의하고 한 번만 사용되는 임시 이름 정의를 중지하는 것입니다. 'return NecControlGUI {winNetControl = bget castToWindow "winNecControl", ...}' – chepner
흠, 확실하지 않지만 LGtk에서 Glade 파일을 지원하지 않는다고 생각하면 LGtk 구문으로 처음부터 GUI를 정의해야 할 것입니다. Glade를 사용하여 꽤 복잡한 GUI를 만들었고 복사 붙여 넣기 및 검색/바꾸기로이 작업을 많이했습니다. 확실히, 그것은 지루하지만, 어떻게 든 당신은 어떤 타입과 값으로 glade 파일의 내용을 연관시켜야합니다. glade 파일에서 뭔가를 가져 와서 레코드 필드에 넣고 Glade의 기본 명명 규칙을 사용하는 표준 경우 만 있다면 Haskell 코드 생성기를 작성할 수 있지만 그만한 가치가 있다면 ... – MichaelO
@chepner'builderGetObject'는 모나드 값을 반환하고 레코드 구조는 순수한 값으로 작동하기 때문에 임시 이름을 사용할 수 없습니다. – zigazou